Sensitivity Examples#
This section includes source code for all of the Gurobi sensitivity examples.
The same source code can be found in the examples
directory of the
Gurobi distribution.
/* 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_c <model filename>
*/
#include <stdlib.h>
#include <stdio.h>
#include "gurobi_c.h"
/* Maximum number of scenarios to be considered */
#define MAXSCENARIOS 100
int
main(int argc,
char *argv[])
{
GRBenv *env = NULL;
GRBenv *modelenv = NULL;
GRBmodel *model = NULL;
double *origx = NULL;
double origObjVal;
int ismip, status, numvars, i;
int scenarios;
int error = 0;
if (argc < 2) {
fprintf(stderr, "Usage: sensitivity_c filename\n");
goto QUIT;
}
/* Create environment */
error = GRBloadenv(&env, "sensitivity.log");
if (error) goto QUIT;
/* Read model */
error = GRBreadmodel(env, argv[1], &model);
if (error) goto QUIT;
modelenv = GRBgetenv(model);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_IS_MIP, &ismip);
if (error) goto QUIT;
if (ismip == 0) {
printf("Model is not a MIP\n");
goto QUIT;
}
/* Solve model */
error = GRBoptimize(model);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &status);
if (error) goto QUIT;
if (status != GRB_OPTIMAL) {
printf("Optimization ended with status %d\n", status);
goto QUIT;
}
/* Store the optimal solution */
error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &origObjVal);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_NUMVARS, &numvars);
if (error) goto QUIT;
origx = (double *) malloc(numvars * sizeof(double));
if (origx == NULL) {
printf("Out of memory\n");
goto QUIT;
}
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, numvars, origx);
if (error) goto QUIT;
scenarios = 0;
/* Count number of unfixed, binary variables in model. For each we create a
* scenario.
*/
for (i = 0; i < numvars; i++) {
double lb, ub;
char vtype;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_LB, i, &lb);
if (error) goto QUIT;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_UB, i, &ub);
if (error) goto QUIT;
error = GRBgetcharattrelement(model, GRB_CHAR_ATTR_VTYPE, i, &vtype);
if (error) goto QUIT;
if (lb == 0.0 && ub == 1.0 &&
(vtype == GRB_BINARY || vtype == GRB_INTEGER) ) {
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
printf("### construct multi-scenario model with %d scenarios\n", scenarios);
/* Set the number of scenarios in the model */
error = GRBsetintattr(model, GRB_INT_ATTR_NUMSCENARIOS, scenarios);
if (error) goto QUIT;
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 (i = 0; i < numvars; i++) {
double lb, ub;
char vtype;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_LB, i, &lb);
if (error) goto QUIT;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_UB, i, &ub);
if (error) goto QUIT;
error = GRBgetcharattrelement(model, GRB_CHAR_ATTR_VTYPE, i, &vtype);
if (error) goto QUIT;
if (lb == 0.0 && ub == 1.0 &&
(vtype == GRB_BINARY || vtype == GRB_INTEGER) &&
scenarios < MAXSCENARIOS ) {
/* Set ScenarioNumber parameter to select the corresponding scenario
* for adjustments
*/
error = GRBsetintparam(modelenv, GRB_INT_PAR_SCENARIONUMBER, scenarios);
if (error) goto QUIT;
/* Set variable to 1-X, where X is its value in the optimal solution */
if (origx[i] < 0.5) {
error = GRBsetdblattrelement(model, GRB_DBL_ATTR_SCENNLB, i, 1.0);
if (error) goto QUIT;
} else {
error = GRBsetdblattrelement(model, GRB_DBL_ATTR_SCENNUB, i, 0.0);
if (error) goto QUIT;
}
scenarios++;
} else {
/* Add MIP start for all other variables using the optimal solution
* of the base model
*/
error = GRBsetdblattrelement(model, GRB_DBL_ATTR_START, i, origx[i]);
if (error) goto QUIT;
}
}
/* Solve multi-scenario model */
error = GRBoptimize(model);
if (error) goto QUIT;
/* Collect the status */
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &status);
if (error) goto QUIT;
/* In case we solved the scenario model to optimality capture the
* sensitivity information
*/
if (status == GRB_OPTIMAL) {
int modelSense;
scenarios = 0;
/* Get model sense (minimization or maximization) */
error = GRBgetintattr(model, GRB_INT_ATTR_MODELSENSE, &modelSense);
if (error) goto QUIT;
for (i = 0; i < numvars; i++) {
double lb, ub;
char vtype;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_LB, i, &lb);
if (error) goto QUIT;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_UB, i, &ub);
if (error) goto QUIT;
error = GRBgetcharattrelement(model, GRB_CHAR_ATTR_VTYPE, i, &vtype);
if (error) goto QUIT;
if (lb == 0.0 && ub == 1.0 &&
(vtype == GRB_BINARY || vtype == GRB_INTEGER) ) {
double scenarioObjVal;
double scenarioObjBound;
char *varName;
/* Set scenario parameter to collect the objective value of the
* corresponding scenario
*/
error = GRBsetintparam(modelenv, GRB_INT_PAR_SCENARIONUMBER, scenarios);
if (error) goto QUIT;
/* Collect objective value and bound for the scenario */
error = GRBgetdblattr(model, GRB_DBL_ATTR_SCENNOBJVAL, &scenarioObjVal);
if (error) goto QUIT;
error = GRBgetdblattr(model, GRB_DBL_ATTR_SCENNOBJBOUND, &scenarioObjBound);
if (error) goto QUIT;
error = GRBgetstrattrelement(model, GRB_STR_ATTR_VARNAME, i, &varName);
if (error) goto QUIT;
/* 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)
printf("Objective sensitivity for variable %s is infeasible\n",
varName);
else
printf("Objective sensitivity for variable %s is unknown (no solution available)\n",
varName);
} else {
/* Scenario is feasible and a solution is available */
printf("Objective sensitivity for variable %s is %g\n",
varName, modelSense * (scenarioObjVal - origObjVal));
}
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
}
QUIT:
/* Error reporting */
if (error != 0) {
printf("ERROR: %s\n", GRBgeterrormsg(env));
exit(1);
}
/* Free data */
free(origx);
/* Free model */
GRBfreemodel(model);
/* Free environment */
GRBfreeenv(env);
return 0;
}
// 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_c++ <model filename>
#include "gurobi_c++.h"
using namespace std;
// Maximum number of scenarios to be considered
#define MAXSCENARIOS 100
int
main(int argc,
char *argv[])
{
if (argc < 2) {
cout << "Usage: sensitivity_c++ filename" << endl;
return 1;
}
GRBVar *vars = NULL;
double *origX = NULL;
try {
// Create environment
GRBEnv env = GRBEnv();
// Read model
GRBModel model = GRBModel(env, argv[1]);
int scenarios;
if (model.get(GRB_IntAttr_IsMIP) == 0) {
cout << "Model is not a MIP" << endl;
return 1;
}
// Solve model
model.optimize();
if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL) {
cout << "Optimization ended with status "
<< model.get(GRB_IntAttr_Status) << endl;
return 1;
}
// Store the optimal solution
double origObjVal = model.get(GRB_DoubleAttr_ObjVal);
vars = model.getVars();
int numVars = model.get(GRB_IntAttr_NumVars);
origX = model.get(GRB_DoubleAttr_X, vars, numVars);
scenarios = 0;
// Count number of unfixed, binary variables in model. For each we
// create a scenario.
for (int i = 0; i < numVars; i++) {
GRBVar v = vars[i];
char vType = v.get(GRB_CharAttr_VType);
if (v.get(GRB_DoubleAttr_LB) == 0.0 &&
v.get(GRB_DoubleAttr_UB) == 1.0 &&
(vType == GRB_BINARY || vType == GRB_INTEGER) ) {
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
cout << "### construct multi-scenario model with "
<< scenarios << " scenarios" << endl;
// Set the number of scenarios in the model */
model.set(GRB_IntAttr_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 < numVars; i++) {
GRBVar v = vars[i];
char vType = v.get(GRB_CharAttr_VType);
if (v.get(GRB_DoubleAttr_LB) == 0.0 &&
v.get(GRB_DoubleAttr_UB) == 1-0 &&
(vType == GRB_BINARY || vType == GRB_INTEGER) &&
scenarios < MAXSCENARIOS ) {
// Set ScenarioNumber parameter to select the corresponding
// scenario for adjustments
model.set(GRB_IntParam_ScenarioNumber, scenarios);
// Set variable to 1-X, where X is its value in the optimal solution */
if (origX[i] < 0.5)
v.set(GRB_DoubleAttr_ScenNLB, 1.0);
else
v.set(GRB_DoubleAttr_ScenNUB, 0.0);
scenarios++;
} else {
// Add MIP start for all other variables using the optimal solution
// of the base model
v.set(GRB_DoubleAttr_Start, origX[i]);
}
}
// Solve multi-scenario model
model.optimize();
// In case we solved the scenario model to optimality capture the
// sensitivity information
if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL) {
// get the model sense (minimization or maximization)
int modelSense = model.get(GRB_IntAttr_ModelSense);
scenarios = 0;
for (int i = 0; i < numVars; i++) {
GRBVar v = vars[i];
char vType = v.get(GRB_CharAttr_VType);
if (v.get(GRB_DoubleAttr_LB) == 0.0 &&
v.get(GRB_DoubleAttr_UB) == 1-0 &&
(vType == GRB_BINARY || vType == GRB_INTEGER) ) {
// Set scenario parameter to collect the objective value of the
// corresponding scenario
model.set(GRB_IntParam_ScenarioNumber, scenarios);
// Collect objective value and bound for the scenario
double scenarioObjVal = model.get(GRB_DoubleAttr_ScenNObjVal);
double scenarioObjBound = model.get(GRB_DoubleAttr_ScenNObjBound);
cout << "Objective sensitivity for variable "
<< v.get(GRB_StringAttr_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)
cout << "infeasible" << endl;
else
cout << "unknown (no solution available)" << endl;
} else {
// Scenario is feasible and a solution is available
cout << modelSense * (scenarioObjVal - origObjVal) << endl;
}
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
}
} catch (GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
} catch (...) {
cout << "Error during optimization" << endl;
}
delete[] vars;
delete[] origX;
return 0;
}
// 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);
}
}
}
// 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:
// java Sensitivity <model filename>
import com.gurobi.gurobi.*;
public class Sensitivity {
// Maximum number of scenarios to be considered
private static final int MAXSCENARIOS = 100;
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java Sensitivity filename");
System.exit(1);
}
try {
// Create environment
GRBEnv env = new GRBEnv();
// Read model
GRBModel model = new GRBModel(env, args[0]);
int scenarios;
if (model.get(GRB.IntAttr.IsMIP) == 0) {
System.out.println("Model is not a MIP");
System.exit(1);
}
// Solve model
model.optimize();
if (model.get(GRB.IntAttr.Status) != GRB.OPTIMAL) {
System.out.println("Optimization ended with status "
+ model.get(GRB.IntAttr.Status));
System.exit(1);
}
// Store the optimal solution
double origObjVal = model.get(GRB.DoubleAttr.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.get(GRB.CharAttr.VType);
if (v.get(GRB.DoubleAttr.LB) == 0 &&
v.get(GRB.DoubleAttr.UB) == 1 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) ) {
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
System.out.println("### construct multi-scenario model with "
+ scenarios + " scenarios");
// Set the number of scenarios in the model */
model.set(GRB.IntAttr.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.get(GRB.CharAttr.VType);
if (v.get(GRB.DoubleAttr.LB) == 0 &&
v.get(GRB.DoubleAttr.UB) == 1 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) &&
scenarios < MAXSCENARIOS ) {
// Set ScenarioNumber parameter to select the corresponding
// scenario for adjustments
model.set(GRB.IntParam.ScenarioNumber, scenarios);
// Set variable to 1-X, where X is its value in the optimal solution */
if (origX[i] < 0.5)
v.set(GRB.DoubleAttr.ScenNLB, 1.0);
else
v.set(GRB.DoubleAttr.ScenNUB, 0.0);
scenarios++;
} else {
// Add MIP start for all other variables using the optimal
// solution of the base model
v.set(GRB.DoubleAttr.Start, origX[i]);
}
}
// Solve multi-scenario model
model.optimize();
// In case we solved the scenario model to optimality capture the
// sensitivity information
if (model.get(GRB.IntAttr.Status) == GRB.OPTIMAL) {
// get the model sense (minimization or maximization)
int modelSense = model.get(GRB.IntAttr.ModelSense);
scenarios = 0;
for (int i = 0; i < vars.length; i++) {
GRBVar v = vars[i];
char vType = v.get(GRB.CharAttr.VType);
if (v.get(GRB.DoubleAttr.LB) == 0 &&
v.get(GRB.DoubleAttr.UB) == 1 &&
(vType == GRB.BINARY || vType == GRB.INTEGER) ) {
// Set scenario parameter to collect the objective value of the
// corresponding scenario
model.set(GRB.IntParam.ScenarioNumber, scenarios);
// Collect objective value and bound for the scenario
double scenarioObjVal = model.get(GRB.DoubleAttr.ScenNObjVal);
double scenarioObjBound = model.get(GRB.DoubleAttr.ScenNObjBound);
System.out.print("Objective sensitivity for variable "
+ v.get(GRB.StringAttr.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)
System.out.println("infeasible");
else
System.out.println("unknown (no solution available)");
} else {
// Scenario is feasible and a solution is available
System.out.println("" + modelSense * (scenarioObjVal - origObjVal));
}
scenarios++;
if (scenarios >= MAXSCENARIOS)
break;
}
}
}
// Dispose of model and environment
model.dispose();
env.dispose();
} catch (GRBException e) {
System.out.println("Error code: " + e.getErrorCode());
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
function sensitivity(filename)
% Copyright 2025, Gurobi Optimization, LLC
%
% A simple sensitivity analysis example which reads a MIP model
% from a file and solves it. Then each binary variable is set
% to 1-X, where X is its value in the optimal solution, and
% the impact on the objective function value is reported.
% Read model
fprintf('Reading model %s\n', filename);
model = gurobi_read(filename);
cols = size(model.A, 2);
ivars = find(model.vtype ~= 'C');
if length(ivars) <= 0
fprintf('All variables of the model are continuous, nothing to do\n');
return;
end
% Optimize
result = gurobi(model);
% Capture solution information
if result.status ~= 'OPTIMAL'
fprintf('Model status is %d, quit now\n', result.status);
end
origx = result.x;
origobjval = result.objval;
params.OutputFlag = 0;
% Iterate through unfixed binary variables in the model
for j = 1:cols
if model.vtype(j) ~= 'B' && model.vtype(j) ~= 'I'
continue;
end
if model.vtype(j) == 'I'
if model.lb(j) ~= 0.0 || model.ub(j) ~= 1.0
continue;
end
else
if model.lb(j) > 0.0 || model.ub(j) < 1.0
continue;
end
end
% Update MIP start for all variables
model.start = origx;
% Set variable to 1-X, where X is its value in optimal solution
if origx(j) < 0.5
model.start(j) = 1;
model.lb(j) = 1;
else
model.start(j) = 0;
model.ub(j) = 0;
end
% Optimize
result = gurobi(model, params);
% Display result
if ~strcmp(result.status, 'OPTIMAL')
gap = inf;
else
gap = result.objval - origobjval;
end
fprintf('Objective sensitivity for variable %s is %g\n', ...
model.varnames{j}, gap);
% Restore original bounds
model.lb(j) = 0;
model.ub(j) = 1;
end
#!/usr/bin/env python3.11
# 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.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(f"Optimization ended with status {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(f"### 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
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 modelSense * scenarioObjVal >= GRB.INFINITY:
# Check if the scenario is infeasible
if modelSense * scenarioObjBound >= 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:
# Scenario is feasible and a solution is available
print(
f"Objective sensitivity for variable {v.VarName} is {modelSense * (scenarioObjVal - origObjVal):g}"
)
scenarios += 1
if scenarios >= maxScenarios:
break
# Copyright 2025, Gurobi Optimization, LLC
#
# A simple sensitivity analysis example which reads a MIP model
# from a file and solves it. Then each binary variable is set
# to 1-X, where X is its value in the optimal solution, and
# the impact on the objective function value is reported.
library(Matrix)
library(gurobi)
args <- commandArgs(trailingOnly = TRUE)
if (length(args) < 1) {
stop('Usage: Rscript sensitivity.R filename\n')
}
# Read model
cat('Reading model',args[1],'...')
model <- gurobi_read(args[1])
cat('... done\n')
# Detect set of non-continous variables
numvars <- ncol(model$A)
intvars <- which(model$vtype != 'C')
numintvars <- length(intvars)
if (numintvars < 1) {
stop('All model\'s variables are continuous, nothing to do\n')
}
maxanalyze <- 10
# Optimize
result <- gurobi(model)
# Capture solution information
if (result$status != 'OPTIMAL') {
cat('Optimization finished with status', result$status, '\n')
stop('Stop now\n')
}
origx <- result$x
origobjval <- result$objval
# create lb and ub if they do not exists, and set them to default values
if (!('lb' %in% names(model))) {
model$lb <- numeric(numvars)
}
if (!('ub' %in% names(model))) {
# This line is not needed, as we must have ub defined
model$ub <- Inf + numeric(numvars)
}
# Disable output for subsequent solves
params <- list()
params$OutputFlag <- 0
# We limit the sensitivity analysis to a maximum number of variables
numanalyze <- 0
# Iterate through unfixed binary variables in the model
for (j in 1:numvars) {
if (model$vtype[j] != 'B' &&
model$vtype[j] != 'I' ) next
if (model$vtype[j] == 'I') {
if (model$lb[j] != 0.0) next
if (model$ub[j] != 1.0) next
} else {
if (model$lb[j] > 0.0) next
if (model$ub[j] < 1.0) next
}
# Update MIP start for all variables
model$start <- origx
# Set variable to 1-X, where X is its value in optimal solution
if (origx[j] < 0.5) {
model$start[j] <- 1
model$lb[j] <- 1
} else {
model$start[j] <- 0
model$ub[j] <- 0
}
# Optimize
result <- gurobi(model, params)
# Display result
varnames <- ''
if ('varnames' %in% names(model)) {
varnames <- model$varnames[j]
} else {
varnames <- sprintf('%s%d', model$vtype[j], j)
}
gap <- 0
if (result$status != 'OPTIMAL') {
gap <- Inf
} else {
gap <- result$objval - origobjval
}
cat('Objective sensitivity for variable', varnames, 'is', gap, '\n')
# Restore original bounds
model$lb[j] <- 0
model$ub[j] <- 1
numanalyze <- numanalyze + 1
# Stop when we reached the maximum number of sensitivity analysis steps
if (numanalyze >= maxanalyze) {
cat('Limit sensitivity analysis to the first', maxanalyze, 'variables\n')
break
}
}
# Clear space
rm(model, params, result, origx)
' 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>
Imports System
Imports Gurobi
Class sensitivity_vb
Shared Sub Main(args As String())
If args.Length < 1 Then
Console.Out.WriteLine("Usage: sensitivity_vb filename")
Return
End If
Try
' Maximum number of scenarios to be considered
Dim MAXSCENARIOS as Integer = 100
' Create environment
Dim env As New GRBEnv()
' Read model
Dim model As New GRBModel(env, args(0))
Dim scenarios As Integer
If model.IsMIP = 0 Then
Console.WriteLine("Model is not a MIP")
Return
End If
' Solve model
model.Optimize()
If model.Status <> GRB.Status.OPTIMAL Then
Console.WriteLine("Optimization ended with status " & _
model.Status)
Return
End If
' Store the optimal solution
Dim origObjVal As Double = model.ObjVal
Dim vars As GRBVar() = model.GetVars()
Dim origX As Double() = model.Get(GRB.DoubleAttr.X, vars)
scenarios = 0
' Count number of unfixed, binary variables in model. For each we
' create a scenario.
For i As Integer = 0 To vars.Length - 1
Dim v As GRBVar = vars(i)
Dim vType As Char = v.VType
If v.LB = 0.0 AndAlso _
v.UB = 1.0 AndAlso _
(vType = GRB.BINARY OrElse vType = GRB.INTEGER) Then
scenarios += 1
If scenarios >= MAXSCENARIOS Then
Exit For
End If
End If
Next
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 i As Integer = 0 To vars.Length - 1
Dim v As GRBVar = vars(i)
Dim vType As Char = v.VType
If v.LB = 0.0 AndAlso _
v.UB = 1.0 AndAlso _
(vType = GRB.BINARY OrElse vType = GRB.INTEGER) AndAlso _
scenarios < MAXSCENARIOS Then
' 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 Then
v.ScenNLB = 1.0
Else
v.ScenNUB = 0.0
End If
scenarios += 1
Else
' Add MIP start for all other variables using the optimal solution
' of the base model
v.Start = origX(i)
End If
Next
' 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 Then
Dim modelSense As Integer = model.ModelSense
scenarios = 0
For i As Integer = 0 To vars.Length - 1
Dim v As GRBVar = vars(i)
Dim vType As Char = v.VType
If v.LB = 0.0 AndAlso _
v.UB = 1.0 AndAlso _
(vType = GRB.BINARY OrElse vType = GRB.INTEGER) Then
' Set scenario parameter to collect the objective value of the
' corresponding scenario
model.Parameters.ScenarioNumber = scenarios
' Collect objective value and bound for the scenario
Dim scenarioObjVal As Double = model.ScenNObjVal
Dim scenarioObjBound As Double = 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 Then
' Check if the scenario is infeasible
If modelSense * scenarioObjBound >= GRB.INFINITY Then
Console.WriteLine("infeasible")
Else
Console.WriteLine("unknown (no solution available)")
End If
Else
' Scenario is feasible and a solution is available
Console.WriteLine(modelSense * (scenarioObjVal - origObjVal))
End If
scenarios += 1
If scenarios >= MAXSCENARIOS Then
Exit For
End If
End If
Next
End If
' Dispose of model and environment
model.Dispose()
env.Dispose()
Catch e As GRBException
Console.WriteLine("Error code: " + e.ErrorCode)
Console.WriteLine(e.Message)
Console.WriteLine(e.StackTrace)
End Try
End Sub
End Class