Cole
Cole

Reputation: 21

How do I use m.sign3 or m.sign2 to limit the number of nonzero variables used in the equation

I am trying to optimize this equation by limiting the number of nonzero variables I want to use. x,z,w keep coming back as 0 numbers

from gekko import GEKKO
m = GEKKO()
# creates the variables
x = m.sos1([0,2])
z = m.sos1([0,3])
w = m.sos1([0,4])
# use sign2 to define a new variable
y = m.sign2(x)
t = m.sign2(z)
v = m.sign2(w)
# Equation
m.Equation(y+t+v<=2)
m.Equation(x+z+w>=5)
#objective
m.Obj((x+z+w)*-1)
m.solve(disp=False) 

Sometimes I get back the sign2 values as negatives when I want them to remain as zero.

Upvotes: 2

Views: 286

Answers (1)

John Hedengren
John Hedengren

Reputation: 14346

This code:

from gekko import GEKKO
m = GEKKO(remote=False)
# creates the variables
x = m.sos1([0,2])
z = m.sos1([0,3])
w = m.sos1([0,4])
# use sign2 to define a new variable
y = m.sign2(x)
t = m.sign2(z)
v = m.sign2(w)
# Equation
m.Equation(y+t+v<=2)
m.Equation(x+z+w>=5)
#objective
m.Obj((x+z+w)*-1)
m.solve(disp=False) 

print('Maximize x,z,w')
print('Sum greater than or equal to 5')
print('x,z,w')
print(x.value[0],z.value[0],w.value[0])
print('Sum less than or equal to 2')
print('y,t,v')
print(y.value[0],t.value[0],v.value[0])

Gives the correct solution:

Maximize x,z,w
Sum greater than or equal to 5
x,z,w
2.0 3.0 0.0
Sum less than or equal to 2
y,t,v
1.0 1.0 0.0

However, as you noted the solution has the potential to give a negative signum result if the computing tolerance produces x,z, or w that is slightly negative, even -1e-6. If you avoid the switch location then you'll likely get a more reliable solution. The sign3 often gives a better solution.

from gekko import GEKKO
m = GEKKO(remote=False)
# creates the variables
x = m.sos1([-1e-4,2])
z = m.sos1([-1e-4,3])
w = m.sos1([-1e-4,4])
# use sign2 to define a new variable
y,t,v = m.Array(m.Var,3,lb=0,ub=1)
m.Equation(y==(m.sign3(x)+1)/2)
m.Equation(t==(m.sign3(z)+1)/2)
m.Equation(v==(m.sign3(w)+1)/2)
# Equation
m.Equation(y+t+v<=2)
m.Equation(x+z+w>=5)
#objective
m.Obj((x+z+w)*-1)
m.solve(disp=False) 

print('Maximize x,z,w')
print('Sum greater than or equal to 5')
print('x,z,w')
print(x.value[0],z.value[0],w.value[0])
print('Sum less than or equal to 2')
print('y,t,v')
print(y.value[0],t.value[0],v.value[0])

In this case, both scripts give the same solution.

Upvotes: 1

Related Questions