RHS Not Being Updated in MultiScenario Problem
Awaiting user inputHi,
I am trying to make a multi scenario model where, for each scenario, we explore incrementing a single constraint. I have been using the sensitivity example for reference.
I have implemented a class, SensitivityAnalyzer, which is basically a wrapper around a base problem. I am implementing a class to make a user interface easier, farther down the road.
class SensitivityAnalyzer:
def __init__(
self,
base_problem : VBAProblem,
):
"""
Arguments
------------
base_problem : VBA_Problem
Base problem we'll build the scenarios from
increment : int
How much to increment each element we'll generate a scenario for.
sets : typing.Iterable[str]
Any of ('L','C','V','S') that indicate which set we want to generate scenarios over. We will increment each element of teh requested sets and generate a scenario for each incremented element
omissions : dict[str, set[str]]
A dict whose keys must be contained in sets. For the requested sets, do not generate a scenario for the element's in this args keys.
"""
self.Model=base_problem.Model
self.Model.num_scenarios = 0
def generate_scenarios(self, base_problem, increment, sets, omissions = None) :
scen_index = 0
for it in sets:
#elements to generate scenario which are the base set - the elements of the set
#that are present in omissions
els = base_problem.getSet(it)
#if they provided some omissions, remove them from this elements
if omissions :
els = els - omissions.get(it,set())
self.Model.num_scenarios += len(els)
self.Model.update()
for e in els:
# logging.debug(f'Generating scenario {scen_index+1} / {self.Model.NumScenarios}')
#make scenario where this element is incremented
self.generate_constraint_scenario(
scen_index,
f'{it}_supply_{e.ID}',
increment
)
#increment scenario number so next loop is new scenario
scen_index += 1
logging.info(f'{len(els)} scenarios generated for set {it}.')
def generate_constraint_scenario(self,scenNum , element_name, increment) :
#Initialize the scenario with the scenario number, give it a name
self.Model.Params.ScenarioNumber =scenNum
self.Model.ScenNName = element_name
#get the constraint we're gonna modify
constr = self.Model.getConstrByName(element_name)
assert constr is not None, f'Unable to retrieve constraint {element_name}'
#save the original value
og_rhs = constr.RHS
#increment it
new_rhs=og_rhs+increment
logging.debug(f'Setting {element_name} RHS to {new_rhs} from {og_rhs}')
#set constraint right hand side to new value
constr.ScenNRHS=new_rhs
The output when I am generating the scenarios looks good. I can see that new_rhs has the correct value in SensitivityAnalyzer::generate_constraint_scenario
sa = SensitivityAnalyzer(P)
sa.generate_scenarios(P, 500000, ['C'])
Outputs, as expected
DEBUG: Setting C_supply_301-0963|E RHS to 2890200.0 from 2390200.0
DEBUG: Setting C_supply_300-8792|E2 RHS to 2490200.0 from 1990200.0
DEBUG: Setting C_supply_301-0963|G RHS to 2699296.0 from 2199296.0
DEBUG: Setting C_supply_301-0963|K RHS to 2940200.0 from 2440200.0
DEBUG: Setting C_supply_300-8792|M RHS to 2940200.0 from 2440200.0
DEBUG: Setting C_supply_300-8792|N RHS to 2150200.0 from 1650200.0
DEBUG: Setting C_supply_300-8792|L RHS to 3040200.0 from 2540200.0
DEBUG: Setting C_supply_300-8792|B RHS to 5530000.0 from 5030000.0
INFO: 8 scenarios generated for set C.
But once I call
sa.Model.optimize()
and inspect the constraint RHS in each of the scenarios, they are still at their original values.
for i in range(sa.Model.num_scenarios):
sa.Model.Params.ScenarioNumber =i
print(sa.Model.ScenNName)
print('Base Problem RHS:', P.Model.getConstrByName(sa.Model.ScenNName).RHS)
print(f'Scenario {i} RHS: ', sa.Model.getConstrByName(sa.Model.ScenNName).RHS)
print(f'Scenario {i} Obj Val', sa.Model.ScenNObjVal)
Outputs
C_supply_301-0963|K
Base Problem RHS: 2440200.0
Scenario 0 RHS: 2440200.0
Scenario 0 Obj Val 8162244.5C_supply_300-8792|M
Base Problem RHS: 2440200.0
Scenario 1 RHS: 2440200.0
Scenario 1 Obj Val 8162244.5C_supply_300-8792|B
Base Problem RHS: 5030000.0
Scenario 2 RHS: 5030000.0
Scenario 2 Obj Val 8162244.5C_supply_301-0963|G
Base Problem RHS: 2199296.0
Scenario 3 RHS: 2199296.0
Scenario 3 Obj Val 8162244.5C_supply_300-8792|L
Base Problem RHS: 2540200.0
Scenario 4 RHS: 2540200.0
Scenario 4 Obj Val 8162244.5C_supply_301-0963|E
Base Problem RHS: 2390200.0
Scenario 5 RHS: 2390200.0
Scenario 5 Obj Val 8162244.5C_supply_300-8792|N
Base Problem RHS: 1650200.0
Scenario 6 RHS: 1650200.0
Scenario 6 Obj Val 8162244.5C_supply_300-8792|E2
Base Problem RHS: 1990200.0
Scenario 7 RHS: 1990200.0
Scenario 7 Obj Val 8162244.5
Not too sure what I'm overlooking here.
-
Hi,
You seem to be referring to the RHS attribute for each scenario.print(f'Scenario {i} RHS: ', sa.Model.getConstrByName(sa.Model.ScenNName).RHS)
Does it work if you change it to ScenNRHS attribute?
print(f'Scenario {i} RHS: ', sa.Model.getConstrByName(sa.Model.ScenNName).ScenNRHS)
Regards,
Ryuta0
Please sign in to leave a comment.
Comments
1 comment