我想使用 Optaplanner 建模和解决的问题是为运动队(这里:足球)创建一个花名册。即:从所有可用的玩家中,根据几个标准选择11个。我正在使用硬/中/软分数来定义有效的解决方案,例如,指定一个守门员必须出现在名单中的硬标准。选择球员的顺序无关紧要。
我目前将此作为我的PlanningEntity
:
@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);
}
}
对于我只使用的分数计算getMembers
,即我不在乎玩家是否被分配到member1
或member2
。求解器主要使用默认配置,并配置为在 100 秒后超时,或者在 10 秒后未实现任何改进。
在一些示例数据集上玩过这个之后,我注意到求解器在大多数情况下都没有找到最佳解决方案(但至少是有效的),例如没有选择最好的守门员(这通常很容易看到,因为有可用的不多,应该选择一个)。
我怀疑这与我建模的方式有关PlanningEntity
:由于所有名册成员都可以单独设置,这似乎使解决方案空间不必要地变大。如前所述,将成员分配到哪个字段并不重要。重要的是(或者更确切地说,谁)被分配,谁没有被分配。所以我基本上需要在满足一些约束和优化标准的同时选择一部分玩家。
List of RosterMember
然而,简单地将s注释为@PlanningVariable
似乎不起作用。我在示例中也找不到类似的情况。我想这应该是一个简单的建模示例?
到目前为止,我能想到的唯一想法是明确地对一些(硬)约束进行建模,例如将范围限制goalkeeper
为恰好一个规划变量,同时将所有其他变量限制为non-goalkeeper
(甚至可能更远)。根据文档(4.3.5.2.3.),应该避免这种情况。
编辑:我只有一个名册实例。我假设不同团队的花名册不相关,并计划按顺序为每个团队运行求解器。
编辑2:按照建议,我现在有了这个而不是以前的Roster
:
@PlanningEntity
public class RosterAssignment
{
@PlanningVariable(valueRangeProviderRefs = {"candidates"})
private RosterMember member;
}
在创建初始未解决的解决方案时,我添加了 11 个空的 RosterAssignments。但是,在创建启动解决方案后,求解器似乎无法改进任何东西:
(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).