Search code examples
optimizationgekko

Access decision variable value in function outside objective function Gekko


I need to access the decision variable outside the objective function. I have the following.

tc_var = {}
for index in index_f_a:
    tc_var[index] = m.Var(value=25, name='tc_var_{}'.format(index), lb=15, ub=45, integer=False)

def k1(i, z, j, a):
    a_dif = tce[(i, z, j, a)] - tc_var[(i, j)].VALUE
    return a_dif if a_dif > 0 else 0


m.Minimize(m.sum([k1(i, z, j, a)*KCA for i, z, j, a in index_f_h_a_v]))

In another question, it was told that using .value in the objective only uses the initial value. How can I do this the correct way (access the value decision)?

Thank you.

If I do not use .value, I get the following error:

enter image description here enter image description here

SOLVED With

def k1(i, z, j, a):
    d = m.Var(lb=0)
    s = m.Var(lb=0)
    m.Minimize(1e-3*s)
    m.Equation(d == (tce[(i, z, j, a)] - tc_var[(i, j)])*KCA + s)
    return d

m.Minimize(
m.sum([k1(i, z, j, a) for i, z, j, a in index_f_h_a_v]))

Solution

  • For conditional statements, use the m.if3() function such as:

    def k1(i, z, j, a):
        d = m.Intermediate(tce[(i, z, j, a)] - tc_var[(i, j)])
        a_dif = m.if3(d,0,d)
        return a_dif
    

    This adds a binary decision variable so the APOPT solver (m.options.SOLVER=1)must be used to solve the Mixed Integer solution. If there are many binary decision variables, the solution can take much longer. An alternative method is to use a slack variable s so that d remains positive such as:

    def k1(i, z, j, a):
        d = m.Var(lb=0)
        s = m.Var(lb=0)
        m.Minimize(1e-3*s)
        m.Equation(d==tce[(i, z, j, a)] - tc_var[(i, j)]+s)
        return d
    

    The problem with this approach is that the minimization of s may interfere with other competing objectives. The 1e-3 can be adjusted to tune the optimization problem.