tokobayashiの日記 このページをアンテナに追加 RSSフィード

2014-12-17 OptaPlanner examples その1

[OptaPlanner]OptaPlanner examples その1  [OptaPlanner]OptaPlanner examples その1を含むブックマーク

さて、OptaPlanner トレーニングhttp://d.hatena.ne.jp/tokobayashi/20141027)をやったことで、自分モデリング能力の無さを痛感しました。これを克服するにはまず既存のサンプルのモデルをよく読むところから始めねばならない。

N Queens

これはもうやった(http://d.hatena.ne.jp/tokobayashi/20141004)。。。と思った?モデリングはちゃんと見てなかったー!というわけでここから始めます

  • NQueens : @PlanningSolution
    • List<Row> getRowList() : @ValueRangeProvider(id = "rowRange")
    • List<Queen> getQueenList() : @PlanningEntityCollectionProperty
  • Queen : @PlanningEntity
    • Row getRow() : @PlanningVariable(valueRangeProviderRefs = {"rowRange"}, strengthWeightFactoryClass = RowStrengthWeightFactory.class)
    • Column はただのフィールド

単純な値でも、クラスにした方が便利なのだろうか。

クイーンエンティティで、行が変数

NQueensGenerator.createNQueens() で初期 NQueens が作成される。RowとColumnもN個ずつインスタンス化する。ちょっと気持ち悪い。初期 Queen は Column だけ持っていて固定し、Row は最初 null。@ValueRangeProvider が選択可能な値を提供する。つまり、ConstructionHeuristic/LocalSearchのとき、NQueens.getRowList() の範囲から選んで、Queen.row にセットしていく。N Queens は ROW を変えるだけなので単純だ。といっても問題を与えられてすぐこのようにモデリングできるか?修行必要です。

余談

TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (0), score (-2), accepted (true), move (col0@row1 => row0).

のようにきれいなログが出るので、カスタムMoveクラスを使っているのかな?と思ったけど、org.optaplanner.examples.nqueens.solver.move.RowChangeMove は使われていなかった。デフォルトで使う org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove は

    public String toString() {
        return entity + " => " + toPlanningValue;
    }

なので、@PlanningEntity と @PlanningVariable の toString() を分かりやすくしておけばいい。

Cloud Balancing

Cloud Balancing のモデリングはここを見るべきですね。 http://docs.jboss.org/drools/release/6.1.0.Final/optaplanner-docs/html_single/index.html#d0e653

  • CloudBalance : @PlanningSolution
    • List<CloudComputer> getComputerList() : @ValueRangeProvider(id = "computerRange")
    • List<CloudProcess> getProcessList() : @PlanningEntityCollectionProperty
  • CloudProcess : @PlanningEntity
    • CloudComputer getComputer() : @PlanningVariable(valueRangeProviderRefs = {"computerRange"}, strengthComparatorClass = CloudComputerStrengthComparator.class)

プロセスエンティティで、コンピュータ変数

やっぱどっちをエンティティにしてどっちを変数にするか、っていうのが最初の関門か。これは逆にしても出来るんじゃないか?やってみた。。。

うはあ、@PlanningVariable が List になるときのやり方がわからねえ。後のサンプルに出て来てやり方を学べるはず。ここはスルーだ!

現時点の知識:1-N の関係の時は N側をエンティティにすると、@PlanningVariableを単一変数にできるので簡単ってことかなあ

トラックバック - http://d.hatena.ne.jp/tokobayashi/20141217

2014-12-08 jBPM5 Developer Guide 読書会まとめ

[jBPM] jBPM5 Developer Guide 読書会まとめ  [jBPM] jBPM5 Developer Guide 読書会まとめを含むブックマーク

いやはや、今年の2月に終わった読書会のまとめを今頃書きます

まあ感想としては「疲れた!」でした。いままで読書会経験は無く(参加としても、ホストとしても)、手探りでやってました。まずホストとして1ヶ月に1回、準備やら何やらするのが、ルーチンワークでも結構しんどいんですよね。もう少し間隔を空けたい気持ちもあり、しかしそうするといつまで経っても終わらないっていう問題もあり(jBPM6だって出たし)。

次に英語なので結構メンバーに負荷がかかっている感がありました。もちろん英語勉強するというモチベーションもあるわけですが、事前にちゃんと読んでいないと、読書会本番でいまいち参加しきれない感じですね。以前Java読書会ポリシーで「事前準備不要」というのを聞いたんですが、英語本だと厳しい。。。

良かった点はやはり新しい人との出会いです。まあよく知っているひとも多かったわけですが。そうだ!結局みんなで飲みに行ってなかった!これは失策最終回で飲みに行くようにスケジュールすべきでした。読書会内でも、もっとアットホームな感じで雑談できるとよかったかもしれません。飲みながらとかどうか。

実業務に使っているひとの話が聞けるのもいいですね。実業務に使っていなくても、異るバックグラウンドのひとだと、違う見方が得られて新鮮でした。

アウトプットとしては、以下のwikiに各担当がかなりの量、要約や直訳、感想等を書いています

https://github.com/tkobayas/jbpm5study-ja/wiki

ただ、読書会時に議論したことなどは残ってないんですよねー。議事録を書くのも負担になるし、難しいところです。

KPTは頑張りました。ネタ切れ感ありつつも毎回KPT出せたし、読書会改善/ドライブするには良かったと思います

https://groups.google.com/forum/#!forum/jbpm5-developer-guide-study

さて、jBPM6 Developer Guide がもう出ています。前作より読みやすくなっており、お薦めです。

https://www.packtpub.com/networking-and-servers/jbpm-6-developer-guide

私はこの本に Reviewer として参加して、十分読んじゃったので読書会はやらないですが、さてそろそろ Japan JBoss ユーザグループでなんか発表しようかな。。。

トラックバック - http://d.hatena.ne.jp/tokobayashi/20141208

2014-10-27 OptaPlanner トレーニング

[OptaPlanner]OptaPlanner トレーニング  [OptaPlanner]OptaPlanner トレーニングを含むブックマーク

http://www.optaplanner.org/learn/training.html から optaplanner-training-6.2.0.CR1-training-2.zipダウンロードし、instructions/training.html を開いてみよう。まだ Lab 201 までしか作られていないが、手を動かすとっかかりにはとてもよさそう。

詳しく書こうと思ったけど、よくできてるので興趣を削がないよう、概要だけ書くことにします

Lab 101 : No more than 4 processes per computer

CloudBalancing により、プロセスコンピューターに配分していますお客様からもうひとつ要望がありました。「同じコンピューターに、あんまりたくさんプロセスをのっけないでください」

課題:よし、「4つより多くのプロセスを、1つのコンピューターに割当てない」というhard制約を追加しよう。

僕の場合: モロに score trap の pitfall にひっかかりました。フフフ。

Lab 102 : No process should hog half the CPU power

お客様要望ひとつプロセスCPUの半分より多くを食わないようにして(CPUが少ないコンピューター例外)」

課題

1. ひとつプロセスCPUの半分より多くを食うことを「Hog」と呼ぶ。(半分ちょうどはOK)

-> 6 CPU 以下のコンピュータ例外とする

2. 新規hard制約「プロセスによるコンピューターの Hog は許さない」

3. Hog についてのロジックJava実装すること

-> 制約自体はDRLに実装する

僕の場合: 解けたけど、evalでやったせいで、 score trap を回避できてませんでした。無念。

Lab 103 : Distribute network bandwidth fairly

お客様要望コンピューターはもう買っちゃったんで、あるやつ使ってね。なので値段は気にしなくていいよ」「コンピュータネットワーク帯域は全部同じ」「ネットワークは均等に使うようにしてね」

課題

1. hard制約「requiredNetworkBandwidthTotal」を削除

2. soft制約「computerCost」を削除

3. 新規soft制約「コンピューター毎のネットワーク帯域は可能な限り均等にする」

僕の場合: ドキュメントの「Fairness score constraints」を読んでも、単純にsoft制約の点数の足し算にすることになかなか気づけなかった。結構慣れが必要ですなあ。

Lab 201 : Tennis friends

7つのチームがテニスコート試合をします。18週あって、1週につき、4チームがコートを使います。各チームには「行けない日」があります。できるだけ均等にコートを使わせてあげたいです。チームの対戦相手も均等にあたるようにします。。。詳しくは原文で読んだ方がいいでしょう。

で、この問題モデル化します。とても重要トレーニングですね。絶対に Tennis example のドキュメントコードを見ないように!

初めてのひとにはメチャメチャ難しいかもしれません。でもできるだけ自分でよく考えて、自分なりの回答を書いた上で、正解を見て、「ああー」となりましょう。ああー

2014-10-24 REHV備忘録 このエントリーを含むブックマーク

トラックバック - http://d.hatena.ne.jp/tokobayashi/20141024

2014-10-18 OptaPlanner N queens を考える その3

[OptaPlanner]OptaPlanner N queens を考える その3  [OptaPlanner]OptaPlanner N queens を考える その3を含むブックマーク

中身を覗いてみよう編だ。

まず logback.xmlクラス名を出しておこう。

<pattern>%d [%t] %-5p [%c] %m%n</pattern>

するとキーポイントになるクラスが出てくるかなー。

TRACE [org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor]     Model annotations parsed for Solution NQueens:
TRACE [org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor]         Entity Queen:
TRACE [org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor]             Variable row (genuine)
INFO  [org.optaplanner.examples.nqueens.persistence.NQueensGenerator] NQueens 4 has 4 queens with a search space of 256.
INFO  [org.optaplanner.core.impl.solver.DefaultSolver] Solving started: time spent (55), best score (uninitialized/0), random (JDK with seed 0).
TRACE [org.optaplanner.core.impl.heuristic.selector.entity.decorator.SortingEntitySelector]     Created cachedEntityList with size (4) in entitySelector(Sorting(FromSolutionEntitySelector(Queen))).
TRACE [org.optaplanner.core.impl.heuristic.selector.entity.decorator.SortingEntitySelector]     Sorted cachedEntityList with size (4) in entitySelector(Sorting(FromSolutionEntitySelector(Queen))).
TRACE [org.optaplanner.core.impl.constructionheuristic.decider.ConstructionHeuristicDecider]         Move index (0), score (0), move (col2@null => row0).
DEBUG [org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase]     CH step (0), time spent (82), score (0), selected move count (1), picked move (col2@null => row0).
...
INFO  [org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase] Construction Heuristic phase (0) ended: step total (4), time spent (111), best score (-1).
TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (0), score (-2), accepted (true), move (col0@row1 => row0).
TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (1) not doable, ignoring move (col0@row1 => row1).
TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (2), score (-2), accepted (true), move (col0@row1 => row2).
TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (3), score (-2), accepted (true), move (col0@row1 => row3).
TRACE [org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider]         Move index (4), score (-2), accepted (true), move (col1@row2 => row0).
...
DEBUG [org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase]     LS step (0), time spent (128), score (-1),     best score (-1), accepted/selected move count (12/12), picked move (col1@row2 => row3).
...
INFO  [org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase] Local Search phase (1) ended: step total (2), time spent (138), best score (0).
INFO  [org.optaplanner.core.impl.solver.DefaultSolver] Solving ended: time spent (140), best score (0), average calculate count per second (278).

で、ログを出力しているところらへんにブレークポイントを張って、デバッガでうろうろする。

DefaultSolver

nqueensSolverConfig.xml を元に SolverFactory からボコっと作られるのが DefaultSolver。これが phaseList を保持し、各 Phase を実行する。

DefaultConstructionHeuristicPhase

ConstructionHeuristicPhase を管理する。solveメソッド内で、Step のループを行う。ループは entityPlacer から受け取る Placement 毎に 1 Step となる。

ConstructionHeuristicDecider

各 Step 内で、placement から供給される Move の中からつの Move を決定する。ConstructionHeuristicMoveScope が Moveラッパーとして役立っているようだ。

DefaultLocalSearchPhase

LocalSearchPhase を管理する。solveメソッド内で、Step のループを行う。ループは Phase が terminate されるまで続ける。

LocalSearchDecider

moveSelector, acceptor, forager を従えた重要プレイヤーだ。各 Step 内で、moveSelector から供給される Move の中からつの Move を決定する。processMoveメソッドで、acceptor がその Moveaccept するか判定する。LocalSearchMoveScope が Moveラッパーとして役立っているようだ。

PhaseLifecycleListener

多くのクラスが PhaseLifecycleListener を implements しており、phaseStarted/phaseEnded, stepStarted/stepEnded のライフサイクルに応じて、整然と処理を実行している。

DroolsScoreDirector

ConstructionHeuristicDecider.processMove() / LocalSearchDecider.processMove() -> DefaultSolverScope.calculateScore() -> DroolsScoreDirector.calculateScore() の流れで呼ばれ、DRL を元にスコア計算する。これは Drools じゃなくてもよい。例えば EasyScoreCalculator を implements し、スコア計算方法Java実装することもできる。N Queen には NQueensEasyScoreCalculator が既にあるので、nqueensSolverConfig.xml指定すれば使える。

トラックバック - http://d.hatena.ne.jp/tokobayashi/20141018