-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsensitivity.py
executable file
·131 lines (97 loc) · 3.78 KB
/
sensitivity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3.9
# Copyright 2022, Gurobi Optimization, LLC
# A simple sensitivity analysis example which reads a MIP model from a file
# and solves it. Then uses the scenario feature to analyze the impact
# w.r.t. the objective function of each binary variable if it is set to
# 1-X, where X is its value in the optimal solution.
#
# Usage:
# sensitivity.py <model filename>
#
import sys
import gurobipy as gp
from gurobipy import GRB
# Maximum number of scenarios to be considered
maxScenarios = 100
if len(sys.argv) < 2:
print('Usage: sensitivity.py filename')
sys.exit(0)
# Read model
model = gp.read(sys.argv[1])
if model.IsMIP == 0:
print('Model is not a MIP')
sys.exit(0)
# Solve model
model.optimize()
if model.Status != GRB.OPTIMAL:
print('Optimization ended with status %d' % model.Status)
sys.exit(0)
# Store the optimal solution
origObjVal = model.ObjVal
for v in model.getVars():
v._origX = v.X
scenarios = 0
# Count number of unfixed, binary variables in model. For each we create a
# scenario.
for v in model.getVars():
if (v.LB == 0.0 and v.UB == 1.0 and v.VType in (GRB.BINARY, GRB.INTEGER)):
scenarios += 1
if scenarios >= maxScenarios:
break
# Set the number of scenarios in the model
model.NumScenarios = scenarios
scenarios = 0
print('### construct multi-scenario model with %d 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
for v in model.getVars():
if (v.LB == 0.0 and v.UB == 1.0
and v.VType in (GRB.BINARY, GRB.INTEGER)
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
# 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 v in model.getVars():
if (v.LB == 0.0 and v.UB == 1.0 and v.VType in (GRB.BINARY, GRB.INTEGER)):
# 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('Objective sensitivity for variable %s is infeasible' %
v.VarName)
else:
print('Objective sensitivity for variable %s is unknown (no solution available)' %
v.VarName)
else:
# Scenario is feasible and a solution is available
print('Objective sensitivity for variable %s is %g' %
(v.VarName, modelSense * (scenarioObjVal - origObjVal)))
scenarios += 1
if scenarios >= maxScenarios:
break