Google Optimization Tools(OR-Tools)是一款專門快速而便攜地解決組合優化問題的套件。它包含了:
- 約束編程求解器。
- 簡單而統一的接口,用於多種線性規划和混合整數規划求解,包括 CBC、CLP、GLOP、GLPK、Gurobi、CPLEX 和SCIP。
- 圖算法 (最短路徑、最小成本、最大流量、線性求和分配)。
- 經典旅行推銷員問題和車輛路徑問題的算法。
- 經典裝箱和背包算法。
Google使用C++開發了OR-Tools庫,但支持Python,C#,或Java語言調用。
安裝Google OR-Tools
Google OR-Tools的源碼在[Github] google/or-tools。其它開發環境下的安裝如下。
Linux or Mac下安裝
1. 確認使用了Python 2.7+,3.5+版本,以及pip 9.0.1+版本。
2. Mac OSX系統需要安裝命令行工具Xcode,在Terminal中執行xcode-select --install。
Linux系統需要安裝g++,在Terminal中執行sudo apt-get install g++ make。
如果使用C#請確認安裝了Mono 4.2.0+的64位版本。
3. 在Terminal中執行pip install --upgrade ortools直接安裝Python版本的OR-Tools包。C++/Java/C#版本的鏈接為:Mac, Ubuntu 17.04, Ubuntu 16.04, Ubuntu 14.04, CentOS 7, Debian 9 ,下載到指定目錄后執行make all。
Windows下安裝
Python版本的包的安裝和Linux一樣,可自行選用合適的開發工具。若是使用C++、C#,推薦使用64位版本的Windows10操作系統,並且使用Microsoft Visual Studio 2015 或者 2017作為開發工具,相應的庫文件下載地址為: Visual Studio 2017 the Visual Studio 2015。
- C++使用lib/ortools.lib, 並且將or‑tools/include添加到項目引用。
- Java使用jar命令調用lib/com.google.ortools.lib的方式,並且將 ‑Djava.library.path=PATH_TO_or‑tools/lib添加到命令行。
- C#添加bin/Google.OrTools.dll到項目依賴,或者使用NuGet搜索Google.OrTools進行安裝。
Demo
以下是幾種支持語言的demo,運行一下驗證是否安裝正確。
C++ 代碼
#include "ortools/linear_solver/linear_solver.h" #include "ortools/linear_solver/linear_solver.pb.h" namespace operations_research { void RunTest( MPSolver::OptimizationProblemType optimization_problem_type) { MPSolver solver("Glop", optimization_problem_type); MPVariable* const x = solver.MakeNumVar(0.0, 1, "x"); MPVariable* const y = solver.MakeNumVar(0.0, 2, "y"); MPObjective* const objective = solver.MutableObjective(); objective->SetCoefficient(x, 1); objective->SetCoefficient(y, 1); objective->SetMaximization(); solver.Solve(); printf("\nSolution:"); printf("\nx = %.1f", x->solution_value()); printf("\ny = %.1f", y->solution_value()); } void RunExample() { RunTest(MPSolver::GLOP_LINEAR_PROGRAMMING); } } int main(int argc, char** argv) { operations_research::RunExample(); return 0; }
C# 代碼
using System; using Google.OrTools.LinearSolver; public class my_program { private static void RunLinearProgrammingExample(String solverType) { Solver solver = Solver.CreateSolver("IntegerProgramming", solverType); Variable x = solver.MakeNumVar(0.0, 1.0, "x"); Variable y = solver.MakeNumVar(0.0, 2.0, "y"); Objective objective = solver.Objective(); objective.SetCoefficient(x, 1); objective.SetCoefficient(y, 1); objective.SetMaximization(); solver.Solve(); Console.WriteLine("Solution:"); Console.WriteLine("x = " + x.SolutionValue()); Console.WriteLine("y = " + y.SolutionValue()); } static void Main() { RunLinearProgrammingExample("GLOP_LINEAR_PROGRAMMING"); } }
Python 代碼
from __future__ import print_function from ortools.linear_solver import pywraplp def main(): solver = pywraplp.Solver('SolveSimpleSystem', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING) x = solver.NumVar(0, 1, 'x') y = solver.NumVar(0, 2, 'y') objective = solver.Objective() objective.SetCoefficient(x, 1) objective.SetCoefficient(y, 1) objective.SetMaximization() solver.Solve() print('Solution:') print('x = ', x.solution_value()) print('y = ', y.solution_value()) if __name__ == '__main__': main()
Java 代碼
import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; public class my_program { static { System.loadLibrary("jniortools"); } private static MPSolver createSolver (String solverType) { return new MPSolver("my_program", MPSolver.OptimizationProblemType.valueOf(solverType)); } private static void runmy_program(String solverType, boolean printModel) { MPSolver solver = createSolver(solverType); MPVariable x = solver.makeNumVar(0.0, 1.0, "x"); MPVariable y = solver.makeNumVar(0.0, 2.0, "y"); MPObjective objective = solver.objective(); objective.setCoefficient(y, 1); objective.setMaximization(); solver.solve(); System.out.println("Solution:"); System.out.println("x = " + x.solutionValue()); System.out.println("y = " + y.solutionValue()); } public static void main(String[] args) throws Exception { runmy_program("GLOP_LINEAR_PROGRAMMING", false); } }
執行結果如圖:
下一篇這個系列的文章,將具體介紹一種約束求解的應用場景。