Optaplanner規劃引擎的工做原理及簡單示例(1)

  在以前的文章中,老猿已介紹過APS及規劃的相關內容,也對Optaplanner相關的概念和一些使用示例進行過介紹,接下來的文章中,我會本身作一個規劃小程序 - 一個關於把任務分配到不一樣的機臺上進行做來的小程序,並在這個小程序的基礎上對Optaplanner中更多的概念,功能,及使用方法進行講解。但在此以前,我須要先講解一下Optaplanner在運行規則運算的原理。因此,本文是講述一些關於尋找最優解的過程當中的原理性的內容,做爲後續經過示例深刻講解的基礎。但這些原理知識不會涉及過度深奧的數學算法,畢竟咱們的目標不是寫一個新的規劃引擎出來,只是理解一些概念,用於理解Optaplanner是依據什麼找出一個相對優解的。好讓在接下來的一系列文章中,能夠快速無障礙地理解我所講解的更細化的Optaplanner功能。算法

  好了,言歸正傳,本文主要是講述Optaplanner是如何在用戶定義的規則限制條件中,基於約束的限制,對被規劃對象進行排列組合,再對比各個組合(稱做解,或方案),並找出相對最優的解出來。在這個尋優過程當中,Optaplanner會使用到一些相關算法,例如啓發式算法(例如First Fit)和延遲接受法(例如禁忌搜索),從而提升尋找相對最優解的效率和防止嵌入局部最優解,從而能夠在固定的時間內,找到儘量優的方案。小程序

  在理解Optapalnner是如何實現以前,咱們先複習並展開一下上一篇提到的概念 - 約束。微信

約束(Constraint):

  也就是對事物的一種限制,規定事物的發展應該遵循什麼規則,具體到Optaplanner裏,就是用於表達出什麼是對的,什麼是錯的,什麼狀況是最優,什麼狀況次優,什麼狀況較差。從而讓引擎獲得各個解的對比依據。網絡

  在Optapalnner中的約束能夠分爲硬約束軟約束兩種,其實還有更多的約束類型 ,例如中間約束,甚至是無限層級的約束,但總結起來,其做用也就是把約束劃分爲不一樣層級,從而區分出不一樣的優等級而已,若是有軟件開發經驗的同窗,能夠理解不一樣層級的約束,分別是SQL語句裏Order By子句後面的字段次序。在進行記錄排序時,前面的字段排列的優先級,是從性質上優先於後面的字段的,你們理解了Order By子句,也就理解了不一樣層級約束的問題了。拉下來咱們以最簡單的軟硬約束,來分析一下約束的做用。工具

硬約束:

  硬約束是用來規定什麼狀況是對的,什麼狀況是錯的;什麼組合是好的,什麼組合是很差的......也就是它一般是用來對所得的解進行一些定性的狀態定義。例如一個計劃是否可行,例如會不會同一個機臺同一個時間分配了兩個不一樣的任務(假設每一個機臺同時只能作同一個任務)。一個員工所排班次是否正確(例如一個員工是否被安排了三個連續的班次)。若出現上種狀況,即表示違反了硬約束,這種方案稱做不可行方案。之後的文章裏,會提到Optaplanner裏有一個明確的概念 - Feasable Solution(可行方案,或稱可行解),就是表示這個方案是徹底符合硬約束的。優化

軟約束:

  軟約束規定什麼狀況最優,什麼狀況次優,什麼狀況是差的;它是用來定義方案優劣的定量狀態。例如:一個計劃的成本是否足夠低;一個排班表到底有多大程度上的合理性,例如一我的正常狀況下是須要5天工做制的,但若是遇到特殊狀況,也能夠連續工做6天,但這種狀況是特殊的,須要額外付加班費(成本上升)最好不要出現這種狀況。那麼在編制這個排班表的時候,若是有一個方案是須要有人員連續工做6天,但若是找到另外一個方案,能夠令全部人均不須要連續工做6天,那麼,後面這個方案就比那些有人須要連續工做6天的方案更好了。體如今軟約束上,就是後面的排產表,其軟約束上會比前一個排班表更好,違反的軟約束更少。google

  上述講述的是兩種常見約束,那麼這些約束在Optaplanner裏是如何生效的呢?那說須要有一種評分機制了,也是咱們在使用Optaplanner裏,比較難準確把握的一個內容之一。人工智能

評分機制:評分是用分數來評價事物特性的一種方法。但若是咱們細心觀察總結一下,會發現評份是能夠經過兩種方向來評價的;分別是正評分(獎勵性評分)和負評分(懲罰性評分)。spa

正評分:經過得到分數的多少,來體現事物的優劣。例如咱們在學校考試過程當中,成績是經過一種正分數來體現的,即作對一題獎勵相應的分數,分數越高成績越好;完美狀態是得到滿分。調試

負評分:經過扣除分數的多少,來體現事物的優劣。例如咱們的駕駛證記分制,每違章一次就扣除相應的分數,很明顯這種評份體系中,分數越低越好,也就是扣得越少越好;完美狀態是扣0分。

  在對實際問題進行約束規劃時,是一種封閉性約束,也就是約定事物往指定的一個方向發現,使用負評分的方式,很顯然更合理。也就是一個方案有哪些很差的,咱們經過對它評定一些懲罰分數標準,告訴引擎這種組合出現了一些不太好的狀況。如此類推,每找到一個更佳、扣分更少的方案,就離完美就更近一步。不管是使用正方向評份仍是反方向評分(或稱負方向評分),在Optaplanner裏都是能夠實現的,只不過按咱們平常的邏輯,在定義方案時,一般咱們只會根據業務定義出一些規則,方案是須要守這些規則,當一個方案出現有違反規則時,就做出相應的懲罰性扣分;這種方法比當出現好的狀況就加分更合理。由於咱們的現實世界裏,"好"是可能無限好的,當問題足夠複雜,數據量足夠大,即問題規模夠大時,描述一個方案如何個好法,其實很難是一個定數。比描述一個方案如何個差法更難,由於前者能夠是無限的,然後都就只須要咱們定義好什麼是差的標準,一但問題範圍肯定,它的最差狀況(也就是最差的扣分狀況)就有一個字數了。因此,在Optaplanner的世界裏,常見的作法是,定義一些約束,並設定相應的懲罰分數標準(即將約束量化),用來描述這個方案的制約因素,當這個約束實打破時,就做出懲罰性記分,那麼到最後,扣分越少的方案就越好。這就是Optaplanner實現尋優的最基本原理,但其實現是很是複雜的,會將問題劃分爲不少種類,將尋優的過程劃分爲多個階段,每一個階段利用不一樣種類的算法來提升找到更優方案的效率,每一個階段有不少個步驟,每一個步驟又有多個移動(沒錯,Optaplanner裏就有Step與Move的概念,之後會詳解);在之後的深刻文章中,我會詳細把這個過程分析出來。

  上面描述了硬約束、軟約束和評份機制。那麼如何將這兩種約束與這種評分機制關聯起來,令評分機制能夠實現軟、硬約束呢?你們可能已想到,在Optaplanner給出了軟分數,硬分數的概念。在評分機制中,當出現一個方案違反了某個硬約束時,就給這個方案扣除這個約束相應的分數;一樣地,當該方案違反了一種軟約束時,就對該方案扣除該軟約束相應的分數。這兩個分數是分開處理的。由於經過它們對應的約束類別就知道,它們分別表明的性質不同,硬分數對應的硬約束,表明的是一種定性評價;即描述方案好很差,行不行,可不可取等,一旦被記扣硬分數,那就表示這個方案的性質就變了,由可行方案變成不可行方案。理想的方案是一個硬分都不能扣的,一旦扣了就是不可行方案了。有人問,那麼定義硬分數的分值有什麼用?直接給一個標識出來,將方案的可用性定義爲True or False,分別表明是事有硬約束被違反不就好了嗎,多簡單呀,由於一旦爲False就是不可用了,再去討論它扣了多少分,又有何意義呢?硬約束、硬分數不就是爲了給方案定性而設立的嗎?何須還要記錄它的扣份量,畫蛇添足呢?

  若是這樣想,就是一種不全面的想法了。由於你們須要明白,現實世界每每是很大程度是不完美的,但而對不完美,咱們是放棄這個世界,仍是在不完美中進行堅持,對這個不完美的世界,朝完美的方向進行改造呢?上面的說法就比較抽象比較虛了,舉個你們容易理解的例子。例如:刑法是用來懲罰犯罪的,在正常的法治社會中,犯罪對於一我的說,就至關於違反了硬約束(刑事處罰記錄是終身跟隨的)。也就是對於一我的來講,一輩子中是否觸犯過刑法,是一個定性的問題。那麼既然是定性問題,咱們在設立刑法的時候,其對應的懲罰是否是隻有一種就足夠了呢?例如凡是觸犯刑法,所有判死刑,那不就簡單得多啦?事實上人類社會是不可能這樣的,由於就算是觸犯了刑法(這個已是定性問題),但罪行也有輕重之分的、對應了刑法的不一樣條款,有些罪名通過對罪犯的懲戒,是能夠再給他一次機會的,也說就是說觸犯的刑法,是有輕重之分的,但性質不會變,他在國家司法機關的檔案裏,永遠留有普被刑事處理的記錄。因此,這能夠稱該種狀況爲定性範圍內的定量問題。就是一我的作錯了就是錯了,其性質已經定了,但犯的錯誤有多大,還得是一個定量問題。所以,硬約束對應的扣除硬的分數有多有少就不難理解了。就是咱們的方案若是出現了違反硬約束、被扣除了硬分數的,它在Optaplanner上就是一個不可行方案了。可是在衆多的不可行方案裏,其實還要區分哪一個是更不可行,哪些其實只是違反了一點點,仍是「稍爲可行的」。回到咱們的實際排程問題中,有可能客觀條件限制,咱們全部排出來的方案(例如生產計劃、排班表、車輛調試線路圖)都是不可行的,例如:咱們排生產計劃的時候,將交貨期延誤做爲一種硬約束,可是現實的生產活動中,確確實實有可能不管你怎麼排,由於產能、資源限制等因素,你是不可能找到一個完徹底全符合交期的生產計劃的,那麼這個時間咱們就須要找出一個違反得最小的計劃出來,做爲可行計劃,視狀況進行相應的修改並執行了。也就是說兩害相遇取其輕。

  對於硬約束,除了上述講到,當出現有可能確實須要使用不可行方案做爲執行計劃的狀況外,在Optaplanner進行規則的過程當中,其實也起到很是大做用的。先不說optaplanner引來來排程;若是讓你來排,對於各類硬約束,全都不給出一個分數,而是給一個定性的標識,就是一旦出現違反了,就報一個違反硬約束的消息出來,你會怎麼樣?你確定會抱怨提示的信息太簡陋了,只有一個標識,最多隻是知道哪裏違反了,再也沒有更詳細的信息供你參考了。那你接下來的排產活動,其實就是一個組合一個組合逐一地去碰彩了。由於各個方案之間是否有關聯,你是沒法得知的,因此你根本找不到什麼好的辦法去將各類狀況下的方案進行歸類、比較進行往指定的一個方向收斂。但若是在一個硬約束被違反時,會出現一些明確的信息,是哪一個硬約束被違反了。違反和程度是多少,扣了多少分,是由於哪一個被規則的對象,放在哪裏,或與哪一個對象相鄰從而致使的硬約束被違反。這樣就造成了一個很明確指導方向,對於人而言,經過概括統計就知道某些狀況確定會出現,或極大可能會出現違反硬約束的狀況,那咱們就能夠在排列新方案時,盡力去避免這種狀況了;也就是有了參考方向 。對於Optaplanner引擎來講也是同理,儘管它不像人這麼聰明(但最從近的消息來看,Optapalnner團隊已經着手思考人工智能引入到引擎中,從而實現如上述人類同樣對這類問題進行概括思考),但也可以做爲其尋找更佳方案的過程當中的一些很重要的參考,從而爲尋優算法所用,進而提升尋優效率。例如遺傳算法。

  軟分數對應的軟約束,表明的是一種定量評價;即描述方案有多好、有多差,成本有多高、有多低。它是一種優化約束,即在定義它的時候,就已經知道它必然是被違反的(也有可能徹底不違反,那固然是好的,但若是是這樣的話,就脫離了軟約束的初充了)。因此,軟件約束、軟件分數的扣分值用途相對來講就容易理解得多了。

   綜上所述,Optaplanner就是經過一種體現爲分數的約束機制,進行尋找最優組合。當一個排產問題中,設定的軟硬兩種約束時,它會優先知足硬約束的要求,再知足軟約束的要求,也就是說,軟約束被扣爲1萬分,也不及硬約束被扣了1分重要,聯繫上面的SQL語句中的Order By子句的例子。

  Optaplanner其利用途徑有如下兩點:

1. 用分數來肯定,一個方案是否可行,是優是劣;

2. 在決定每一步的時候,參考上一點的扣分狀況,來肯定下一次生成方法時,應該考慮哪此因素(想一想遺傳算法).

  這一篇咱們先講解一下原理,打一下基礎,下一篇將用一個任務與機臺的例子來講明一下這些原理在Optaplanner中是如何體現的。

 


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


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

相關文章
相關標籤/搜索