You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Optaplanner中双changeMoveSelector笛卡尔积移动配置报错及实现问询

OptaPlanner笛卡尔积移动选择器配置报错及解决方法

问题描述

使用OptaPlanner 8.25版本,尝试通过cartesianProductMoveSelector实现两个规划变量(previousStandstill和startModifier)的笛卡尔积移动,配置代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<solver>
    <solutionClass>com.company.MySolution</solutionClass>
    <entityClass>com.company.Standstill</entityClass>
    <entityClass>com.company.PlanningVisit</entityClass>

    <environmentMode>REPRODUCIBLE</environmentMode>
    <randomSeed>50</randomSeed>
    <environmentMode>FULL_ASSERT</environmentMode>

    <scoreDirectorFactory>
        <constraintProviderClass>com.company.MyConstraintProvider
        </constraintProviderClass>
        <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
    </scoreDirectorFactory>
    <termination>
        <minutesSpentLimit>1800</minutesSpentLimit>
    </termination>

    <customPhase>
        <customPhaseCommandClass>com.company.phase.MySolutionInit</customPhaseCommandClass>
    </customPhase>
    <constructionHeuristic>
        <changeMoveSelector>
        </changeMoveSelector>
        <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
    </constructionHeuristic>

    <localSearch>
        <termination>
            <minutesSpentLimit>300</minutesSpentLimit>
        </termination>
        
        <unionMoveSelector>
            <moveListFactory>
                <variableName>previousStandstill</variableName>
                <moveListFactoryClass>com.company.moves.RideChangeMoveFactory</moveListFactoryClass>
            </moveListFactory>
            
            <cartesianProductMoveSelector>
                <changeMoveSelector>
                    <entitySelector id="cartesianProductEntitySelector"/>
                    <valueSelector>
                        <variableName>previousStandstill</variableName>
                    </valueSelector>
                </changeMoveSelector>
                <changeMoveSelector>
                    <entitySelector mimicSelectorRef="cartesianProductEntitySelector"/>
                    <valueSelector>
                        <variableName>startModifier</variableName>
                    </valueSelector>
                </changeMoveSelector>
            </cartesianProductMoveSelector>
            <swapMoveSelector>
                <variableName>previousStandstill</variableName>
            </swapMoveSelector>
            <subChainChangeMoveSelector>
                <subChainSelector>
                    <valueSelector variableName="previousStandstill">
                    </valueSelector>
                </subChainSelector>
                <valueSelector variableName="previousStandstill">
                </valueSelector>
                <selectReversingMoveToo>true</selectReversingMoveToo>
            </subChainChangeMoveSelector>

            <subChainSwapMoveSelector>
                <subChainSelector>
                    <valueSelector variableName="previousStandstill">
                    </valueSelector>
                </subChainSelector>
                <secondarySubChainSelector>
                    <valueSelector variableName="previousStandstill">
                    </valueSelector>
                </secondarySubChainSelector>
                <selectReversingMoveToo>true</selectReversingMoveToo>
            </subChainSwapMoveSelector>

            <tailChainSwapMoveSelector>
                <valueSelector variableName="previousStandstill">
                </valueSelector>
            </tailChainSwapMoveSelector>
        </unionMoveSelector>
        <acceptor>
            <entityTabuSize>12</entityTabuSize>
        </acceptor>
        <forager>
            <acceptedCountLimit>3000</acceptedCountLimit>
        </forager>
    </localSearch>
</solver>

运行时抛出异常:

Multiple EntityMimicRecorders (usually EntitySelectors) have the same id (cartesianProductEntitySelector).

解决方案

报错原因是手动指定的entitySelector ID在全局范围内重复(可能配置中其他隐式生成的选择器也使用了该ID)。正确的配置方式不需要手动给第一个entitySelector设置ID,OptaPlanner会自动在cartesianProductMoveSelector内部关联两个changeMoveSelector的实体选择器,确保操作的是同一个实体。

修正后的cartesianProductMoveSelector配置如下:

<cartesianProductMoveSelector>
    <changeMoveSelector>
        <!-- 无需手动指定id,OptaPlanner自动处理内部关联 -->
        <valueSelector>
            <variableName>previousStandstill</variableName>
        </valueSelector>
    </changeMoveSelector>
    <changeMoveSelector>
        <!-- 使用mimicSelectorRef="cartesianProductEntitySelector" 自动关联第一个changeMoveSelector的entitySelector -->
        <entitySelector mimicSelectorRef="cartesianProductEntitySelector"/>
        <valueSelector>
            <variableName>startModifier</variableName>
        </valueSelector>
    </changeMoveSelector>
</cartesianProductMoveSelector>

说明

  • 第一个changeMoveSelector中的entitySelector可以省略,OptaPlanner会默认选择所有规划实体;若需指定实体范围,可添加entitySelector但不要手动设置id。
  • 第二个changeMoveSelector的entitySelector通过mimicSelectorRef="cartesianProductEntitySelector"自动关联第一个changeMoveSelector的实体选择器,确保笛卡尔积操作针对同一个实体的两个不同规划变量。

内容的提问来源于stack exchange,提问作者Luka Bradeško

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:55:30