一个MoveSelector的多个ValueSelector

时间:2015-01-22 15:32:06

标签: optaplanner

如何在Optaplanner中为一个移动选择器设置多个值选择器?文档清楚地表明:" MoveSelector通常由EntitySelectors, ValueSelectors 或甚至其他MoveSelectors组成,如果需要可以单独配置",我假设它意味着多个值选择器可以分配给一个移动选择器,这对我来说很有意义,但是在尝试时我得到一个解组错误。

<unionMoveSelector>
        <changeMoveSelector>
            <entitySelector>
                <entityClass>com.rdthree.plenty.domain.activity.Activity</entityClass>
            </entitySelector>
            <valueSelector>
                <variableName>startTime</variableName>
            </valueSelector>
            <valueSelector>
                <variableName>endTime</variableName>
            </valueSelector> <--this is the line where the error stems from
            <filterClass>myclass(don't want to say the name of it)</filterClass>
        </changeMoveSelector>
    </unionMoveSelector> 

错误:

java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (activitySolverConfig.xml) fails.

原因:

Caused by: com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field valueSelectorConfig
---- Debugging information ----
field               : valueSelectorConfig
class               : org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig
required-type       : org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number         : 36
class[1]            : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig
class[2]            : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
class[3]            : org.optaplanner.core.config.solver.SolverConfig
version             : 1.4.7
-------------------------------

我没有复制整个错误文本,但我可以向您保证,它指的是我有两个值选择器。

1 个答案:

答案 0 :(得分:0)

changeMoveSelector目前只能拥有1个valueSelector

我认为你想要一个笛卡尔积(或者你可以使用unionMoveSelector)而不是那些changeMoveSelector,所以:

  <cartesianProductMoveSelector>
    <changeMoveSelector>
      <entitySelector id="cartesianProductEntitySelector"/>>
      <valueSelector>
        <variableName>startTime</variableName>
      </valueSelector>
    </changeMoveSelector>
    <changeMoveSelector>
      <entitySelector mimicSelectorRef="cartesianProductEntitySelector"/>
      <valueSelector>
        <variableName>endTime</variableName>
      </valueSelector>
    </changeMoveSelector>
  </cartesianProductMoveSelector>

这意味着单个移动(CompositeMove)会更改1(和相同)实体的startTime和endTime。有关详情,请参阅有关cartesianProductMoveSelector的文档部分和模拟选择。

请注意,cartesianProductMoveSelector可以嵌套在unionMoveSelector中,以便将CompositeMove与其他动作合并。