Bagian ini menjelaskan pemecah masalah pemrograman batasan asli, yang telah diganti dengan pemecah masalah CP-SAT yang unggul.
Bagian berikut menjelaskan cara menyelesaikan contoh yang dijelaskan di bagian CP-SAT, kali ini menggunakan pemecah masalah CP asli. Jika Anda bersikeras menggunakan pemecah masalah CP asli, Anda dapat melihat referensi API. Perhatikan bahwa pemecah masalah CP asli adalah dasar dari library perutean, dan API-nya mungkin diperlukan untuk menyesuaikan model perutean.
Mengimpor library
Kode berikut mengimpor library yang diperlukan.
Python
from ortools.constraint_solver import pywrapcp
C++
#include <ostream> #include <string> #include "ortools/constraint_solver/constraint_solver.h"
Java
import com.google.ortools.Loader; import com.google.ortools.constraintsolver.DecisionBuilder; import com.google.ortools.constraintsolver.IntVar; import com.google.ortools.constraintsolver.Solver; import java.util.logging.Logger;
C#
using System; using Google.OrTools.ConstraintSolver;
Mendeklarasikan pemecah masalah
Kode berikut mendeklarasikan resolver.
Python
solver = pywrapcp.Solver("CPSimple")
C++
Solver solver("CpSimple");
Java
Solver solver = new Solver("CpSimple");
C#
Solver solver = new Solver("CpSimple");
Membuat variabel
Kode berikut membuat variabel untuk masalah tersebut.
Pemecah masalah membuat tiga variabel, x, y, dan z, yang masing-masing dapat mengambil nilai 0, 1, atau 2.
Python
num_vals = 3 x = solver.IntVar(0, num_vals - 1, "x") y = solver.IntVar(0, num_vals - 1, "y") z = solver.IntVar(0, num_vals - 1, "z")
C++
const int64_t num_vals = 3; IntVar* const x = solver.MakeIntVar(0, num_vals - 1, "x"); IntVar* const y = solver.MakeIntVar(0, num_vals - 1, "y"); IntVar* const z = solver.MakeIntVar(0, num_vals - 1, "z");
Java
final long numVals = 3; final IntVar x = solver.makeIntVar(0, numVals - 1, "x"); final IntVar y = solver.makeIntVar(0, numVals - 1, "y"); final IntVar z = solver.makeIntVar(0, numVals - 1, "z");
C#
const long numVals = 3; IntVar x = solver.MakeIntVar(0, numVals - 1, "x"); IntVar y = solver.MakeIntVar(0, numVals - 1, "y"); IntVar z = solver.MakeIntVar(0, numVals - 1, "z");
Membuat batasan
Kode berikut membuat batasan x ≠ y
.
Python
solver.Add(x != y) print("Number of constraints: ", solver.Constraints())
C++
solver.AddConstraint(solver.MakeAllDifferent({x, y})); LOG(INFO) << "Number of constraints: " << std::to_string(solver.constraints());
Java
solver.addConstraint(solver.makeAllDifferent(new IntVar[] {x, y})); logger.info("Number of constraints: " + solver.constraints());
C#
solver.Add(solver.MakeAllDifferent(new IntVar[] { x, y })); Console.WriteLine($"Number of constraints: {solver.Constraints()}");
Panggil pemecah masalah
Kode berikut memanggil pemecah.
Pembuat keputusan adalah input utama untuk pemecah masalah CP asli. Isinya berisi hal berikut:
vars
— Array yang berisi variabel untuk masalah.- Aturan untuk memilih variabel berikutnya yang akan ditetapkan nilai.
- Aturan untuk memilih nilai berikutnya yang akan ditetapkan ke variabel tersebut.
Lihat Pembuat keputusan untuk mengetahui detailnya.
Python
decision_builder = solver.Phase( [x, y, z], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE )
C++
DecisionBuilder* const db = solver.MakePhase( {x, y, z}, Solver::CHOOSE_FIRST_UNBOUND, Solver::ASSIGN_MIN_VALUE);
Java
final DecisionBuilder db = solver.makePhase( new IntVar[] {x, y, z}, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
C#
DecisionBuilder db = solver.MakePhase(new IntVar[] { x, y, z }, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
Cetak solusi
Kode untuk printer solusi, yang menampilkan setiap solusi sebagai pemecah menemukannya, ditunjukkan di bagian berikut.
Karena ada lebih dari satu solusi untuk masalah kita, kita dapat melakukan iterasi solusi dengan loop while solver.NextSolution()
. (Perhatikan bahwa cara kerjanya
berbeda dengan printer solusi untuk pemecah masalah CP-SAT).
Python
count = 0 solver.NewSearch(decision_builder) while solver.NextSolution(): count += 1 solution = f"Solution {count}:\n" for var in [x, y, z]: solution += f" {var.Name()} = {var.Value()}" print(solution) solver.EndSearch() print(f"Number of solutions found: {count}")
C++
int count = 0; solver.NewSearch(db); while (solver.NextSolution()) { ++count; LOG(INFO) << "Solution " << count << ":" << std::endl << " x=" << x->Value() << " y=" << y->Value() << " z=" << z->Value(); } solver.EndSearch(); LOG(INFO) << "Number of solutions found: " << solver.solutions();
Java
int count = 0; solver.newSearch(db); while (solver.nextSolution()) { ++count; logger.info( String.format("Solution: %d\n x=%d y=%d z=%d", count, x.value(), y.value(), z.value())); } solver.endSearch(); logger.info("Number of solutions found: " + solver.solutions());
C#
int count = 0; solver.NewSearch(db); while (solver.NextSolution()) { ++count; Console.WriteLine($"Solution: {count}\n x={x.Value()} y={y.Value()} z={z.Value()}"); } solver.EndSearch(); Console.WriteLine($"Number of solutions found: {solver.Solutions()}");
Hasil yang ditampilkan oleh pemecah masalah
Berikut adalah 18 solusi yang ditemukan oleh pemecah masalah:
Number of constraints: 1 Solution 1: x = 0 y = 1 z = 0 Solution 2: x = 0 y = 1 z = 1 Solution 3: x = 0 y = 1 z = 2 Solution 4: x = 0 y = 2 z = 0 Solution 5: x = 0 y = 2 z = 1 Solution 6: x = 0 y = 2 z = 2 Solution 7: x = 1 y = 0 z = 0 Solution 8: x = 1 y = 0 z = 1 Solution 9: x = 1 y = 0 z = 2 Solution 10: x = 1 y = 2 z = 0 Solution 11: x = 1 y = 2 z = 1 Solution 12: x = 1 y = 2 z = 2 Solution 13: x = 2 y = 0 z = 0 Solution 14: x = 2 y = 0 z = 1 Solution 15: x = 2 y = 0 z = 2 Solution 16: x = 2 y = 1 z = 0 Solution 17: x = 2 y = 1 z = 1 Solution 18: x = 2 y = 1 z = 2 Number of solutions found: 18 Advanced usage: Problem solved in 2 ms Memory usage: 13918208 bytes
Selesaikan program
Berikut adalah program lengkap sebagai contoh menggunakan pemecah soal CP yang asli.
Python
"""Simple Constraint optimization example.""" from ortools.constraint_solver import pywrapcp def main(): """Entry point of the program.""" # Instantiate the solver. solver = pywrapcp.Solver("CPSimple") # Create the variables. num_vals = 3 x = solver.IntVar(0, num_vals - 1, "x") y = solver.IntVar(0, num_vals - 1, "y") z = solver.IntVar(0, num_vals - 1, "z") # Constraint 0: x != y. solver.Add(x != y) print("Number of constraints: ", solver.Constraints()) # Solve the problem. decision_builder = solver.Phase( [x, y, z], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE ) # Print solution on console. count = 0 solver.NewSearch(decision_builder) while solver.NextSolution(): count += 1 solution = f"Solution {count}:\n" for var in [x, y, z]: solution += f" {var.Name()} = {var.Value()}" print(solution) solver.EndSearch() print(f"Number of solutions found: {count}") print("Advanced usage:") print(f"Problem solved in {solver.WallTime()}ms") print(f"Memory usage: {pywrapcp.Solver.MemoryUsage()}bytes") if __name__ == "__main__": main()
C++
#include <ostream> #include <string> #include "ortools/constraint_solver/constraint_solver.h" namespace operations_research { void SimpleCpProgram() { // Instantiate the solver. Solver solver("CpSimple"); // Create the variables. const int64_t num_vals = 3; IntVar* const x = solver.MakeIntVar(0, num_vals - 1, "x"); IntVar* const y = solver.MakeIntVar(0, num_vals - 1, "y"); IntVar* const z = solver.MakeIntVar(0, num_vals - 1, "z"); // Constraint 0: x != y.. solver.AddConstraint(solver.MakeAllDifferent({x, y})); LOG(INFO) << "Number of constraints: " << std::to_string(solver.constraints()); // Solve the problem. DecisionBuilder* const db = solver.MakePhase( {x, y, z}, Solver::CHOOSE_FIRST_UNBOUND, Solver::ASSIGN_MIN_VALUE); // Print solution on console. int count = 0; solver.NewSearch(db); while (solver.NextSolution()) { ++count; LOG(INFO) << "Solution " << count << ":" << std::endl << " x=" << x->Value() << " y=" << y->Value() << " z=" << z->Value(); } solver.EndSearch(); LOG(INFO) << "Number of solutions found: " << solver.solutions(); LOG(INFO) << "Advanced usage:" << std::endl << "Problem solved in " << std::to_string(solver.wall_time()) << "ms" << std::endl << "Memory usage: " << std::to_string(Solver::MemoryUsage()) << "bytes"; } } // namespace operations_research int main(int /*argc*/, char* /*argv*/[]) { operations_research::SimpleCpProgram(); return EXIT_SUCCESS; }
Java
package com.google.ortools.constraintsolver.samples; import com.google.ortools.Loader; import com.google.ortools.constraintsolver.DecisionBuilder; import com.google.ortools.constraintsolver.IntVar; import com.google.ortools.constraintsolver.Solver; import java.util.logging.Logger; /** Simple CP Program.*/ public class SimpleCpProgram { private SimpleCpProgram() {} private static final Logger logger = Logger.getLogger(SimpleCpProgram.class.getName()); public static void main(String[] args) throws Exception { Loader.loadNativeLibraries(); // Instantiate the solver. Solver solver = new Solver("CpSimple"); // Create the variables. final long numVals = 3; final IntVar x = solver.makeIntVar(0, numVals - 1, "x"); final IntVar y = solver.makeIntVar(0, numVals - 1, "y"); final IntVar z = solver.makeIntVar(0, numVals - 1, "z"); // Constraint 0: x != y.. solver.addConstraint(solver.makeAllDifferent(new IntVar[] {x, y})); logger.info("Number of constraints: " + solver.constraints()); // Solve the problem. final DecisionBuilder db = solver.makePhase( new IntVar[] {x, y, z}, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // Print solution on console. int count = 0; solver.newSearch(db); while (solver.nextSolution()) { ++count; logger.info( String.format("Solution: %d\n x=%d y=%d z=%d", count, x.value(), y.value(), z.value())); } solver.endSearch(); logger.info("Number of solutions found: " + solver.solutions()); logger.info(String.format("Advanced usage:\nProblem solved in %d ms\nMemory usage: %d bytes", solver.wallTime(), Solver.memoryUsage())); } }
C#
using System; using Google.OrTools.ConstraintSolver; /// <summary> /// This is a simple CP program. /// </summary> public class SimpleCpProgram { public static void Main(String[] args) { // Instantiate the solver. Solver solver = new Solver("CpSimple"); // Create the variables. const long numVals = 3; IntVar x = solver.MakeIntVar(0, numVals - 1, "x"); IntVar y = solver.MakeIntVar(0, numVals - 1, "y"); IntVar z = solver.MakeIntVar(0, numVals - 1, "z"); // Constraint 0: x != y.. solver.Add(solver.MakeAllDifferent(new IntVar[] { x, y })); Console.WriteLine($"Number of constraints: {solver.Constraints()}"); // Solve the problem. DecisionBuilder db = solver.MakePhase(new IntVar[] { x, y, z }, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // Print solution on console. int count = 0; solver.NewSearch(db); while (solver.NextSolution()) { ++count; Console.WriteLine($"Solution: {count}\n x={x.Value()} y={y.Value()} z={z.Value()}"); } solver.EndSearch(); Console.WriteLine($"Number of solutions found: {solver.Solutions()}"); Console.WriteLine("Advanced usage:"); Console.WriteLine($"Problem solved in {solver.WallTime()}ms"); Console.WriteLine($"Memory usage: {Solver.MemoryUsage()}bytes"); } }
Pembuat keputusan
Input utama ke pemecah masalah CP asli adalah builder keputusan yang berisi variabel untuk masalah dan menetapkan opsi untuk pemecah masalah.
Contoh kode di bagian sebelumnya membuat pembuat keputusan
menggunakan metode Phase
(sesuai dengan metode C++
MakePhase
.
Istilah Fase mengacu pada fase penelusuran. Dalam contoh sederhana ini, hanya ada satu fase, tetapi untuk masalah yang lebih kompleks, pembuat keputusan dapat memiliki lebih dari satu fase, sehingga pemecah masalah dapat menggunakan strategi penelusuran yang berbeda dari satu fase ke fase berikutnya.
Metode Phase
memiliki tiga parameter input:
vars
— Array yang berisi variabel untuk masalah, yang dalam hal ini adalah[x, y, z]
.IntVarStrategy
— Aturan untuk memilih variabel tak terikat berikutnya guna menetapkan nilai. Di sini, kode menggunakanCHOOSE_FIRST_UNBOUND
default, yang berarti bahwa pada setiap langkah, pemecah masalah akan memilih variabel tidak terikat pertama sesuai urutan kemunculannya dalam array variabel yang diteruskan ke metodePhase
.IntValueStrategy
— Aturan untuk memilih nilai berikutnya yang akan ditetapkan ke variabel. Di sini, kode menggunakanASSIGN_MIN_VALUE
default, yang memilih nilai terkecil yang belum dicoba untuk variabel tersebut. Ini menetapkan nilai-nilai dalam urutan meningkat. Opsi lainnya adalahASSIGN_MAX_VALUE
, dengan pemecah masalah akan menetapkan nilai dalam urutan menurun.