Source code for pyomo.contrib.alternative_solutions.solnpool

#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright (c) 2008-2024
#  National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________

import logging

logger = logging.getLogger(__name__)

from pyomo.common.dependencies import attempt_import
from pyomo.common.errors import ApplicationError

import pyomo.environ as pe
from pyomo.contrib import appsi
import pyomo.contrib.alternative_solutions.aos_utils as aos_utils
from pyomo.contrib.alternative_solutions import Solution


[docs] def gurobi_generate_solutions( model, *, num_solutions=10, rel_opt_gap=None, abs_opt_gap=None, solver_options={}, tee=False, ): """ Finds alternative optimal solutions for discrete variables using Gurobi's built-in Solution Pool capability. See the Gurobi Solution Pool documentation for additional details. Parameters ---------- model : ConcreteModel A concrete Pyomo model. num_solutions : int The maximum number of solutions to generate. This parameter maps to the PoolSolutions parameter in Gurobi. rel_opt_gap : non-negative float or None The relative optimality gap for allowable alternative solutions. None implies that there is no limit on the relative optimality gap (i.e. that any feasible solution can be considered by Gurobi). This parameter maps to the PoolGap parameter in Gurobi. abs_opt_gap : non-negative float or None The absolute optimality gap for allowable alternative solutions. None implies that there is no limit on the absolute optimality gap (i.e. that any feasible solution can be considered by Gurobi). This parameter maps to the PoolGapAbs parameter in Gurobi. solver_options : dict Solver option-value pairs to be passed to the Gurobi solver. tee : boolean Boolean indicating that the solver output should be displayed. Returns ------- solutions A list of Solution objects. [Solution] """ # # Setup gurobi # opt = appsi.solvers.Gurobi() if not opt.available(): raise ApplicationError("Solver (gurobi) not available") opt.config.stream_solver = tee opt.config.load_solution = False opt.gurobi_options["PoolSolutions"] = num_solutions opt.gurobi_options["PoolSearchMode"] = 2 if rel_opt_gap is not None: opt.gurobi_options["PoolGap"] = rel_opt_gap if abs_opt_gap is not None: opt.gurobi_options["PoolGapAbs"] = abs_opt_gap for parameter, value in solver_options.items(): opt.gurobi_options[parameter] = value # # Run gurobi # results = opt.solve(model) condition = results.termination_condition if not (condition == appsi.base.TerminationCondition.optimal): raise ApplicationError( "Model cannot be solved, " "TerminationCondition = {}" ).format(condition.value) # # Collect solutions # solution_count = opt.get_model_attr("SolCount") variables = aos_utils.get_model_variables(model, include_fixed=True) solutions = [] for i in range(solution_count): # # Load the i-th solution into the model # results.solution_loader.load_vars(solution_number=i) # # Pull the solution from the model into a Solution object, # and append to our list of solutions # solutions.append(Solution(model, variables)) return solutions