Optaplannerを使用してモデル化して解決したい問題は、スポーツチーム(ここではサッカー)のための名簿を作成することです。つまり、利用可能なすべてのプレーヤーから、いくつかの基準に従って11を選択します。私は、ハード/中/ソフトスコアを使用して、有効な解決策を定義しています。正確に1人のゴールキーパーがロスタに存在しなければならないという厳しい基準。選手が選出される順番は関係ありません。モデリング:サブセットの選択を効率的にモデル化
私は現在、私のPlanningEntity
としてこれを持っている:私はgetMembers
使用スコア計算のために
@PlanningEntity
public class Roster
{
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member1;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member2;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member3;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member4;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member5;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member6;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member7;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member8;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member9;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member10;
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member11;
public List<RosterMember> getMembers()
{
return Lists.newArrayList(member1, member2, member3, member4, member5, member6, member7, member8, member9, member10, member11);
}
}
、すなわちプレイヤーがmember1
またはmember2
に割り当てられている場合、私は気にしません。 ソルバーはほとんどがデフォルト設定を使用しており、100秒後にタイムアウトするように、または10秒後に改善が得られないように設定されています。
いくつかのサンプルデータセットでこの問題を解消した後、ほとんどの場合、ソルバーが最適解を見つけられないことがわかりました。最高のゴールキーパーは選択されていません(これは通常、利用可能なものが少なく、正確に1つを選択する必要があるため、見やすくなります)。
これは私がモデル化した方法と関係があると思われます。PlanningEntity
:すべてのロスターメンバーを個別に設定できるため、ソリューションスペースが不必要に大きくなるようです。前述したように、メンバーがどのフィールドに割り当てられているかは重要ではありません。それが重要なのは、(あるいはむしろ)誰が割り当てられ、誰が割り当てられていないかだけです。ですから、基本的にいくつかの制約と最適化基準を満たしながら、プレイヤーのサブセットを選択する必要があります。
List of RosterMember
を単に@PlanningVariable
と注釈するだけでは機能しないようです。私は例でも同様の状況を見つけることができませんでした。 これはむしろ単純なモデリングの例であるべきでしょうか?
私がこれまで思いつくことができる唯一のアイデアは、(ハード)制約のいくつかを明示的にモデリングすることです。プランニング変数のうちの1つだけを範囲としてgoalkeeper
に制限し、他のすべての変数はnon-goalkeeper
(またはそれ以上)に制限します。ドキュメント(4.3.5.2.3。)によると、これはむしろ避けるべきです。
編集:私は1つのロスターインスタンスしか持っていません。私は、異なるチームのロースターは関係なく、各チームのソルバーを順番に実行することを計画していると仮定します。
編集2:の提案に続いて、私は今、代わりに前のRoster
の本を持っている:最初の未解決のソリューションを作成する場合
@PlanningEntity
public class RosterAssignment
{
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member;
}
、私は11の空RosterAssignmentsを追加します。各Day
例えば、4つのTeamAssignment
インスタンスではなく、上の4つの計画変数がある:
(DefaultConstructionHeuristicPhase.java:158) Construction Heuristic phase (0) ended: step total (11), time spent (111), best score (-1hard/-2medium/1275soft).
(DefaultLocalSearchPhase.java:152) Local Search phase (1) ended: step total (375104), time spent (10111), best score (-1hard/-2medium/1275soft).
(DefaultSolver.java:238) Solving ended: time spent (10129), best score (-1hard/-2medium/1275soft), average calculate count per second (75545), environment mode (REPRODUCIBLE).
あなたはいくつの「Roster」インスタンスを持っていますか? –