2016-08-26 26 views
0

我們剛剛開始使用Optaplanner來開展項目。我們有一個非常簡單的解決方案設置如下:Optaplanner何時以及如何評估規則?

Job -> PlanningEntity, PlanningVariable=Resource from resourcesList 
Resource -> POJO 
Solution 
    - List<Job> PlanningEntityCollectionProperty 
    - List<Resource> ProblemFactCollectionProperty, resourcesList 

我們已經設置了一些測試規則。第一條規則是簡單地說,不具有三個以上喬布斯資源:

rule "noMoreThan3JobsPerResource" 
    when 
     $resource : Resource() 
     $totalJobsOnResource : Number(intValue > 3) from accumulate (
      Job(
       resource == $resource, 
       $count : 1), 
       sum($count) 
      ) 
    then 
     scoreHolder.addHardConstraintMatch(kcontext, 3 - $totalJobsOnResource.intValue()); 
end 

我們要明白什麼是如何以及何時Drools的規則進行評估。舉例來說,如果我們添加這兩個規則:

rule "logWhenResource" 
    when 
     $resource: Resource() 
    then 
     System.out.println("RESOURCE encountered"); 
end 
rule "logWhenJob" 
    when 
     $job : Job() 
    then 
     System.out.println("JOB encountered"); 
end 

我們得到「作業遇到」在日誌中,但從來沒有「資源遭遇」。然而,我們的第一條規則有$ resource:Resource()在什麼時候? optaplanner是否在放置工作時觸發規則(在我們的示例中)?我們爲什麼logWhenResource不火只是有點不清楚,但確實noMoreThan3JobsPerResource(當它們都試圖與「匹配」資源對象?是資源作業已被移動到?

提前感謝

資源

回答

0

打開TRACE記錄。它激發所有規則(因爲上次已經改變,因爲它是增量計算)每有一個舉動線在該日誌的時間。

+0

嗨傑弗裏 我認爲我的問題是更高的水平,什麼時候評估規則?是否每次考慮移動?在上面的例子中,如果我們有2個資源和10個工作,每次考慮移動時規則1會觸發兩次,規則2會觸發10次?或者規則中的模式只選擇已移動的對象?例如,如果工作7被移動,將會規則2點燃一次(僅匹配工作2)還是10次(匹配所有工作)? – user3707

+0

試着將System.out放在'then'一側。但打開跟蹤日誌記錄清楚地看到每個fireAllRules()也出現在哪裏。它會進行增量計算,所以它只會觸發該增量。 –

1

在IRC上的一些討論之後,(和來自傑弗裏的很多病人的幫助!),希望以下將作爲啊elper爲其他人。

1.打開登錄

首先,確保你打開跟蹤日誌記錄Optaplanner包(也許把它關掉Drools的)。這真的有幫助,因爲它顯示剛好當optaplanner觸發分數計算。它也顯示了考生分數計算:

Move index (0), score (-3init/-2hard/0medium/0soft), move (Job 7 {null -> Resource 1}). 

除最後一步選擇:

CH step (6), time spent (110), score (-3init/-2hard/0medium/0soft), selected move count (2), picked move (Job 7 {null -> Resource 1}). 

您也可以登錄你的「那麼」規則的一部分,通過執行類似:

LoggerFactory.getLogger("org.optaplanner").debug("...); 

這確保它以正確的順序登錄,因爲Logging vs println可以是異步的,事情可能不是按時間升序排列的。

2.瞭解當Optaplanner計算分數,當它不

這是optaplanner的「事件循環」的一個非常有用的總結:

doMove() 
fireAllRules() 
undoMove() 
doMove() 
fireAllRules() 
undoMove() 
doStep() 
doMove() 
fireAllRules() 
undoMove() ... 

等一件事這很有趣,因爲我們在IRC上的聊天如下:

「請注意,它不會在撤消移動或doStep()後執行fireAllRules(),因爲它可以預測分數。整齊。

3 FULL_ASSERT

要檢查您是否破壞了比分,打開FULL_ASSERT。

<environmentMode>FULL_ASSERT</environmentMode> 

這對確定您的分數計算是否正確(我們的不是)非常有用。