Optaplanner與Google OR-Tools的區別

 

在規劃相關的項目工做中,近兩年咱們的項目主要使用的是Optaplanner做爲規劃引擎,其核心也是一個的規劃求解器(Solver)。但做爲另外一個著名開源求解器Google OR-Tools(下稱OR-Tools)也日漸流行。且因Google自帶流量的支持,OR-Tools有更多專門研究運籌的學者使用和研究。而Optaplanner則更偏向工程實踐上的應用。本文就兩者在技術特性、使用方法與場景等方面,列出若干差別。但願爲須要使用開源求解器進行項目工做的同行提供初步入門參考與選擇。html

簡介

Optaplanner

Optaplanner目前是Apache基金會的一款開源軟件,JBOSS社區,基於Apache開源軟件協議,該協議對商用友好,所以能夠自由地將該技術的部門或所有應用於商用軟件項目中。該項目目前由受僱於Redhat的團隊在維護.其創業人Geoffrey De Smit先生做爲該項目的Leader. 其實Optaplanner已發展了十餘年,最初是由Geoffrey在參加運籌規劃大賽中,針對各類競賽題目 開發的一個求解器。後來將它貢獻給開源社區,並做爲開源項目一直維護至今,其版本發佈仍十分高效,除進行一些對用戶透明不可視的算法與架構優化外,不時還有極具價值的新功能與新特徵發佈,如7.09版本發佈的多線程支持,本人認爲是極具里程碑意義的新特徵,能夠令對運算資源敏感的求解過程,最大程度上提升對CPU的利用率。node

Google OR-Tools

Google OR-Tools, 顧名思義是由Google提代的一套運籌規劃的運算工具,它針對不一樣的規劃場景,提供了不一樣的求解器(以組件方式提供)。OR-Tools一樣是基於Apache開源軟件協議,它是由受僱於Google的Laurent Perron博士帶領團隊維護。OR-Tools的討論區討論至關熱烈,主要緣由是它的使用方法與傳統商用的求解器(如Cplex, Gurobi等)至關相似,所以至關一些運籌學的學者、學生對該軟件比較感興趣。git

下面,從使用方法,結構構成等方面,分別對兩個規劃引擎進行分別討論。github

開發技術與使用方式的區別

Optaplanner的技術特性

Optaplanner是使用Java語言開發,是基於純Java技術。所以,使用它的時候也只須要使用Java語言自己的特性,便可知足幾乎全部基本的建模、開發及求解過程;而無需使用其它第三方的技術或框架。固然當你在實際的工程實踐中,仍是須要依賴強大的Java生態圈,才能讓項目事半功倍。例如經過第三方組件實現日誌,數據的持久化、Web服務等。算法

Optaplanner的評分邏輯,須要使用Drools做爲規則描述語言,實現約束的評分。事實上Optaplanner同時支持Java語言實現約束評分的,即Easy Java Score Calculation與Incremental Java Score Calculation,使用這兩種評分方式,評分邏輯可直接使用Java語言實現。僅需經過POJO便可對業務實體進行建模,經過Java程序代碼便可描述業務約束。Optaplanner的核心程序以Jar包方式提供;固然你也能夠獲取它的源代碼,從源代碼級把它的核心集成到你本身的系統中去。但做爲商業軟件項目,此方法並不是最佳實踐,直接使用官方發佈的Jar 包便可。Optaplanner不支持MiniZinc做爲建模語言,OR-Tools則支持該種約束建模語言。在對MiniZinc的支持方面,可能各位ORer感受有些許遺憾。服務器

與既有系統集成成

從另外一個角度來看,純Java技術實現的Optaplanner,對使用環境起到簡化做用的同時,又會造成了一種限制。例如對於一些非Java技術開發的系統(例如一些舊系統),要與Optaplanner集成到同一個程序中,則沒法實現嘗試結合。對於這種狀況,解決辦法是將Optaplanner獨立成一個Web服務,以WebAPI 的方式對外提供服務。事實上這種系統結構即便是在整個項目都是用Java開發,也是直得推薦的方法。由於規劃服務程序在運行的時候,主要佔用的資源是CPU的運算資料,在一些規模大,規則複雜的規劃程序中,對CPU資源的佔用更明顯。從另外一方面來看,在某些複雜的規劃場景中,CPU的性能,直接決定了在固定時間內,找到相對最優方案的質量。所以,將規劃服務獨立成一個服務,使用獨立的服務器資源做爲運行環境,爲規劃引擎提供充足的CPU資源;同時也消除了規劃運算對系統其它部分的影響。微信

Google OR-Tools的技術特性

OR-Tools內核是使用C++開發,所以,其兼任性相對Optapalnner來講好不少。目前Google OR-Tools支持C++, C#, Java和Python四種語言接口。即他具備動態連接庫存(DLL), Jar包和Python包三種提供提供形式。固然由於它的原始形式是dll文件,用過Java對它進行調用的時候,就須要經過JNI對它進行裝載,下文的示例中會展現。由於OR-Tools提供豐富的兼容形式,所以,與不一樣系統集成較容易。可直接將它的源代碼或DLL嵌入到本身的系統中去。固然,若是使用源代碼的方式集成,只能嵌入到C++開發的系統中。網絡

建模語言方面,OR-Tools同時支持使用程序語言(Python, C++, Java, C#)描述模型,如上文提到,它同時也支持MiniZinc做爲約束建模語言。各位科班出身的ORer應該對此較有親切感。也所以在OR-Tools的討論區,其中提出討論的問題,除了工程實踐的問題,還有很是可能是運籌學方面較專業的理論問題。這也許反映了世界各地存在着大量的ORer正在使用OR-Tools做爲他們的研究工具。多線程

與既然有系統的體成

在系統集成方面,由於OR-Tools接口相對開放,集成的問題則基本上不存在任何問題。其核心(規劃求解器)能夠做爲系統的一個組件存在於任何系統中;也能夠將其封裝成一個服務對外提供服務。架構

建模方式的區別

在建模方式方面,二者均可以使用程序設計語言進行規則、約束描述。同時也可以使用使用其它專用的約束或建模語言;Optaplanner支持Drools, OR-Tools支持MiniZinc。但二者面對的場景,或說偏向解決的具體問題,仍是有區別的。

Optaplanner更偏向於面向對象

使用Optaplanner進行系統開發的時候(例如開發APS系統),如其它商用軟件同樣,先對業務進行分析,設計出具體的業務實體,識別出須要規則的實體和因素(字段),提練出業務規則,概括出哪些規則是硬約束,哪些是能夠優化的軟約束。而後根據Optaplanner的固定對象結構模式,創建Planning Entity, Planning Variable,Problem Fact和Solution等類;並配置好求解器的各類參數。整個核心系統的設計就差很少完成了。

Google OR-Tools偏向於傳統的數據建模

OR-Tools除了一樣須要進行業務分析與設計外,還須要加多一步工做 - 數學建模。由於OR-Tools求解規劃問題時,輸出的必須是一個完整的數學模型。也就是在使用OR-Tools進行系統開發時,須要先進行業務分析設計,得到各類業務要素和約束後,須要對這些業務要素進行數學建模,並將這個模型以程序語言(Python, C++, Java, C#)或MiniZinc進行模型描述。而後才能啓動規劃求解器進行尋找優點方案。事實現Optaplanner在使用其求解器進行規劃求解時,也須要有相應的數學模型的,只不過它能夠在求解以前,把用Java對象表示的業務模型,轉換成數學模型;而這個步驟對使用都來講是透明的,所以無需關心。

使用場景的區別

基於上一節中二者建模方式上的差異,對於偏向於理論研究、學習的學者來講,OR-Tools更接近於他們平常接觸的各種規模模型,與CPLEX和Gurobi等知名商用(有免費的學術用途受權)求解器的應用方法與設計思想均較接近。所以,對於一些考研類的應用場景,OR-Tools來得更直接。

而Optaplanner則更趨向解決具體的業務問題,從期誕生的背景能夠得知,它主就是爲解決具體問題而生的。關於 Optaplanner的來歷,能夠參考其做者Geoffrey的一篇博文《A decade of OptaPlanner》。儘管Optaplanner與OR-Tools其核心是至關接近的,都是經過各類啓發式算法,對NP-Hard問題尋找相對最優解。但Optaplanner考慮到非運籌專業人員的數學功底,對問題多作了一層封裝,將程序中描述業務問題的各類對象,轉換成相應的規劃模型,再進行規劃求解。從而在商用軟件開發環境中,普通的程序設計人員,只須要關注具體的業務細則,根據Optaplanner提供的模式,創建合理的對象模型,來反映業務模型,確保這些業務模型能準確地反映業務需求便可。而無需再將這些業務模型轉換成可運籌學上數學規劃所需的數學規劃模型。從而大大下降了規劃程序的開發難度。

從規劃到AI

目前兩個引擎都號稱本身屬於AI約束求解器,OR-Tools被歸入做爲Google AI的其中一個產品。也難慘,畢竟這兩個引擎的規劃求解器都是基於啓發工算法,確實有對於NP-Hard問題,啓發式算法是目前較經常使用的算法,而這些算法對數據的各要素的具體分佈狀況依賴較大。必定程度上體現了「智能」的感受。不過我更以爲這是爲了蹭近年AI的火,以爲不必呀,雖然AI的核心算法追溯回去與運籌規劃是同源的。但運籌畢竟已是一個很成熟獨立的分支了。

 

 

Google OR-Tools最基礎入門

如下代碼是OR-Tools的一個最基本的入門示例,它解決的是《Excel與Google Sheets中實現線性規劃求解》一文中的生產資源優化問題。讀者能夠結合這篇文章中相關的模型,來對照這些代碼進行理解,從中體OR-Tools在進行規劃求解時所需的規劃模型的創建方法。

 

 

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 HelloOR {
        // 經過JNI調用OR-Tools包
    static { System.loadLibrary("resources/jniortools"); }

         // 建立求解器對象
     private static MPSolver createSolver (String solverType) {
        return new MPSolver("my_program", MPSolver.OptimizationProblemType.valueOf(solverType));
     }

          // 程序入口,建立一個線性規劃求解器,並求解規模模型。
          public static void main(String[] args) throws Exception {
        solverTest("GLOP_LINEAR_PROGRAMMING");
      }

      private static void solverTest(String solverType) {
        MPSolver solver = createSolver(solverType);
        // 建立決策變量,Optaplanner中稱爲Planning Variable, 規劃變量.
        double infinity = MPSolver.infinity();
        MPVariable x = solver.makeIntVar(0.0, infinity, "x");
        MPVariable y = solver.makeIntVar(0.0, infinity, "y");
        
        // 建立約束
        //資源1限制: 5x + 3y <= 280
        MPConstraint c1 = solver.makeConstraint(-infinity, 280);
        c1.setCoefficient(x, 5);
        c1.setCoefficient(y, 3);
        
        //資源2限制: 4x + 8y <= 580
        MPConstraint c2 = solver.makeConstraint(-infinity, 580);
        c2.setCoefficient(x, 4);
        c2.setCoefficient(y, 8);
        
        //資源3限制: 3x + 5y <= 360
        MPConstraint c3 = solver.makeConstraint(-infinity, 360);
        c3.setCoefficient(x, 3);
        c3.setCoefficient(y, 5);
        
        // 建立目標函數,求20*x + 25*y 的最大值.
        MPObjective objective = solver.objective();
        objective.setCoefficient(x, 20);
        objective.setCoefficient(y, 25);
        objective.setMaximization();
        
        // 調用求解器求解模型,並輸出結果.
        solver.solve();
        System.out.println("Solution:");
        System.out.println("x = " + x.solutionValue());
        System.out.println("y = " + y.solutionValue());
        System.out.println("20x + 25y = " + (20 * x.solutionValue() + 25 * y.solutionValue()));
      }

     
}

能夠看到,使用OR-Tools裏,須要先創建Solver對,並將模型中的各不等式以係數方式體現到程序中,最後求解得出結果。由於這是一個線性規劃問題,所以代碼中建立的是一個線性求解器(以GLOP_LINEAR_PROGRAMMING參數表示)。儘管都是規劃問題,但針對不一樣同的類型,OR-Tools提供不一樣的Solver解,例如線性規劃問題,TSP問題等,有專用的Solver對象解決。

輸出結果爲:

 

關於Optaplanner的使用方法,則能夠《Optaplanner規劃引擎的工做原理及簡單示例(2)》。

  • End.

如需瞭解更多關於Optaplanner的應用,請發電郵致:kentbill@gmail.com

或到討論組發表你的意見:

https://groups.google.com/forum/#!forum/optaplanner-cn​groups.google.com

如有須要可添加本人微信(13631823503)或QQ(12977379)實時溝通,但因本人平常工做繁忙,經過微信,QQ等工具可能沒法深刻溝通,較複雜的問題,建議以郵件或討論組方式提出。(討論組屬於google郵件列表,國內網絡可能較難訪問,需自行解決)

相關文章
相關標籤/搜索