Skip to content

PyROS causes Python to crash when solving a model with uncertainty set constrained to be a single value. #2465

Open
@makansij

Description

@makansij

In running my PyROS models, I occasionally get an error that there was no feasible solution found. Even for problems to which I know there is a feasible solution.

Of course, when I fix the parameters to be equal to the feasible solution that is known to exist, and thus remove them from the set of uncertain parameters - it finds the optimal/feasible solution with ease.

However, when these parameters are made to be uncertain again, by creating an uncertainty set such that it includes only the nominal value for the uncertain parameters, then it causes PyROS/Python to crash.

Compare the two examples of runnable code:

## Feasible solution clearly exists, because when we make the uncertain parameters to be certain, it finds the solution


# === Required import ===
import pyomo.kernel as pmo
import numpy as np
import pyomo.environ as pe
import pyomo.contrib.pyros as pyros

# === Instantiate the PyROS solver object ===
pyros_solver = pe.SolverFactory("pyros")

def d_init(m, ix):
    if ix == 19:
        return 1
    return 0

def t_init(m, i):
    t = 0.5*np.ones((1,m.n))
    return t[0,i]

# === Construct the Pyomo model object ===
m = pe.ConcreteModel()
n = m.n = 3
Q = m.Q = 20
N = m.N = 2

# === Define continuous variables ===
m.del_component('L')
m.add_component('L', pe.Var(range(n), range(n*Q*N), within=pe.Reals))

# === Define parameters ===
m.t = pe.Param(range(n), initialize=t_init, mutable=True)
m.d = pe.Param(range(Q), initialize=d_init, mutable=True)

# === Specify the objective function ===
m.del_component('objective')
m.add_component('objective', pe.Objective(expr=0)) 

S=2
M=1
W=5
# === Specify the constraints ===
m.del_component('c1')
m.add_component('c1', pe.Constraint(expr= 0 <= S*m.t[0] + W*m.d[0] + m.d[1]*M*m.L[0,1]*m.t[1])) 


results = ipopt_solver.solve(m)

Now look at the example below, where the uncertain parameters are introduced, yet fixed to a single value. This causes Python/PyROS to crash on my machine:

### In the example below, the parameters are made to be uncertain, but fixed to a particular value,...
### ...and this causes PyROS/Python to crash

# === Required import ===
import pyomo.kernel as pmo
import numpy as np
import pyomo.environ as pe
import pyomo.contrib.pyros as pyros

# === Instantiate the PyROS solver object ===
pyros_solver = pe.SolverFactory("pyros")

def d_init(m, ix):
    if ix == 19:
        return 1
    return 0

def t_init(m, i):
    t = 0.5*np.ones((1,m.n))
    return t[0,i]

# === Construct the Pyomo model object ===
m = pe.ConcreteModel()
n = m.n = 3
Q = m.Q = 20
N = m.N = 2

# === Define continuous variables ===
m.del_component('L')
m.add_component('L', pe.Var(range(n), range(n*Q*N), within=pe.Reals))

# === Define parameters ===
m.t = pe.Param(range(n), initialize=t_init, mutable=True)
m.d = pe.Param(range(Q), initialize=d_init, mutable=True)

# === Specify the objective function ===
m.del_component('objective')
m.add_component('objective', pe.Objective(expr=0)) 

S=2
M=1
W=5
# === Specify the constraints ===
m.del_component('c1')
m.add_component('c1', pe.Constraint(expr= 0 <= S*m.t[0] + W*m.d[0] + m.d[1]*M*m.L[0,1]*m.t[1])) 

# === Specify which parameters are uncertain ===
uncertain_parameters = [m.t, m.d] # We can pass IndexedParams this way to PyROS, or as an expanded list per index
# === Define the pertinent data ===

bounds_t = [(0.5, 0.5)]*pe.value(m.n)
bounds_d = [(0,0)]*pe.value(m.Q)
bounds_d[19] = (1,1)
bounds = bounds_t + bounds_d

# === Construct the desirable uncertainty set ===
box_uncertainty_set = pyros.BoxSet(bounds=bounds)

# === Designate local and global NLP solvers ===
ipopt_solver = pe.SolverFactory('appsi_ipopt')

local_solver = ipopt_solver
global_solver = ipopt_solver

# === Designate which variables correspond to first- and second-stage degrees of freedom ===
first_stage_variables =[m.L]
second_stage_variables = []
# The remaining variables are implicitly designated to be state variables

# === Call PyROS to solve the robust optimization problem ===
results_1 = pyros_solver.solve(model = m,
                                 first_stage_variables = first_stage_variables,
                                 second_stage_variables = second_stage_variables,
                                 uncertain_params = uncertain_parameters,
                                 uncertainty_set = box_uncertainty_set,
                                 local_solver = local_solver,
                                 global_solver = global_solver,
                                 tee=True,
                                 options = {
                                    "objective_focus": pyros.ObjectiveType.worst_case,
                                    "solve_master_globally": True,
                                    "load_solution":False
                                  })

# === Query results ===
time = results_1.time
iterations = results_1.iterations
termination_condition = results_1.pyros_termination_condition
objective = results_1.final_objective_value
# === Print some results ===
single_stage_final_objective = round(objective,-1)
print("Final objective value: %s" % single_stage_final_objective)

print("PyROS termination condition: %s" % termination_condition)

I'm running:

  • MacOS Monterey 12.4
  • Python 3.7

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions