Optaplanner - 入門介紹

OptaPlanner背景

  在上一篇裏噴了不少水,這一篇準備放點乾貨;其實也沒辦法完全乾,因爲很多預備知道在交待一下。好了,說一下關於OptaPlanner的背景、應用兼容性及其原理。

這一篇先說一下OptaPlanner是何方神聖,再看看它適用於哪種平臺(.NET能用嗎?老舊系統能用嗎?),再從原理上探究一下,它是如何幫我們把一個看上去幾乎不可能實現的工作,努力做到比經驗豐富的老師傅更好的。下一篇我將會講解OptaPlanner相關的基本概念,並教大家它的examples(示例)運行起來(這些examples可是好東西喔,並且非常豐富)。

  顧名思義,叫什麼planner的,它肯定是用來plan東西的東東,就是把一堆東西(數據)扔進去,再教它一些規則(Drools腳本或Java寫的算分程序),然後它就運用它的數學頭腦,把這些東東按要求把它初始化好,並努力找到一個相對最優的方案;如果數據不是太多,那它就能找到一個絕對最優方案了,因爲它以把所有情況都篇歷。例如:你有一堆任務需要確定分配到哪些機臺,需要計算每個任務什麼時候開始處理(也就是明細的生產計劃了);用OptaPlanner跑完之後,就會給出一個方案,這個方案包含了每個任務應該放在哪個機臺,應該在什麼時候開始。又例如:在醫院等單位進行醫護人員排班時,把各個醫護人員的專長,每個人員的作息信息,每個科室需要的專業技能等信息放進去,OptaPlanner就能給你找出一個排班方案出來,可以滿足各科室對特殊專業人員的需求,也可以滿足各人員儘量不超時工作的方案。

  那麼問題來了,OptaPlanner到底是一個什麼鬼東西?它有這麼牛?真能這樣,我們做排產的老師傅不是要失業了嗎?其實不然,它只是按我們設計的規則來找儘量好的方案,而這些規則好不好直接影響到方案的優劣,所以如果OptaPlanner成功應用了,並不是替代了老師傅們,而是把老師傅解放出來,讓他們去重新思考並制定更佳的規則,並通過OptaPlanner來驗證並實現這些方案。

  E文好的同學可以直接進它的官網(http://www.optaplanner.org), 學成了記得分享呀。先說一下這OptaPlanner的來頭,它本來是一個名叫Geoffrey De Smet的大牛自己寫的,後來他就把它貢獻給了JBoss基金會(這裏省去了N年的曲折離奇, N >= 10),併成爲KIE項目組中OptaPlanner項目的負責人。所以OptaPlanner是基於Apache2.0開源協議的,對商業友好,就是說你想用就儘管用,有問題還可以在他們的討論組上求助。關於這位超級大牛的個信息及OptaPlanner的詳情,可從以下鏈接看到,其實這位大牛給OptaPlanner錄製了很多講解OptaPlanner的視頻,只不過它只放在Youtube上,大家要看的自己想辦法上去搜OptaPlanner了,提醒一下各位,Gerffrey這牛不是英美或其它以英語爲母語國家的人(好像是比利時還是荷蘭人),它的口語鄉單比較重,聽起來挺吃力的,還沒字幕。而且講的都是各個示例和一些比較高級的應用,去看視頻之前最好還是打一下基礎,要不然基本上看不懂(沒基礎就算講中文也聽不懂吧?)。

  Geoffrey De Smet在GitHub上的主頁:https://github.com/ge0ffrey(還有StackOverflow上也有他老人家不少對OptaPlanner問題的解答,大家可以搜搜
OptaPlanner的背景介紹:http://www.oschina.net/news/75942/a-decade-of-optaplanner (這是開源中國社區翻譯Geoffrey老人家的文章,原著E文版在這:http://www.optaplanner.org/blog/2016/08/07/ADecadeOfOptaPlanner.html

  OptaPlanner其實是一個很好的排程引擎(更貼切地說它是一個規劃引擎,下面就稱規劃引擎吧,因爲它不光用於排產上),耐何在國內使用的人十分少,所以中文資料幾乎沒有,國內有幾個比較出名的APS產品,不知道其排程核心用的是什麼,不過如果是自主開發APS系統的話,OptaPlanner是一個好的引擎,畢竟並不是所有企業都能找到一堆數學專家對組合優化問題進行研究的。而OptaPlanner資料非常豐富,它的項目組還能提供很好的技術支持(免費的僅限於討論組答疑,付費的就沒試過了),而且使用起來也方便、容易。但目前我觀察的情況來看,還只有比較多國外的同行們及相關的技術網站在研究討論。我也是奉公司之命開發生產排程方面的系統,才硬着頭皮去啃它的。又耐何我的體育老師不給力,教的E文也不怎麼樣,雖然是把基本的東西看懂了,但很多更深層的東西其實還沒有完全摸透的(到目前爲止我還遇到一個Score Corruption的問題還在研究)。所以有賴大家一起學習之後的分享了。在應用OptaPlanner的過程中,我也遇到一些問題,一開始有些小白問題,後來又遇到一些跟系統實情相關的難題,我也曾經在討論組上向Geoffrey他老人家請教,老實說,他還是一個比較有耐心,非常nice的人,一點都不嫌我這類小白煩,從原理開始給我講解出錯的原因,應該如何改,這個要猛贊一下。

  接下來我就發揮程序狗的看家本領Ctrl + C -> Ctrl + V, 中間還去逛了一次百度翻譯(沒辦法,體育老師呀).
OptaPlanner是一個約束求解器。它優化了企業資源計劃的使用情況,如車輛調度、員工排班、雲優化、任務分配、任務調度、Bin Packing等等。每個組織都面臨這樣的調度難題:分配一組有限的受限資源(員工、資產、時間和金錢)來提供產品或服務。OptaPlanner提供了更有效的計劃,提高服務質量並降低成本。OptaPlanner是一個輕量級的、可嵌入的規劃引擎。它令普通的java程序員有效地解決優化問題。它還與其他JVM語言兼容(如 Kotlin 與 Scala)。約束適用普通的域對象,可以重用現有代碼。沒有必要把它們作爲數學方程來輸入。在引擎蓋之下,OptaPlanner結合先進的優化的啓發式和共通啓發式演算法(如禁忌搜索、模擬退火和延遲接受),非常高效地進行分數計算。OptaPlanner是開放源代碼的軟件,Apache軟件許可下發布。它是用100%的純java™,運行在任何JVM在Maven的中央存儲庫也可用。

  好了按上述的官方描述我們可以大概知道,它就是一個用來解一些規劃問題的引擎,而規劃問題幾乎都可以被視作NPC問題,關於什麼是NPC問題呢?這裏還噴點水,讓大家對NPC問題有個大概的概念,如果不是研究數據的,瞭解一下就可以了。大家可以看一下這位牛人寫的關於NPC問題的文章(http://www.matrix67.com/blog/archives/105),概括來說,就是一些沒有辦法使用確定性算法來得到結果的問題,而對於這類問題,又分爲NP問題和NPC問題,但都只能通過遍歷的辦法才能找到。對於NP問題和NPC問題,我有以下理解,也不知道對不對,大牛看到不對的幫忙指正一下

  NP問題:一種無法通過確定性算法直接獲得解,但對獲得的解是可驗證的,例如:結合上一篇文章提到的生產排程問題,如果老闆只要求做出一個可行的生產計劃,也就是只需要一個可以執行的生產排程就可以了。成本、效率什麼的都不管;那麼這就是一個NP問題。因爲要做出這個計劃,你也是沒有直接的、確定的方法或算法來做的;更多的是靠經驗、對實際情況的有限掌握、對來情況的預判和感覺。但是做出來的計劃是可以驗證的。也就是說車間拿着這個計劃是真的可能執行的,而不會出現物料不到位、產品分配到了錯誤的機臺上等違反硬約束問題的, 那麼只要不違反這些硬性約束,就認爲這是一個可行的計劃。所以做一個可行計劃,可以被視作是NP問題。

  NPC問題:則是那種不旦無法通過確定性算法獲得解,對所得的解,也沒有一個確定的辦法去驗證的問題。還是上面的生產排程問題,如果老闆要求做一個所有情況下除了可行,還要成本最低、效率最高的計劃。那麼:1. 計劃員也只是靠經驗、預判、對數據有有限掌握做出一個計劃來,計劃是否可行是可能驗證的(也就是NP問題),但這個計劃是否成本最低、效率最高,那就沒辦法驗證了,除非你把所有可能的計劃都列出來(這個就不是確定性算法了,因爲並不是所有情況你都能把所有情況都列出來)。事實上,現實世界遇到的問題,光靠人類,即便通過超級計算機,也是不太可能把所有情況都遍歷完的,例如一個計劃有1000個任務,就算忽略任務的所有其它考慮因素,就是1000個任務無任務要求,隨便自由地排列,也就是1000個數的排列問題了,有多少種情況?是1000的階乘!(有興趣的同學自己回顧一下高中的排列公式)再考慮每個任務的各種屬性,及每個屬性的可能取值範圍,那麼組合下來,通常是天文數字了。

  所以,OptaPlanner在排程領域的作用就是幫人們對問題的可能性進行“遍歷”,爲什麼我把遍歷引起來呢?因爲如果僅僅是無序地遍歷,對所有情況一個一個試,那OptaPlanner就沒啥作用了,我們可以通過自己編寫程序,就能設計出遍歷所有組合情況的代碼來(能不能跑完那是另外一回事)。OptaPlanner強大之處在於,他是有方法地去遍歷的,它引入了禁忌搜索,模擬退火等算法,力求在固定的時間內,找到比傻傻地遍歷更好的組合方案出來。事實上也證明它這些算法是有效的。

OptaPlanner的作用、構架和應用兼容性

  關於OptaPlanner開源包,大家可以上官網看看,我在這裏也只做個大概的介紹,畢竟我也是新手呀。其實OptaPlanner現在已經加入KIE Project Group,作爲KIE的一個子項目,關於KIE可以看看Redhat的一個項目羣,包括了OptaPlanner(就是本系列文章的主角),Drools(規則引擎,國內已有很多相關的資料,我就不再熬述了,OptaPlanner是需要結合Drools來使用的,所以這個系列的文章裏也會有些內容涉及Drools,但不會太深入),另外一個就是jBMP了,是一個流程定製的平臺。

作用

  OptaPlanner用官方的描述就是可以幫你規劃出一個用更少的資源做更多更好事情的規劃引擎。如下圖列出它可以做的工作領域(這僅僅是OptaPalnner的Example裏有的示例,其實所有關於規則的問題,屬於NPC的問題,只要你能把它抽象並建模成OptaPlanner可識別的模型,你就可以用OptaPlanner來解決):車輛調度、工作排程、設備排程,Bin Packing(就是用袋子裝石頭那個問題啦)及員工排班。

  

構架和應用兼容性

  那麼應用OptaPlanner需要什麼條件呢?其實作爲一個輕量的、可嵌入的規則引擎,兼容性肯定是人家設計時的考慮重點之一,所以它完全是一個純Java環境的軟件,只要你的系統有Java8以上的運行環境(7.6版本要求的是Java8),遵循 Apache Software License 2.0就可以使用了。在我的工作中,我把它運行於Windows, 雲端的Unbuntu.凡是一般Java程序能運行的環境,只需你一個jar命令,就可以運行你內嵌了OptaPlanner的程序了。這裏有一個官方關於OptaPlanner兼容性的圖:

    

  那麼有人就問了,現在很多企業用的都是Microsoft平臺或其它老舊平臺技術(有什麼辦法呢.NET就是多人才),是不是OptaPlanner與我的項目就無緣了?其實不然,因爲OptaPlanner本身是一個引擎,是基於Java技術的,你通過它來實現你自己的規劃引擎程序的時候,必然也是需要Java寫的。但這個規劃程序是一個服務程序,它不像普通的Web程序,需要頻繁跟用戶交互,事實上它的所有運行過程中涉及的數據都是需要基於內存的,在此過程是不能進行IO的(並不是說OptaPlanner引擎不允許這麼做,而是我們設計的時候就不應該這麼做),至於爲什麼,是碼農都懂,一個對CPU高度依賴的程序,你還要它去做I/O,是不是有點那個?所以通常情況下,它是一次性把需要規則及數據都裝入內存,完成後再輸出。基於上述原則我們就可以把寫好的規劃引擎程序(Java包)放在一臺相對獨立的服務器上去運行,再以服務的形成爲其它客戶端系統提供規劃服務。那你的客戶端系統是用Web還是 C++來寫,是你自己的事了。

原理

  那麼OptaPlanner是通過什麼方法,高效地幫我們在儘量短的時間內,找到更佳的方案呢?還記得上一任篇老農提到,我們做排程的時候,通常有兩種約束條件,分別是不可違反的硬約束,如果一個計劃違反了硬約束,那這個計劃就是不可行的,例如:生產計劃中,把產品固定工序的加工次序調亂了,又或者把產品分配到錯誤的機臺上生產(這些約束條件都是業務上你們自己定義的),那麼OptaPlanner就把它定義爲違反了硬約束。另一類就是軟約束,就是那種可以違反,但違反得越多,就會影響越大(影響包括成本、效率、質量等),所得結果方案的質量越差;違反這種約束,OptaPlanner就把它定義爲違反了軟約束。OptaPlanner就是對這兩類約束進行打分,硬約束對應的是硬分數,軟約束對應的是軟分數。那麼得分越高,就表示對應方案的質量越高。在計算這些約束分數的過程中,OptaPlanner會保持優先優化硬分數、然後在硬分數最優的基礎上,再去優化軟分數的原則,來尋找最佳方案。例如:兩個方案A、B對比,方案A的硬分數比方案B的硬分數高1分,方案B的軟分數比方案A的軟高出10萬分。那麼OptaPlanner最後還是認爲方案A更佳。也就相當於我們寫SQL腳本時,order by子句中前後兩個字段的關係了,靠前的字段排序比靠後的字段更優先。

思考題:

  既然硬約束是不能違反的,那OptaPlanner當然要保證找出來的方案絕對是不違反硬約束的,這個大家覺得在所有情況下都成立嗎?就是OptaPlanner必然給你找到一個絕對不違反硬約束的方案嗎? - 顯示不是,大家自己思考一下。

這一篇我們先介紹一下OptaPlanner的背景、使用情景和原理。下一篇我們就開始實質的瞭解它的應用。

另外,若對此文(或本系列任何內容)感興趣,歡迎轉載,但請尊重艱辛勞動,註明出處。爲謝!

本系列文章在公衆號不定時連載,請關注公衆號(讓APS成爲可能)及時接收,二維碼:
Optaplanner - 入門介紹

如需瞭解更多關於Optaplanner的應用,請發電郵致:[email protected]
或到討論組發表你的意見:https://groups.google.com/forum/#!forum/optaplanner-cn
若有需要可添加本人微信(13631823503)或QQ(12977379)實時溝通,但因本人日常工作繁忙,通過微信,QQ等工具可能無法深入溝通,較複雜的問題,建議以郵件或討論組方式提出。(討論組屬於google郵件列表,國內網絡可能較難訪問,需自行解決)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章