sensitivity_cs.cs#
// Copyright 2025, 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_cs <model filename>
using System;
using Gurobi;
class sensitivity_cs
{
// Maximum number of scenarios to be considered
public const int MAXSCENARIOS = 100;
static void Main(string[] args)
{
const int maxscenarios = sensitivity_cs.MAXSCENARIOS;
if (args.Length < 1) {
Console.Out.WriteLine("Usage: sensitivity_cs filename");
return;
}
try {
// Create environment
GRBEnv env = new GRBEnv();
// Read model
GRBModel model = new GRBModel(env, args[0]);
int scenarios;
if (model.IsMIP == 0) {
Console.WriteLine("Model is not a MIP");
return;
}
// Solve model
model.Optimize();
if (model.Status != GRB.Status.OPTIMAL) {
Console.WriteLine("Optimization ended with status " + model.Status);
return;
}
// Store the optimal solution
double origObjVal = model.ObjVal;
GRBVar[] vars = model.GetVars();
double[] origX = model.Get(GRB.DoubleAttr.X, vars);
scenarios = 0;
// Count number of unfixed, binary variables in model. For each we
// create a scenario.
for (int i = 0; i < vars.Length; i++) {
GRBVar v = vars[i];
char vType = v.VType;
if (v.LB == 0.0 && v.UB == 1.0 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) ) {
scenarios++;
if (scenarios >= maxscenarios)
break;
}
}
Console.WriteLine("### construct multi-scenario model with "
+ scenarios + " scenarios");
// Set the number of scenarios in the model */
model.NumScenarios = scenarios;
scenarios = 0;
// 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 (int i = 0; i < vars.Length; i++) {
GRBVar v = vars[i];
char vType = v.VType;
if (v.LB == 0.0 && v.UB == 1.0 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) &&
scenarios < maxscenarios ) {
// Set ScenarioNumber parameter to select the corresponding
// scenario for adjustments
model.Parameters.ScenarioNumber = scenarios;
// Set variable to 1-X, where X is its value in the optimal solution */
if (origX[i] < 0.5)
v.ScenNLB = 1.0;
else
v.ScenNUB = 0.0;
scenarios++;
} else {
// Add MIP start for all other variables using the optimal solution
// of the base model
v.Start = origX[i];
}
}
// Solve multi-scenario model
model.Optimize();
// In case we solved the scenario model to optimality capture the
// sensitivity information
if (model.Status == GRB.Status.OPTIMAL) {
// get the model sense (minimization or maximization)
int modelSense = model.ModelSense;
scenarios = 0;
for (int i = 0; i < vars.Length; i++) {
GRBVar v = vars[i];
char vType = v.VType;
if (v.LB == 0.0 && v.UB == 1.0 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) ) {
// Set scenario parameter to collect the objective value of the
// corresponding scenario
model.Parameters.ScenarioNumber = scenarios;
double scenarioObjVal = model.ScenNObjVal;
double scenarioObjBound = model.ScenNObjBound;
Console.Write("Objective sensitivity for variable "
+ v.VarName + " is ");
// Check if we found a feasible solution for this scenario
if (modelSense * scenarioObjVal >= GRB.INFINITY) {
// Check if the scenario is infeasible
if (modelSense * scenarioObjBound >= GRB.INFINITY)
Console.WriteLine("infeasible");
else
Console.WriteLine("unknown (no solution available)");
} else {
// Scenario is feasible and a solution is available
Console.WriteLine(modelSense * (scenarioObjVal - origObjVal));
}
scenarios++;
if (scenarios >= maxscenarios)
break;
}
}
}
// Dispose of model and environment
model.Dispose();
env.Dispose();
} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode);
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}