// Copyright 2010-2025 Google LLC // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. namespace Google.OrTools.ModelBuilder { using Google.OrTools.Util; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using Google.Protobuf.Collections; /// /// Model solver class /// public class Solver { class SolverException : Exception { public SolverException(String methodName, String msg) : base(methodName + ": " + msg) { } } /// /// Creates the solver with the supplied solver backend. /// /// the name of the solver backend public Solver(String solverName) { this.helper_ = new ModelSolverHelper(solverName); this.logCallback_ = null; } /// /// Solves given model, and returns the status of the response. /// /// the model to solve /// the status of the solve public SolveStatus Solve(Model model) { if (logCallback_ == null) { helper_.ClearLogCallback(); } else { helper_.SetLogCallbackFromDirectorClass(logCallback_); } helper_.Solve(model.Helper); if (!helper_.HasResponse()) { return SolveStatus.UNKNOWN_STATUS; } return helper_.Status(); } /// /// Enables or disables the underlying solver output. /// /// the Boolean that controls the output public void EnableOutput(bool enable) { helper_.EnableOutput(enable); } /** Sets the time limit for the solve in seconds. */ public void SetTimeLimitInSeconds(double limit) { helper_.SetTimeLimitInSeconds(limit); } /** Sets solver specific parameters as string. */ public void SetSolverSpecificParameters(String parameters) { helper_.SetSolverSpecificParameters(parameters); } /// /// Returns whether solver specified during the ctor was found and correctly installed. /// /// whether the solver is supported or not public bool SolverIsSupported() { return helper_.SolverIsSupported(); } /// /// Tries to interrupt the solve. Returns true if the feature is supported. /// /// whether the solver supports interruption public bool InterruptSolve() { return helper_.InterruptSolve(); } /// /// Returns true if solve() was called, and a response was returned. /// /// whether solve did happen public bool HasResponse() { return helper_.HasResponse(); } /// /// Returns true if solve() was called, and a solution was returned. /// /// whether a solution was found public bool HasSolution() { return helper_.HasSolution(); } /// /// The best objective value found during search. This raises a SolverException if no solution has been found, /// or if Solve() has not been called. /// public double ObjectiveValue { get { if (!helper_.HasSolution()) { throw new SolverException("Solver.ObjectiveValue", "Solve() was not called or no solution was found"); } return helper_.ObjectiveValue(); } } /// /// The best objective bound found during search. This raises a SolverException if no solution has been found, /// or if Solve() has not been called. /// public double BestObjectiveBound { get { if (!helper_.HasSolution()) { throw new SolverException("Solver.BestObjectiveBound", "Solve() was not called or no solution was found"); } return helper_.BestObjectiveBound(); } } /// /// The value of a variable in the current solution. This raises a SolverException if no solution has been /// found, or if Solve() has not been called. /// public double Value(Variable var) { if (!helper_.HasSolution()) { throw new SolverException("Solver.Value())", "Solve() was not called or no solution was found"); } return helper_.VariableValue(var.Index); } /// /// The reduced cost of a variable in the current solution. This raises a SolverException if no solution has /// been found, or if Solve() has not been called. /// public double ReducedCost(Variable var) { if (!helper_.HasSolution()) { throw new SolverException("Solver.ReducedCost())", "Solve() was not called or no solution was found"); } return helper_.ReducedCost(var.Index); } /// /// The dual value of a linear constraint in the current solution. This raises a SolverException if no solution /// has been found, or if Solve() has not been called. /// public double DualValue(LinearConstraint ct) { if (!helper_.HasSolution()) { throw new SolverException("Solver.DualValue())", "Solve() was not called or no solution was found"); } return helper_.DualValue(ct.Index); } /// /// The activity of a constraint in the current solution. This raises a SolverException if no solution has been /// found, or if Solve() has not been called. /// public double Activity(LinearConstraint ct) { if (!helper_.HasSolution()) { throw new SolverException("Solver.Activity())", "Solve() was not called or no solution was found"); } return helper_.Activity(ct.Index); } /// /// Sets the log callback for the solver. /// public MbLogCallback LogCallback { get { return logCallback_; } set { logCallback_ = value; } } /// /// Returns the elapsed time since the creation of the solver. /// public double WallTime { get { return helper_.WallTime(); } } /// /// Returns the user time since the creation of the solver. /// public double UserTime { get { return helper_.UserTime(); } } private ModelSolverHelper helper_; private MbLogCallback logCallback_; } } // namespace Google.OrTools.ModelBuilder