In den folgenden Abschnitten wird anhand eines Beispiels für ein LP-Problem gezeigt, wie Sie es lösen können. Hier ist das Problem:
Die 3x + 4y
-Maximierung unterliegt den folgenden Einschränkungen:
x + 2y
≤ 143x - y
≥ 0x - y
≤ 2
Sowohl die Zielfunktion (3x + 4y
) als auch die Einschränkungen werden durch lineare Ausdrücke bestimmt, was dies zu einem linearen Problem macht.
Die Einschränkungen definieren den zulässigen Bereich. Dies ist das unten gezeigte Dreieck, einschließlich des Innenbereichs.
Grundlegende Schritte zur Lösung eines LP-Problems
Um ein LP-Problem zu lösen, sollte Ihr Programm die folgenden Schritte umfassen:
- Importieren Sie den Wrapper für den Linear Solver
- den LP-Rechner zu deklarieren,
- die Variablen definieren,
- die Einschränkungen zu definieren,
- das Ziel zu definieren,
- Rufen Sie den LP Solver auf.
- Lösung anzeigen
Lösung mit MPsolver
Im folgenden Abschnitt wird ein Programm vorgestellt, das das Problem mithilfe des MPSolver-Wrappers und eines LP-Lösers löst.
Hinweis: Um das folgende Programm auszuführen, müssen Sie OR-Tools installieren.
Der primäre lineare Optimierungslöser von OR-Tools ist Glop, der interne Lösungsrechner für lineare Programmierung von Google. Es ist schnell, speichereffizient und numerisch stabil.
Lineare Solver-Wrapper importieren
Importieren (oder schließen) Sie den Linear Solver-Wrapper der OR-Tools, eine Schnittstelle für MIP-Resolver und Linear Solver, wie unten dargestellt.
Python
from ortools.linear_solver import pywraplp
C++
#include <iostream> #include <memory> #include "ortools/linear_solver/linear_solver.h"
Java
import com.google.ortools.Loader; import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable;
C#
using System; using Google.OrTools.LinearSolver;
LP-Belöser deklarieren
MPsolver
ist ein Wrapper für mehrere verschiedene Solver, einschließlich Glop. Mit dem folgenden Code wird der GLOP-Belöser deklariert.
Python
solver = pywraplp.Solver.CreateSolver("GLOP") if not solver: return
C++
std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("SCIP")); if (!solver) { LOG(WARNING) << "SCIP solver unavailable."; return; }
Java
MPSolver solver = MPSolver.createSolver("GLOP");
C#
Solver solver = Solver.CreateSolver("GLOP"); if (solver is null) { return; }
Hinweis: Ersetzen Sie PDLP
durch GLOP
, um einen alternativen LP-Resolver zu verwenden. Weitere Informationen zur Auswahl von Solvern finden Sie unter Erweiterte LP-Lösung. Informationen zur Installation von Solvern von Drittanbietern finden Sie in der Installationsanleitung.
Variablen erstellen
Erstellen Sie zuerst die Variablen x und y, deren Werte im Bereich von 0 bis unendlich liegen.
Python
x = solver.NumVar(0, solver.infinity(), "x") y = solver.NumVar(0, solver.infinity(), "y") print("Number of variables =", solver.NumVariables())
C++
const double infinity = solver->infinity(); // x and y are non-negative variables. MPVariable* const x = solver->MakeNumVar(0.0, infinity, "x"); MPVariable* const y = solver->MakeNumVar(0.0, infinity, "y"); LOG(INFO) << "Number of variables = " << solver->NumVariables();
Java
double infinity = java.lang.Double.POSITIVE_INFINITY; // x and y are continuous non-negative variables. MPVariable x = solver.makeNumVar(0.0, infinity, "x"); MPVariable y = solver.makeNumVar(0.0, infinity, "y"); System.out.println("Number of variables = " + solver.numVariables());
C#
Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x"); Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y"); Console.WriteLine("Number of variables = " + solver.NumVariables());
Einschränkungen definieren
Definieren Sie als Nächstes die Einschränkungen für die Variablen. Geben Sie jeder Einschränkung einen eindeutigen Namen (z. B. constraint0
) und definieren Sie dann die Koeffizienten für die Einschränkung.
Python
# Constraint 0: x + 2y <= 14. solver.Add(x + 2 * y <= 14.0) # Constraint 1: 3x - y >= 0. solver.Add(3 * x - y >= 0.0) # Constraint 2: x - y <= 2. solver.Add(x - y <= 2.0) print("Number of constraints =", solver.NumConstraints())
C++
// x + 2*y <= 14. MPConstraint* const c0 = solver->MakeRowConstraint(-infinity, 14.0); c0->SetCoefficient(x, 1); c0->SetCoefficient(y, 2); // 3*x - y >= 0. MPConstraint* const c1 = solver->MakeRowConstraint(0.0, infinity); c1->SetCoefficient(x, 3); c1->SetCoefficient(y, -1); // x - y <= 2. MPConstraint* const c2 = solver->MakeRowConstraint(-infinity, 2.0); c2->SetCoefficient(x, 1); c2->SetCoefficient(y, -1); LOG(INFO) << "Number of constraints = " << solver->NumConstraints();
Java
// x + 2*y <= 14. MPConstraint c0 = solver.makeConstraint(-infinity, 14.0, "c0"); c0.setCoefficient(x, 1); c0.setCoefficient(y, 2); // 3*x - y >= 0. MPConstraint c1 = solver.makeConstraint(0.0, infinity, "c1"); c1.setCoefficient(x, 3); c1.setCoefficient(y, -1); // x - y <= 2. MPConstraint c2 = solver.makeConstraint(-infinity, 2.0, "c2"); c2.setCoefficient(x, 1); c2.setCoefficient(y, -1); System.out.println("Number of constraints = " + solver.numConstraints());
C#
// x + 2y <= 14. solver.Add(x + 2 * y <= 14.0); // 3x - y >= 0. solver.Add(3 * x - y >= 0.0); // x - y <= 2. solver.Add(x - y <= 2.0); Console.WriteLine("Number of constraints = " + solver.NumConstraints());
Die Zielfunktion definieren
Der folgende Code definiert die Zielfunktion 3x + 4y
und gibt an, dass es sich um ein Maximierungsproblem handelt.
Python
# Objective function: 3x + 4y. solver.Maximize(3 * x + 4 * y)
C++
// Objective function: 3x + 4y. MPObjective* const objective = solver->MutableObjective(); objective->SetCoefficient(x, 3); objective->SetCoefficient(y, 4); objective->SetMaximization();
Java
// Maximize 3 * x + 4 * y. MPObjective objective = solver.objective(); objective.setCoefficient(x, 3); objective.setCoefficient(y, 4); objective.setMaximization();
C#
// Objective function: 3x + 4y. solver.Maximize(3 * x + 4 * y);
Den Solver aufrufen
Der folgende Code ruft den Solver auf.
Python
print(f"Solving with {solver.SolverVersion()}") status = solver.Solve()
C++
const MPSolver::ResultStatus result_status = solver->Solve(); // Check that the problem has an optimal solution. if (result_status != MPSolver::OPTIMAL) { LOG(FATAL) << "The problem does not have an optimal solution!"; }
Java
final MPSolver.ResultStatus resultStatus = solver.solve();
C#
Solver.ResultStatus resultStatus = solver.Solve();
Lösung anzeigen
Der folgende Code zeigt die Lösung an.
Python
if status == pywraplp.Solver.OPTIMAL: print("Solution:") print(f"Objective value = {solver.Objective().Value():0.1f}") print(f"x = {x.solution_value():0.1f}") print(f"y = {y.solution_value():0.1f}") else: print("The problem does not have an optimal solution.")
C++
LOG(INFO) << "Solution:"; LOG(INFO) << "Optimal objective value = " << objective->Value(); LOG(INFO) << x->name() << " = " << x->solution_value(); LOG(INFO) << y->name() << " = " << y->solution_value();
Java
if (resultStatus == MPSolver.ResultStatus.OPTIMAL) { System.out.println("Solution:"); System.out.println("Objective value = " + objective.value()); System.out.println("x = " + x.solutionValue()); System.out.println("y = " + y.solutionValue()); } else { System.err.println("The problem does not have an optimal solution!"); }
C#
// Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } Console.WriteLine("Solution:"); Console.WriteLine("Objective value = " + solver.Objective().Value()); Console.WriteLine("x = " + x.SolutionValue()); Console.WriteLine("y = " + y.SolutionValue());
Alle Programme
Die vollständigen Programme sind unten aufgeführt.
Python
from ortools.linear_solver import pywraplp def LinearProgrammingExample(): """Linear programming sample.""" # Instantiate a Glop solver, naming it LinearExample. solver = pywraplp.Solver.CreateSolver("GLOP") if not solver: return # Create the two variables and let them take on any non-negative value. x = solver.NumVar(0, solver.infinity(), "x") y = solver.NumVar(0, solver.infinity(), "y") print("Number of variables =", solver.NumVariables()) # Constraint 0: x + 2y <= 14. solver.Add(x + 2 * y <= 14.0) # Constraint 1: 3x - y >= 0. solver.Add(3 * x - y >= 0.0) # Constraint 2: x - y <= 2. solver.Add(x - y <= 2.0) print("Number of constraints =", solver.NumConstraints()) # Objective function: 3x + 4y. solver.Maximize(3 * x + 4 * y) # Solve the system. print(f"Solving with {solver.SolverVersion()}") status = solver.Solve() if status == pywraplp.Solver.OPTIMAL: print("Solution:") print(f"Objective value = {solver.Objective().Value():0.1f}") print(f"x = {x.solution_value():0.1f}") print(f"y = {y.solution_value():0.1f}") else: print("The problem does not have an optimal solution.") print("\nAdvanced usage:") print(f"Problem solved in {solver.wall_time():d} milliseconds") print(f"Problem solved in {solver.iterations():d} iterations") LinearProgrammingExample()
C++
#include <iostream> #include <memory> #include "ortools/linear_solver/linear_solver.h" namespace operations_research { void LinearProgrammingExample() { std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("SCIP")); if (!solver) { LOG(WARNING) << "SCIP solver unavailable."; return; } const double infinity = solver->infinity(); // x and y are non-negative variables. MPVariable* const x = solver->MakeNumVar(0.0, infinity, "x"); MPVariable* const y = solver->MakeNumVar(0.0, infinity, "y"); LOG(INFO) << "Number of variables = " << solver->NumVariables(); // x + 2*y <= 14. MPConstraint* const c0 = solver->MakeRowConstraint(-infinity, 14.0); c0->SetCoefficient(x, 1); c0->SetCoefficient(y, 2); // 3*x - y >= 0. MPConstraint* const c1 = solver->MakeRowConstraint(0.0, infinity); c1->SetCoefficient(x, 3); c1->SetCoefficient(y, -1); // x - y <= 2. MPConstraint* const c2 = solver->MakeRowConstraint(-infinity, 2.0); c2->SetCoefficient(x, 1); c2->SetCoefficient(y, -1); LOG(INFO) << "Number of constraints = " << solver->NumConstraints(); // Objective function: 3x + 4y. MPObjective* const objective = solver->MutableObjective(); objective->SetCoefficient(x, 3); objective->SetCoefficient(y, 4); objective->SetMaximization(); const MPSolver::ResultStatus result_status = solver->Solve(); // Check that the problem has an optimal solution. if (result_status != MPSolver::OPTIMAL) { LOG(FATAL) << "The problem does not have an optimal solution!"; } LOG(INFO) << "Solution:"; LOG(INFO) << "Optimal objective value = " << objective->Value(); LOG(INFO) << x->name() << " = " << x->solution_value(); LOG(INFO) << y->name() << " = " << y->solution_value(); } } // namespace operations_research int main(int argc, char** argv) { operations_research::LinearProgrammingExample(); return EXIT_SUCCESS; }
Java
package com.google.ortools.linearsolver.samples; import com.google.ortools.Loader; import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; /** Simple linear programming example. */ public final class LinearProgrammingExample { public static void main(String[] args) { Loader.loadNativeLibraries(); MPSolver solver = MPSolver.createSolver("GLOP"); double infinity = java.lang.Double.POSITIVE_INFINITY; // x and y are continuous non-negative variables. MPVariable x = solver.makeNumVar(0.0, infinity, "x"); MPVariable y = solver.makeNumVar(0.0, infinity, "y"); System.out.println("Number of variables = " + solver.numVariables()); // x + 2*y <= 14. MPConstraint c0 = solver.makeConstraint(-infinity, 14.0, "c0"); c0.setCoefficient(x, 1); c0.setCoefficient(y, 2); // 3*x - y >= 0. MPConstraint c1 = solver.makeConstraint(0.0, infinity, "c1"); c1.setCoefficient(x, 3); c1.setCoefficient(y, -1); // x - y <= 2. MPConstraint c2 = solver.makeConstraint(-infinity, 2.0, "c2"); c2.setCoefficient(x, 1); c2.setCoefficient(y, -1); System.out.println("Number of constraints = " + solver.numConstraints()); // Maximize 3 * x + 4 * y. MPObjective objective = solver.objective(); objective.setCoefficient(x, 3); objective.setCoefficient(y, 4); objective.setMaximization(); final MPSolver.ResultStatus resultStatus = solver.solve(); if (resultStatus == MPSolver.ResultStatus.OPTIMAL) { System.out.println("Solution:"); System.out.println("Objective value = " + objective.value()); System.out.println("x = " + x.solutionValue()); System.out.println("y = " + y.solutionValue()); } else { System.err.println("The problem does not have an optimal solution!"); } System.out.println("\nAdvanced usage:"); System.out.println("Problem solved in " + solver.wallTime() + " milliseconds"); System.out.println("Problem solved in " + solver.iterations() + " iterations"); } private LinearProgrammingExample() {} }
C#
using System; using Google.OrTools.LinearSolver; public class LinearProgrammingExample { static void Main() { Solver solver = Solver.CreateSolver("GLOP"); if (solver is null) { return; } // x and y are continuous non-negative variables. Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x"); Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y"); Console.WriteLine("Number of variables = " + solver.NumVariables()); // x + 2y <= 14. solver.Add(x + 2 * y <= 14.0); // 3x - y >= 0. solver.Add(3 * x - y >= 0.0); // x - y <= 2. solver.Add(x - y <= 2.0); Console.WriteLine("Number of constraints = " + solver.NumConstraints()); // Objective function: 3x + 4y. solver.Maximize(3 * x + 4 * y); Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } Console.WriteLine("Solution:"); Console.WriteLine("Objective value = " + solver.Objective().Value()); Console.WriteLine("x = " + x.SolutionValue()); Console.WriteLine("y = " + y.SolutionValue()); Console.WriteLine("\nAdvanced usage:"); Console.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds"); Console.WriteLine("Problem solved in " + solver.Iterations() + " iterations"); } }
Optimale Lösung
Das Programm gibt die optimale Lösung für das Problem zurück, wie unten dargestellt.
Number of variables = 2
Number of constraints = 3
Solution:
x = 6.0
y = 4.0
Optimal objective value = 34.0
Hier ist ein Diagramm, das die Lösung zeigt:
Die gestrichelte grüne Linie wird definiert, indem die Zielfunktion auf den optimalen Wert 34 gesetzt wird. Jede Gerade, deren Gleichung die Form 3x + 4y = c
hat, verläuft parallel zur gestrichelten Linie und 34 ist der größte Wert von c, bei dem die Linie den zulässigen Bereich überschneidet.
Weitere Informationen zum Lösen linearer Optimierungsprobleme finden Sie unter Erweiterte LP-Lösungen.