pyomoipopt

Warm Starting - Pyomo


I am relatively new to Pyomo and was trying to find a way to do the following: I have a robot model which consists of many variables, parameters, constraints and an objective function. The model consists of torques and contact penalties. After running the ipopt solver (specifying initial and final conditions along with initializing the variables) the solution was optimal. The objective function only incorporated contact penalties.

I would like to rerun the model with the above solution as initialized values but with an updated the objective function (which includes both contact penalties and torque^2). Is there a way to do this?

The reason for not including it in the first run is that the solver tends to take super long and either return infeasible or has a restoration error. Doing it this way allows me to find a feasible solution and thereafter the optimal one.

I have tried the following example here. However, I'm unsure on how to incorporate the updated objective function.


Solution

  • There are a few options for changing the objective function between solves. The first is to declare multiple Objective components and use activate and deactivate to swap which one gets sent to the solver:

    m.obj1 = Objective(expr=m.x)
    m.obj2 = Objective(expr=m.x + m.y**2)
    m.obj2.deactivate()
    SolverFactory('ipopt').solve(m) # obj1 is sent to the solver
    
    m.obj1.deactivate()
    m.obj2.activate()
    SolverFactory('ipopt').solve(m) # obj2 is sent to the solver
    

    Another way is to use mutable Param components to change weights in the objective function:

    m.p = Param(mutable=True, initialize=0)
    m.obj = Objective(expr=m.x + m.p*m.y**2)
    SolverFactory('ipopt').solve(m) # m.p is 0 so second term in obj is effectively removed
    
    m.p = 10
    SolverFactory('ipopt').solve(m) # m.p is 10 so second term in obj is seen by solver
    

    Finally, you could use Expression components for different terms in the objective function which could be modified independently between solves:

    m.o_exp1 = Expression(expr=m.x)
    m.o_exp2 = Expression(expr=0)
    m.obj = Objective(expr=m.o_exp1 + m.o_exp2)
    SolverFactory('ipopt').solve(m) # obj = m.x
    
    m.o_exp2 = m.y**2
    SolverFactory('ipopt').solve(m) # obj = m.x + m.y**2