Cheap time scheduling
http://docs.jboss.org/optaplanner/release/latest/optaplanner-docs/html_single/index.html#cheapTimeScheduling
遂にラスト!
タスクをマシンに割り当て、消費電力を最小化します。CloudBalance や MachineReassignment に似てます。
- CheapTimeSolution : @PlanningSolution
- TaskAssignment : @PlanningEntity
- Machine machine : @PlanningVariable
- Integer startPeriod : @PlanningVariable
- Task task
@PlanningVariable は2つ。モデリングはシンプルなんだけど、制約の実装が意外と手強い。このサンプルにはDRLがまだ無く、CheapTimeEasyScoreCalculator と CheapTimeIncrementalScoreCalculator が実装されています。理解するにはまず CheapTimeEasyScoreCalculator を見よう。
期間(Period)単位でリソースの制約や消費電力コストを計算するので、MachinePeriodPart というクラスを導入します。
for (Machine machine : machineList) { List<MachinePeriodPart> machinePeriodList = new ArrayList<MachinePeriodPart>(globalPeriodRangeTo); for (int period = 0; period < globalPeriodRangeTo; period++) { machinePeriodList.add(new MachinePeriodPart(machine, period, resourceListSize)); } machinePeriodListMap.put(machine, machinePeriodList); }
リソースの計算は MachinePeriodPart 側でやります。
public void addTaskAssignment(TaskAssignment taskAssignment) { active = true; Task task = taskAssignment.getTask(); for (int i = 0; i < resourceAvailableList.size(); i++) { int resourceAvailable = resourceAvailableList.get(i); TaskRequirement taskRequirement = task.getTaskRequirementList().get(i); resourceAvailableList.set(i, resourceAvailable - taskRequirement.getResourceUsage()); } }
「休止中は、アイドル状態にしておくか停止/起動するか、安い方を選ぶ」はこのように実装されています。
if (previousStatus != MachinePeriodStatus.OFF) { idleCostMicros += CheapTimeCostCalculator.multiplyTwoMicros(machine.getPowerConsumptionMicros(), periodPowerPrice.getPowerPriceMicros()); if (idleCostMicros > machine.getSpinUpDownCostMicros()) { idleCostMicros = 0L; previousStatus = MachinePeriodStatus.OFF; } else { previousStatus = MachinePeriodStatus.IDLE; } }
そんなに難しそうに見えない?これが CheapTimeIncrementalScoreCalculator ではエライことになります。
ここでは詳細に説明しませんが、insert と retract に応じたスコアのメンテナンスがかなりハードです。
DRLで書けば少なからず楽になるはずです。さてそれは次回。。。