0

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). 
+0

あなたはいくつの「Roster」インスタンスを持っていますか? –

答えて

1

テニスの例を参照してください:開始ソリューションが作成された後、ソルバーが何を改善することができていないようですが Dayそれ自身。

TeamAssignment "day1-spot1"とTeamAssignment "day2-spot3"の間を入れ替えるので、デフォルトの移動(changeMoveとswapMove)ははるかに優れています。

+0

変更案については、編集2を参照してください。ソルバーは今や何の改善も見つけられません - 何が欠けていますか? – geld0r

+0

出力ソリューションを視覚化し、改善するために何が必要かを確認します(可能な場合)。デバッグとトレースのロギングで何が起こっているのかを理解できるようにし、ベンチマークを設定します。その後、pilarChange/SwapMoveSelectorを追加してみてください。 –

+0

ソルバーが最初のソリューションを改善できない理由を本当に理解できませんでしたが、(ナイーブな)スタートソリューションを手作業で構築すると、これが機能することがわかりました。それ以来、実際の改善が行われ、良い解決策に達しています。私は高度な設定を試してみる必要があります。構成XMLファイルを読み込めなかったので(何らかの理由で見つからなかったため)、高度な設定を提供していないようなコードから構成を使用することしかできませんでした。 – geld0r

関連する問題