Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# sensitivity.py

    #!/usr/bin/env python3

    # 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

Help and Feedback

Press `/` or click to search this documentation | Gurobi website | Gurobi community forum
Go to other Gurobi documentation | Gurobi download | Contact support