controll a summation with binary variables

Hi everyone,

I have got a problem with summing up a value.
If a binary variable gets the level 1, a subtraction of the variable
“temp” should start until a certain level is reached.
Then, if another binary variable gets the level 1, the variable “temp”
needs to be set on a value.

The binary variables are:
A(i,t) switching a unit i on → A gets the level 1 for one time slot
B(i,t) switching a unit i off → B gets the level 1 for one time
slot

Then we have the variable:
temp(i,t)

When A(i,t) gets the value “1”, the variable temp(i,t) should be set
on the value “1”.
When the unit i is switched off, - B(i,t) gets the value “1” - the
variable temp(i,t) should decrease by 0.1 (or a different parameter)
per time slot until the level “0” is reached, or the unit is switched
on again.

Thanks for the help!
If any more detail etc. is needed just let me know.

\

Hi there,
this is some kind of unit commitment problem, I believe.
I’m afraid you will need to add a “status” variable U(i,t), valued 1
when the unit is on, and 0 when the unit is off. Then the binary
variables :
A(i,t) =g= U(i,t) - U(i,t-1);
B(i,t) =g= U(i,t-1) - U(i,t);

then your temp variables should be obtained with the couple of
inequalities:

temp(i,t) =g= U(i,t) ;
(ensures that you pay at least 1 when the unit is switched on)
temp(i,t) =g= temp(i,t-1) - (1-U(i,t))*0.1 - BigM * A(i,t) ;
(allows to decrease temp by 0.1 when the unit if off (hence 1-U=1)
and drops the residual temp when the unit gets restarted)

Is this what you needed?
hope this helps
cheers
dax



On 2 déc, 12:44, PowerM wrote:

Hi everyone,

I have got a problem with summing up a value.
If a binary variable gets the level 1, a subtraction of the variable
“temp” should start until a certain level is reached.
Then, if another binary variable gets the level 1, the variable “temp”
needs to be set on a value.

The binary variables are:
A(i,t) switching a unit i on → A gets the level 1 for one time slot
B(i,t) switching a unit i off → B gets the level 1 for one time
slot

Then we have the variable:
temp(i,t)

When A(i,t) gets the value “1”, the variable temp(i,t) should be set
on the value “1”.
When the unit i is switched off, - B(i,t) gets the value “1” - the
variable temp(i,t) should decrease by 0.1 (or a different parameter)
per time slot until the level “0” is reached, or the unit is switched
on again.

Thanks for the help!
If any more detail etc. is needed just let me know.

\

Hi Dax,

thanks for the hint.
You’re right, it is a unit commitment problem, where I have different
start-up types (hot (A1), warm (A2) and cold (A3) start), each with
different start up costs ( hot start-up is cheaper the a cold start-
up).
A status variable is already here, named “An(i,t)”.

I try to modell different start-up types depending on the time the
unit is already switched off.

temp(i,t-1) - A1(i,t)/1.25 -A2(i,t)/2 =g= 0 ; when unit i is
switched of since le 2 timeslots a hot start-up can be performed an
after 5 timeslots a warm start-up, else a cold star-tup

temp(i,t) =g= An(KW,t) ;

temp(i,t) =g= temp(i,t-1) - (1-An(KW,t))*0.1 -A1(i,t) -A2(i,t) -
A3(i,t);

The solver trys to use a hot start-up, since it is cheaper and
therefor the solver sets the variable temp(i,t) it that way, that the
first equation is alway fulfilled.

When temp(i,t) decreases due to off status, the variable “jumps” up to
a value, that a hot start-up can be performed.

Any clue how that can be corrected?

\

I am not sure if the following will be useful for you PowerM, but it
may be.

I think (and not 100% checked) that with a little bit of prep work via
new parameter/sets you should be able to get hot/warm/cold start costs
just by using the unit commitment (U) variable. I might be a little
sloppy with syntax, but I think you should get the general gist.


parameter STARTUP_COST(i,j) “startup cost if the unit has been offline
for j periods”
alias (t,j) {thinking while typing, could probably just make j =
max(the number of periods needed by any unit until it hits a cold
start), but the alias is OK as is }

So if a hotstart is say restarted within 3 or less periods of being
off, and warm 5, and the rest cold then:
STARTUP_COST(i,1) = HOTSTART_COST(i)
STARTUP_COST(i,2) = HOTSTART_COST(i)
STARTUP_COST(i,3) = HOTSTART_COST(i)
STARTUP_COST(i,4) = WARMSTART_COST(i)
STARTUP_COST(i,5) = WARMSTART_COST(i)
STARTUP_COST(i,j>5) = COLDSTART_COST(i)


alias(t,t2)
set map_t2StartUpCost_j(i,t,j) “true if the j periods prior to t
have a startup cost function defined” { we can be efficient here and
only go back from t to the 1st period t-j where a cold start begins
and ignore periods beyond this }
set map_t2StartUpCost_jt(i,t,j,t2) “flag the j periods prior to t
where we have a startup cost function defined” { so if at t, t2 will
go back from t-1, t-2,…, to t-j }

{ create the cost function sets.
If at period t, will flag true the j periods prior up to the first
period we hit the first cold start, all periods beyond then can be
ignored }
loop (t) do
loop (i) do
temp = NUMBER_PERIODS_UNTIL_HIT_COLDSTART(i); {eg 6 in this
case}
loop (j)$(ord(j) 0 only if the unit was offline for ALL of the
last j periods }


The general idea of the constraint is that the RHS will only be >0 if
the unit has been offline for exactly the last j periods. If it was
on at any time within the last j periods the RHS will be wrote:

Hi Dax,

thanks for the hint.
You’re right, it is a unit commitment problem, where I have different
start-up types (hot (A1), warm (A2) and cold (A3) start), each with
different start up costs ( hot start-up is cheaper the a cold start-
up).
A status variable is already here, named “An(i,t)”.

I try to modell different start-up types depending on the time the
unit is already switched off.

temp(i,t-1) - A1(i,t)/1.25 -A2(i,t)/2 =g= 0 ; when unit i is
switched of since le 2 timeslots a hot start-up can be performed an
after 5 timeslots a warm start-up, else a cold star-tup

temp(i,t) =g= An(KW,t) ;

temp(i,t) =g= temp(i,t-1) - (1-An(KW,t))*0.1 -A1(i,t) -A2(i,t) -
A3(i,t);

The solver trys to use a hot start-up, since it is cheaper and
therefor the solver sets the variable temp(i,t) it that way, that the
first equation is alway fulfilled.

When temp(i,t) decreases due to off status, the variable “jumps” up to
a value, that a hot start-up can be performed.

Any clue how that can be corrected?

\

Thanks Andy for this detailed help.
I will try to implement the code tday and will give a review of how it
works.

\

Hi andy,

somehoe it did not work out. GAMS had some problems with the
c_CostStartup(i,t) ant the whole loop. Thou I had the right syntax.
Anyway, thanks for the help!

\

Hi PowerM

I pretty much just typed the code into my newsgroup viewer, it’s
probably got some syntax bugs in it which may mean a direct copy and
paste wont work. But it should be pretty close…

The loop issue may be associated with the $onend setting? There are a
couple of ways you can write loops/ifs in GAMS depending on the
settings. The code I wrote assumed that the $onend setting was
enabled. It might be worth checking this out? (search help for $onend
if you are not familiar with it).

If you posted your full code, or the exact errors GAMS is throwing up,
then I may be able to help further.

As mentioned originally, I am not sure this code will be useful for
you. Its main advantage is you dont need the additional Hot/Warm/Cold
variables, you can simply use the U binary. This may speed up the
solve time.



As an alternative formulation, where the focus is on ease rather than
minimising variables, you could track unit commitment UC(i,t), start
ups SU(i,t), shut downs SD(i,t) (these may not be needed, but in
case you have shut down costs
), hot starts HS(i,t) and warm starts
WS(i,t). You don’t actually need to track cold starts as not being
hot or warm implies cold.

NOTE: I am typing directly into newsgroup, syntax might be a bit off.

Let STARTUP_COST_COLD(i) = cold start cost.
STARTUP_COST_WARM(i) = warm start cost.
STARTUP_COST_HOT(i) = hot start cost.

HOT_START = number of periods for hotstart
WARM_START = number of periods for warm start

The objective function part related to startup costs would be
something like:

sum((i,t), SU(i,t) * STARTUP_COST_COLD(i)

  • WS(i,t) * (STARTUP_COST_WARM(i) - STARTUP_COST_COLD(i))
  • HS(i,t) * (STARTUP_COST_HOT(i) -
    STARTUP_COST_COLD(i)) )

This says we initially assume that if the unit starts up it is a cold
start, but we remove this cold start cost and replace it with either a
warm or hot start cost if it was actually a warm/hot start.


The constraints would be as follows. I have overdone the constraints,
some are probably unrequired as the solution economics would mean the
model will naturally move to the solution the constraints are
enforcing. But there for completeness. I assume you correctly set UC
somewhere else, eg something like if UC=0 then unit cannot do
something - I dont have that constraint here.

Unit Commitment
** your existing UC constraints somewhere.

Startups / Shutdowns

  1. Force the start-up binary variable to 1 if the unit turns on.
    SU(i,t) >= UC(i,t) - UC(i,t-1)

  2. If the unit is off in t it could not have started up in t, force
    the start-up binary variable to 0
    SU(i,t) = UC(i,t-1) - UC(i,t)

  3. If the unit is on it could not have shut down, force the shut-down
    binary variable to 0.
    SD(i,t) ord(t - HOT_START)) =
    yes

HS(i,t) ord(t - WARM_START))
= yes

WS(i,t) = (sum(t_hot(t,t2), UC(i,t2) ) / HOT_START ) - (1 -
SU(i,t))

The first bit of the RHS is a fraction which will always be 0 if the unit was operating within the last HOT_START
periods. Assuming the unit has started up (which is dealt with
shortly) then if the unit was operating in prior hot start periods
then this part of the RHS is somewhere within (0,1], which forces the
hot start binary to be 1. The last part of the RHS checks the unit
has actually started up. 1 - SU(i,t) disappears if the unit started
up in t and leaves just the logic dealing with the unit operating,
described above. Conversely it forces the entire RHS to be ≤ 0 if the
unit did not start up, thereby making this whole constraint unbinding.


11. Similarly force the warm start variable to 1 if the unit was
previously operating within the last WARM_START periods AND has
started up.

WS(i,t) >= (sum(t_warm(t,t2), UC(i,t2) ) / WARM_START ) - (1 -
SU(i,t))

  1. A unit cannot start up AND shut down in the same period ***
    this might help a branch and bound solver ***

SU(i,t) + SD(i,t) wrote:

Hi andy,

somehoe it did not work out. GAMS had some problems with the
c_CostStartup(i,t) ant the whole loop. Thou I had the right syntax.
Anyway, thanks for the help!

\

Andy, thanks again for the help.

I got some questions.

This should be defiined as another set for t: set
t_hot(t,t2);
Is this an equation?: t_hot(t,t2)$(ord(t2) > ord(t - HOT_START)) =yes ; GAMS gives me an error due to the
same name for the set and the equation.
This should be an equation: HS(i,t)
(ord(t)-HOT_START)) ) ; here I get the error, that the RHS of
an equation cannot be a set expression.
EQ2(i,t) … HS(i,t) =l= sum(t_hot(t,t2), UC(i,t2)) ;


Thank you
PowerM

\

Andy,
I figured it out now. It works so far.
Thank you very much!

When theres a problem I will let you know.

Thanks
PowerM

\

As noted before, this uses many more integer/binary variables. The
original formulation simply uses the unit commitment UC binary.

Modern solvers are pretty good, and the branch and bound heuristics
and other tricks they use can be pretty quick at culling the tree and
cleverly joining them all together. However if you run into speed
problems AND you don’t need the hot/warm start binaries for anything
other than cost then it might be worth retrying my original idea.

Cheers
AndyC




On Dec 9, 4:34 am, PowerM wrote:

Andy,
I figured it out now. It works so far.
Thank you very much!

When theres a problem I will let you know.

Thanks
PowerM

\