Accessing the values of all variable in a multiscenario model for sensitivity analysis
Awaiting user inputI am trying to run sensitivity analysis on a model named scnd1 by increasing the budget by 10% in each scenario (Total 10 such scenarios are there). I want to access the value of all the variables of my model in each scenario along with the objective function value and then I want to write it to an excel file. But, cells remain blank by all the writing operations in the code sensitivity1.py. Am I doing anything wrong? Also, I am writing the .sol file using model.write() for each scenario. Each of these files contains the same values for all variables and objective function.
# -*- coding: utf-8 -*-
"""
Created on Tue May 24 14:43:16 2022
@author: hp
"""
# -*- coding: utf-8 -*-
"""
Created on Fri May 20 18:48:45 2022
@author: hp
"""
import sys
import gurobipy as gp
from gurobipy import GRB
from datetime import date
# from basemodelcode import*
from readData import*
maxScenarios = 10
import pandas as pd
# if len(sys.argv) < 2:
# print('Usage: sensitivity.py filename')
# sys.exit(0)
# Read model
filename=f'D:\ppr 3\\lpFiles\LP_scnd{date.today()}.lp'
# model = gp.read(sys.argv[1])
model = gp.read(filename)
if model.IsMIP == 0:
print('Model is not a MIP')
# Solve model
model.optimize()
for v in model.getVars():
if v.x>0.01:
print(v.varName, v.x)
print('Objective function value:',model.objVal)
if model.Status != GRB.OPTIMAL:
print(f'Optimization ended with status {model.Status}')
# Store the optimal solution
origObjVal = model.ObjVal
for v in model.getVars():
v._origX = v.X
increased_budget1=[(i*0.1)*budget1 for i in range(11,21,1)]
scenarios = 0
for i in range(len(increased_budget1)):
scenarios+=1
if scenarios >= maxScenarios:
break
model.NumScenarios = scenarios
# Count number of unfixed, binary variables in model. For each we create a
# scenario.
# for v in model.getVars():
# if (v.VType in (GRB.BINARY)):
# scenarios += 1
# if scenarios >= maxScenarios:
# print(f'created scenarios={scenarios} increase the max number of scenarios->out of loop')
# break
scenarios = 0
for p in increased_budget1:
if scenarios<maxScenarios:
model.Params.ScenarioNumber = scenarios
# increased_budget1=budget1*0.1*p
constraint = model.getConstrByName('Strategic_budget')
# model.setAttr("RHS", constraint, p)
constraint.ScenNRhs=p
# budget1_list.append(increased_budget1)
# change_budget('Strategic_budget',increased_budget1)
scenarios+= 1
# else:
# v.Start = v._origX
# Set the number of scenarios in the model
# model.NumScenarios = scenarios
print(f'The no. of scenarios in the model is {scenarios}')
print('############ construct multi-scenario model with {scenarios} scenarios #################')
# Create a (single) scenario model by iterating through unfixed binary
# variables in the model and create for each of these variables a scenario
# by fixing the variable to 1-X, where X is its value in the computed
# optimal solution
# scenarios = 0
# for v in model.getVars():
# if (v.VType in (GRB.BINARY) and scenarios < maxScenarios):
# # Set ScenarioNumber parameter to select the corresponding scenario
# # for adjustments
# model.Params.ScenarioNumber = scenarios
# # Set variable to 1-X, where X is its value in the optimal solution
# if v._origX < 0.5:
# v.ScenNLB = 1.0
# else:
# v.ScenNUB = 0.0
# scenarios += 1
# else:
# # Add MIP start for all other variables using the optimal solution of the base model
# v.Start = v._origX
model.update()
# Solve multi-scenario model
model.optimize()
# In case we solved the scenario model to optimality capture the sensitivity information
if model.Status == GRB.OPTIMAL:
modelSense = model.ModelSense
scenarios = 0
# Capture sensitivity information from each scenario
# for s in range(model.NumScenarios):
for t in model.getVars():
# if (v.VType in (GRB.BINARY)):
# Set scenario parameter to collect the objective value of the corresponding scenario
model.Params.ScenarioNumber = scenarios
# Collect objective value and bound for the scenario
scenarioObjVal = model.ScenNObjVal
scenarioObjBound = model.ScenNObjBound
# Check if we found a feasible solution for this scenario
if scenarioObjVal >= modelSense * GRB.INFINITY:
# Check if the scenario is infeasible
if scenarioObjBound >= modelSense * GRB.INFINITY:
print(f'Objective sensitivity for variable {v.VarName} is infeasible')
else:
print(f'Objective sensitivity for variable {v.VarName} is unknown (no solution available)')
else:
matrix1 = [[q_cap[f,b].X for f in food] for b in all_fb if v.VarName=='q_cap_fb']
df1 = pd.DataFrame(matrix1, columns=food, index=all_fb)
matrix2=[[q[f,b].ScenNX for f in food] for b in all_fb if v.VarName=='q_fb']
df2 = pd.DataFrame(matrix2, columns=food, index=all_fb)
with pd.ExcelWriter(f'EXCEL_SOL{date.today()}_{scenarios}.xlsx') as writer:
df1.to_excel(writer,sheet_name='q_cap_fb')
df2.to_excel(writer,sheet_name='q_fb')
writer.save()
print('Objective function value:',scenarioObjVal)
# Scenario is feasible and a solution is available
print(f'Objective sensitivity for budget with initial value={origObjVal}\
and scenario obj val {scenarioObjVal}is {modelSense * (scenarioObjVal - origObjVal)}')
model.write(f'D:\ppr 3\LPscenarios\{scenarios}.lp')
model.write(f'D:\ppr 3\\SOLscenarios\{scenarios}.sol')
scenarios += 1
if scenarios >= maxScenarios:
print(f'created scenarios={scenarios} increase the max number of scenarios->out of capture sensitivity loop')
break
-
Could you please either edit your post or add a comment where you modify your example such that it is reproducible and minimal? There is a lot of code, which (I think) does nothing w.r.t. you issue. Additionally, there are input files missing. Since it is not possible to upload files to the Community, we provide an alternative as described in Posting to the Community Forum.
Best regards,
Jaromił0
Please sign in to leave a comment.
Comments
1 comment