logical equations & binary variables

Hey guys,

I got another question on logical equations or rather binary variables. This is again a beginner question.

So right now I’m trying to understand how to set the value of binary variables with conditions.

Consider the binary variable x and variable m.
If i would write the code in other language synthex, what I’m trying to do would look like:

if m > 0
x = True
else
x = False
end

So I’m trying to set the value of x to 1, when the variable m is greater than zero.

How do I model this in GAMS? Do I need to use logical equations for it?
I can’t find a solution for this.

Thanks again for your help.

Cheers
Max

Just include the following constraint:

m-Mx <=0

where M is an upper bound for m.

Hi, try these equations

eq1… m =g= m.lox;
eq2… m =l= m.up
x;

m.lo (lower bound)
m.up (upper bound)

if x=1
m greater than m.lo1;
m lower than m.up
1
if x=0
m greater than m.lo0;
m lower than m.up
0;
so, m = 0

Bye!

Thanks for your fast reply again, Manassaldi.
You are really helping me with my project.

I got another question:
I actually explained wrong, what I want to have. I need the binary variable x to equal 1, when the variable m equals zero.
So basically the opposite of the problem I stated before. Is there any good way to do it?
Unfortunately with your solution of the problem I can’t think of a similar solution for this topic.

Thanks in advance!

Cheers

Hi, It’s similar

eq1… m =g= m.lo*(1-x);
eq2… m =l= m.up*(1-x)

Bye!

Thanks a lot for your fast reply.
I could have got to this myself. I apologize for not thinking enough, before asking the question.

Hi guys,

I got another problem, that’s based in this here.

So coming back to my model, I still want to set the binary variable nrc to 1, when the mass flows m_rc_ts and m_rc_pb both equal to zero.
That’s why I implemented the following equations:

e_nrc_lo(i+1) … m_rc_ts(i+1)+m_rc_pb(i+1) =g= (1-nrc(i+1));
e_nrc_up(i+1) … m_rc_ts(i+1)+m_rc_pb(i+1) =l= m_rcmax*(1-nrc(i+1));

So if I get this right mathemetically, if the mass fows equal to zero, it should look like this:

0 + 0 >= 1 - nrc
0 + 0 <= 282 * (1-nrc)

which leads to:

nrc >= 1 and nrc <= 1, which leads to the only solution nrc = 1.

I implemented the variable, so these are the only equations were it is in. The inital value is 1.

If I run it now, I get the following from the equation list:

e_nrc_lo(1)..  m_rc_ts(1) + m_rc_pb(1) + nrc(1) =G= 1 ; (LHS = 1)
     
e_nrc_lo(2)..  m_rc_ts(2) + m_rc_pb(2) + nrc(2) =G= 1 ; (LHS = 0
     , INFES = 1 ****)
     
e_nrc_lo(3)..  m_rc_ts(3) + m_rc_pb(3) + nrc(3) =G= 1 ; (LHS = 0
     , INFES = 1 ****)

e_nrc_up(1)..  m_rc_ts(1) + m_rc_pb(1) + 282*nrc(1) =L= 282 ; (LHS = 282)
     
e_nrc_up(2)..  m_rc_ts(2) + m_rc_pb(2) + 282*nrc(2) =L= 282 ; (LHS = 0)
     
e_nrc_up(3)..  m_rc_ts(3) + m_rc_pb(3) + 282*nrc(3) =L= 282 ; (LHS = 0)

*The column list gives the following:

nrc(1)
                (.LO, .L, .UP, .M = 0, 1, 1, 0)
        1       e_nrc_lo(1)
      282       e_nrc_up(1)

nrc(2)
                (.LO, .L, .UP, .M = 0, 0, 1, 0)
        1       e_nrc_lo(2)
      282       e_nrc_up(2)

nrc(3)
                (.LO, .L, .UP, .M = 0, 0, 1, 0)
        1       e_nrc_lo(3)
      282       e_nrc_up(3)

m_rc_ts(1)
                (.LO, .L, .UP, .M = 0, 0, 282, 0)
        1       e_nrc_lo(1)
        1       e_nrc_up(1)
       (0)      e_nts(1)
        1       e_m_rc_same(1)
        1       e_ts_rc_same(1)
       (0)      e_charge(1)
       -5.8864  e_Re(1)
       -0.0001  e_U(1)
     (-12.5642) e_h(1)

m_rc_ts(2)
                (.LO, .L, .UP, .M = 0, 0, 282, 0)
        1       e_nrc_lo(2)
        1       e_nrc_up(2)
       (0)      e_nts(2)
        1       e_m_rc_same(2)
        1       e_ts_rc_same(2)
       (0)      e_charge(2)
       -5.8864  e_Re(2)
       -0.0001  e_U(2)

m_rc_ts(3)
                (.LO, .L, .UP, .M = 0, 0, 282, 0)
        1       e_nrc_lo(3)
        1       e_nrc_up(3)
       (0)      e_nts(3)
        1       e_m_rc_same(3)
        1       e_ts_rc_same(3)
       (0)      e_charge(3)
       -5.8864  e_Re(3)
       -0.0001  e_U(3)

m_rc_pb(1)
                (.LO, .L, .UP, .M = 0, 0, 112, 0)
        1       e_nrc_lo(1)
        1       e_nrc_up(1)
        1       e_m_pbmax(1)
    (-838)      e_T_pi(1)
        1       e_m_pb_same(1)
       (0)      e_T_po(1)
       (0)      e_P_out(1)
        1       e_m_rc_same(1)

m_rc_pb(2)
                (.LO, .L, .UP, .M = 0, 0, 112, 0)
        1       e_nrc_lo(2)
        1       e_nrc_up(2)
        1       e_m_pbmax(2)
    (-839)      e_T_pi(2)
        1       e_m_pb_same(2)
      (-0.0597) e_T_po(2)
   (30340)      e_P_out(2)
        1       e_m_rc_same(2)

m_rc_pb(3)
                (.LO, .L, .UP, .M = 0, 0, 112, 0)
        1       e_nrc_lo(3)
        1       e_nrc_up(3)
        1       e_m_pbmax(3)
    (-839)      e_T_pi(3)
        1       e_m_pb_same(3)
      (-0.0597) e_T_po(3)
   (30340)      e_P_out(3)
        1       e_m_rc_same(3)

I don’t know why, the equation e_nrc_lo does not set the binary variable nrc to 1, but just says, that the equation is infeasable. I mean the whole purpose of the equation is to set the variable to 1. Is there something obvious, which I can’t see? Or is it maybe more complicated?

Thanks in advance, guys!

Cheers,
Max

Hi, the equation listing and column Listing shows the value on the initial point, not in the solution. The equations are fine.
You should review the SolEQU and SolVAR section.
Bye!

Hi Manassaldi,

thanks again for your answer. I see, that I missunderstood the columen and the equation listing.
However I wanted to set the binary variable nrc to prevent the division by zero.

e_T_ri(i+1) … T_ri(i+1) =e= (m_ts_rc(i+1)*T_to(i+1) + m_pb_rc(i+1)*T_po(i+1)) / (m_ts_rc(i+1) + m_pb_rc(i+1) + nrc(i+1)) + nrc(i+1)*T_ri(i);

The binary variable should set the value to one when the mass flows m_ts_rc and m_pb_rc are zero, so that a division by zero is prevented. Because of this, I can’t review the solequ and solvar yet, because the model gets an execution error. Is there anyway to prevent this correctly? Or do I just have to add small numbers into the denominator to prevent the division by zero?

Thanks in advance!

Cheers

Hi, In another post I suggested this equation

e_T_pi(i+1) … T_pi(i+1)*(m_rc_pb(i+1)+m_ts_pb(i+1)) =e= (m_rc_pb(i+1)*T_ro + m_ts_pb(i+1)*T_to(i+1));

Hi Manassaldi,

thank you a lot for your answer. Apparently I didn’t realize, that you already provided the solution I needed.
I’m sorry for that. Thank you a lot for you help!

Cheers

Hi, To avoid taking the first element, in my opinion, it is preferable to use this code:

e_T_pi(i)$(ord(i) gt 1) … T_pi(i)*(m_rc_pb(i)+m_ts_pb(i)) =e= (m_rc_pb(i)*T_ro + m_ts_pb(i)*T_to(i));

Bye!

Hi,

I have one question for you Manassaldi.
In my objective function I have this member that is z = […]-TWC(j)*HS(j). Where HS(j)is a variable.

Now, TWC(j) should be a parameter that works like this:

TWC(j) = 0 when HS(j) < 1000

and

TWC(j) = 3.21 when HS(j) >=1000.

Any idea how to implement this in GAMS?

I tried to defined an equation called TWCup(j) that was:

TWCup(j)$(HS.l(j) >= 1000)… TWC(j) =e= 3.21;

but is not working
Thanks :wink:

Hi, I think you can try a simple big-M reformulation.
I assume that “HS(j)” is continuous and positive.
The new variable TWC_HS(j) correspond to TWC(j)*HS(j)
x(j) is a binary variable:
x(j)=1 if HS(j) >=1000.
x(j)=0 if HS(j) < 1000

eq1(j)… HS(j) =g= 1000x(j);
eq2(j)… TWC_HS(j) =g= 3.21
HS(j) - 3.21HS.up(j)(1-x(j));
eq3(j)… TWC_HS(j) =l= 3.21HS(j) + 3.21HS.up(j)(1-x(j));
eq4(j)… HS(j) =l= (1000-1e-10) + HS.up
x(j);
eq5(j)… TWC_HS(j) =l= 3.21HS.up(j)x(j);


So,
if x(j)=1
HS(j) =g= 1000;
TWC_HS(j) =g= 3.21
HS(j);
TWC_HS(j) =l= 3.21
HS(j); (so, TWC_HS(j) = 3.21HS(j))
HS(j) =l= (1000-1e-10) + HS.up; (always satisfied)
TWC_HS(j) =l= 3.21
HS.up(j); (always satisfied)

if x(j)=0
HS(j) =g= 0; (always satisfied)
TWC_HS(j) =g= 3.21HS(j) - 3.21HS.up(j);(always satisfied)
TWC_HS(j) =l= 3.21HS(j) + 3.21HS.up(j);(always satisfied)
HS(j) =l= (1000-1e-10); (1e-10 is to avoid the value of 1000)
TWC_HS(j) =l= 0; (so, TWC_HS(j) = 0*HS(j))

There may be mistakes, but I think it should work.
Bye!

Hi, if p (n) is a parameter, I think it is better to reformulate the intervals definition:

if th >= p(n) then a(n) =0;
else if th < p(n) and th >= p(n) * 10^-.5 then a(n) = .2;
else if th < p(n)*10^-.5 and th >= p(n) * 10^-1 then a(n) = .4;
else if th < p(n)*10^-1 and th >= p(n) * 10^-1.5 then a(n) = .6;
else if th < p(n)*10^-1.5 and th >= p(n) * 10^-2 then a(n) = .8;
else if th < p(n)*10^-2 then a(n) = 1

Now, using binary variables, you must identify which is the interval where “th” is located:

[0 ; p(n)*10^-2) or
[p(n) * 10^-2 ; p(n)*10^-1.5) or
[p(n) * 10^-1.5 ; p(n)*10^-1) or
[p(n) * 10^-1 ; p(n)*10^-.5) or
[p(n)*10^-0.5 ; p(n) ) or
[p(n) ; Max_value]

Is this analysis ok?
Equations for selecting the intervals are easy to implement. Let me know if you need help.
Bye!

Hi, in the previous answer I wrote this code and I saved it as a draft.
I hope this can help you.
Bye!

set
i intervals /i1*i6/
n your nset /n1*n2/
l limits    /l,u/
;
parameter
p(n) /n1 1, n2 3/
intervals(n,i,l)
anvalue(i)
/i1 0
i2  0.2
i3  0.4
i4  0.6
i5  0.8
i6  1/

evalue /1e-6/
;
intervals(n,'i1','l')=0;
intervals(n,'i2','l')=p(n)*(10**(-2));
intervals(n,'i3','l')=p(n)*(10**(-1.5));
intervals(n,'i4','l')=p(n)*(10**(-1));
intervals(n,'i5','l')=p(n)*(10**(-0.5));
intervals(n,'i6','l')=p(n);

intervals(n,'i1','u')=p(n)*(10**(-2))  - evalue;
intervals(n,'i2','u')=p(n)*(10**(-1.5))- evalue;
intervals(n,'i3','u')=p(n)*(10**(-1))  - evalue;
intervals(n,'i4','u')=p(n)*(10**(-.5)) - evalue;
intervals(n,'i5','u')=p(n)                  - evalue;
intervals(n,'i6','u')=p(n)*2;

display intervals;

variable
th
thd(n,i)
a(n)
;
binary variable
bin(n,i)
;
equation
eq1,eq2,eq3,eq4,eq5
;

eq1(n)..   th =e= sum(i,thd(n,i));
eq2(n,i).. thd(n,i) =g= intervals(n,i,'l')*bin(n,i);
eq3(n,i).. thd(n,i) =l= intervals(n,i,'u')*bin(n,i);
eq4(n)..   sum(i,bin(n,i)) =e= 1;
eq5(n)..   a(n) =e= sum(i,bin(n,i)*anvalue(i));

*this is only for testing:
th.lo=0.5; 

model test /all/
solve test using mip minimizing th