我是Optaplanner的新手,我试图解决一个非常简单的问题(现在,我最终会添加更多约束)。我的模型如下:我有任务(MarkerNesting
),必须在VirtualMachine
上一次运行一个;目标是将MarkerNesting
s列表分配给VirtualMachine
s,使用所有机器(我们可以认为我们有比机器更多的任务作为第一个近似值)。因此,我希望每个任务都有一个开始和结束日期(作为阴影变量 - 尚未实现)。
我想我必须使用链式变量,VirtualMachine
是锚(通过时间模式链接) - 我是对的?
所以我写了一个program,灵感来自一些例子(tsp和coach和shuttle),有4台机器和4个任务,我希望每台机器在解决时都有一个任务。但是,当它运行时,我得到一些奇怪的结果:并非所有机器都被使用,但最糟糕的是我有重复的MarkerNesting
实例(输出示例):
[VM 1/56861999]~~~>[Nesting(155/2143571436)/[Marker m4/60s]]~~~>[Nesting(816/767511741)/[Marker m2/300s]]~~~>[Nesting(816/418304857)/[Marker m2/300s]]~~~>[Nesting(980/1292472219)/[Marker m1/300s]]~~~>[Nesting(980/1926764753)/[Marker m1/300s]]
[VM 2/1376400422]~~~>[Nesting(155/1815546035)/[Marker m4/60s]]
[VM 3/1619356001]
[VM 4/802771878]~~~>[Nesting(111/548795052)/[Marker m3/180s]]
实例是不同的(读取日志:[Nesting(id/hashcode)]
),但它们具有相同的ID,因此它们最终是相同的实体。如果我理解得很好,Optaplanner会在找到最佳解决方案时克隆解决方案,但我不知道为什么会混合这样的实例。
我的代码有什么问题吗?这是正常的行为吗?
先感谢您!
您没有创建的重复MarkerNesting实例,具有相同的内容,但具有不同的内存地址,因此!=
彼此相同:这意味着默认解决方案克隆中出现错误,这是基于反射。已经有一段时间了,因为那里有人遇到过问题。请参阅有关“规划克隆”的文档部分。链式变量的复杂模型(will be improved)根本没有帮助。
有时一个位置很好的@DeepPlanningClone
修复它,但在这种情况下,它可能也是由于没有被挑选的@InverseRelationShadowVariable
。
在任何情况下,setter方法中的那些system.out
都会产生误导 - 它们既可以通过解决方案克隆器也可以通过移动来实现,因此如果没有解决方案哈希(=内存地址),它们就什么也不说。尝试在最佳解决方案更改事件或BestSolutionRecaller
调用cloneWorkingSolution()
中为原始和克隆执行类似的system.out。
正如所料,我做错了什么:在Schedule
(PlanningSolution
),我有一个VirtualMachine
集合的吸气剂,从另一个领域计算(pools
:每个Pool
持有VirtualMachine
s)。因此,没有setter,解决方案克隆人可能无法正确克隆解决方案(可能因为pools
没有注释为问题事实或计划实体?)。
为了解决这个问题,我删除了Pool
类(不是真的需要),在VirtualMachine
中留下了Schedule
s的集合。
总而言之,在您需要之前不要引入太多类^ _ ^'
我在github上推送了正确版本的代码。