当前位置: 首页 > 知识库问答 >
问题:

OptaPlanner 6.2 -链式实体的不可移动规划实体(VRP)

杨腾
2023-03-14

对于时间窗VRP的解决方案,我编辑了已求解的XML文件并设置了< code >

我添加了一个SectionFiler类,并按照建议进行了配置。在解决的xml数据文件的末尾,我添加了一些新的未分配客户。

我预计只有新的未分配客户才会被优化并插入现有链的末尾 - 事实并非如此 - 链条被破坏了。

问题:6.2中处理不可移动客户预约的具体内容是什么?

我认为jira问题https://issues.jboss.org/browse/PLANNER-239只需要解决6.0.1。

Geoffrey写道:在6.2中,对这个IIRC做了许多改进,但并不是在所有情况下都能解决。时间窗VRP有什么改进?

这个问题属于我的问题:optaplanner能否使用Drools规则解决部分预先分配的规划实体?

最好的问候,米连科

共有1个答案

华鹭洋
2023-03-14

这是我们在optaplanner 6.2.0中使用的配置。为了保持客户锁定到位,除了CustomerEntitySelectionFilter之外,还必须为changeMoveSelector、swapMoveSelect和tailChainSwapMoveSelecter实施过滤器。

<localSearch>
    <unionMoveSelector>
        <changeMoveSelector>
            <entitySelector id="entitySelector1"/>
            <filterClass>...THIS....CustomerFilterChangeMove</filterClass>
            <valueSelector>
                <nearbySelection>
                    <originEntitySelector mimicSelectorRef="entitySelector1"/>
                    <nearbyDistanceMeterClass>....CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                    <parabolicDistributionSizeMaximum>80</parabolicDistributionSizeMaximum>
                </nearbySelection>
            </valueSelector>
        </changeMoveSelector>
        <swapMoveSelector>
            <filterClass>...THIS....CustomerFilterSwapMove</filterClass>
        </swapMoveSelector>
        <tailChainSwapMoveSelector>
            <entitySelector id="entitySelector3"/>
            <filterClass>...THIS...CustomerFilterTailChainSwapMove</filterClass>
            <valueSelector>
                <nearbySelection>
                    <originEntitySelector mimicSelectorRef="entitySelector3"/>
                    <nearbyDistanceMeterClass>....CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                    <parabolicDistributionSizeMaximum>80</parabolicDistributionSizeMaximum>
                </nearbySelection>
            </valueSelector>
            <!--Disabled, doesn't work with tailChain -->
            <!--<selectReversingMoveToo>false</selectReversingMoveToo>-->
        </tailChainSwapMoveSelector>

    </unionMoveSelector>
    <acceptor>
        <lateAcceptanceSize>200</lateAcceptanceSize>
    </acceptor>
    <forager>
        <acceptedCountLimit>1</acceptedCountLimit>
    </forager>
</localSearch>

在EntitySelectionFilter和CustomerFilterTailChainSwapMove(两个链)上检查客户链是否锁定了客户。

这些类别是:

namespace ...THIS...;

public class CustomerFilterChangeMove implements SelectionFilter<ChangeMove> {

    @Override
    public boolean accept(ScoreDirector scoreDirector, ChangeMove changeMove) {
        Customer customer = (Customer) changeMove.getEntity();
        if(customer!=null && customer.isLocked())
            return false;
        //everything is fine
        return true;
    }
}

public class CustomerFilterSwapMove implements SelectionFilter<SwapMove>
{
    @Override
    public boolean accept(ScoreDirector scoreDirector, SwapMove move)
    {
        Customer leftCustomer = (Customer) move.getLeftEntity();
        Customer rightCustomer = (Customer) move.getRightEntity();
        if(leftCustomer!=null && leftCustomer.isLocked())
            return false;
        if(rightCustomer!=null && rightCustomer.isLocked())
            return false;
        return true;
    }
}

public class CustomerFilterTailChainSwapMove implements SelectionFilter<TailChainSwapMove>
{
    /**
     * Chain starting at left entity will be moved to the right. If there's an entity on the right side, it's chain will be moved to the left
     */
    @Override
    public boolean accept(ScoreDirector scoreDirector, TailChainSwapMove move)
    {
        Customer shadow=null;
        Customer leftCustomer = (Customer) move.getLeftEntity();
        Customer rightCustomer = null;
        Vehicle leftVehicle = leftCustomer.getVehicle();
        Vehicle rightVehicle=null;
        if(move.getRightValue() instanceof Customer)
        {
            rightCustomer = (Customer) move.getRightValue();
            rightVehicle = rightCustomer.getVehicle();
        }
        else if(move.getRightValue() instanceof Vehicle)
        {
            rightVehicle = (Vehicle) move.getRightValue();
            rightCustomer = rightVehicle.getNextCustomer();
        }

        shadow=rightCustomer;
        while(shadow!=null)
        {
            if(shadow.isLocked())
                return false;
            shadow=shadow.getNextCustomer();
        }

        shadow=leftCustomer;
        while(shadow!=null)
        {
            if(shadow.isLocked())
                return false;
            shadow=shadow.getNextCustomer();
        }
        return true;
    }
}

public class CustomerEntitySelectionFilter implements SelectionFilter<Customer> {
    @Override
    public boolean accept(ScoreDirector scoreDirector, Customer customer) {
        Customer shadow = customer;
        while(shadow!=null)
        {
            if (shadow.isLocked())
                return false;
            shadow=shadow.getNextCustomer();
        }
        return true;
    }
}
 类似资料:
  • 我正在使用Optaplanner解决一个类似于病人入院调度示例的问题。 我面临两个问题。 首先,当一个规划实体(类似于示例中的bedDesignation)被某人(而不是optaplanner)定位时,该规划实体像其他实体一样被打分。手工放置的计划实体变为不可移动的计划实体,但仍被打分为可移动的计划实体。正因为如此,它打破了一些硬性的限制。 BedDesignationPillarPartSwap

  • 在Optaplanner中,是否可以在移动中(在分数计算之间)将相同的计划变量分配给不同的计划实体?例如,当客户 A 被分配到一个静止状态时,客户 B 也会被分配到同一个静止状态。感谢任何想法或意见。

  • 我正在尝试使用MoveSelectionFilter从计划中排除一些计划整体实例。 然而,即使我拒绝所有的移动,根据调试输出,实例仍然在构建启发式阶段进行初始规划。我使用WEAKEST_FIT启发式,两个自定义的MoveListFactory(目前根本不生成任何移动),并且没有默认的MoveListWorks。 如何阻止OptaPlanner规划这些实体?我看了护士名册示例,如果您提前日期但无法重

  • 我是Optaplanner的新手,我一直在考虑将VRP扩展到一个不同的问题空间。我用的是6.1.0-final。这是一个很难计算的问题,但下面是: 规划实体-装运(扩展Standstill),由运输商(即货船)锚定规划变量-终端(货物目的地),当然隐含运输商(作为VRP示例中的Vehicle这样的影子变量) 在这个路径问题中,货物直接运输到一个终端,然后再运回工厂。即一个运输机服务于一个终点站,然

  • 我正在研究来自OptaPlanner的示例用例。我也找不到任何类似的例子,可以在一个规划实体中求解多个规划变量。例如,在护士名册中,一个轮班的每个可能需要多个分配的。在这种情况下,如何利用planner和编写规则呢?

  • 我有一个VRP路由问题的变体,我想利用Optaplanners(v6.4)ValueRangeProvider特性。然而,在某些情况下,我有点困惑它是如何工作的。我的理解是,如果我选择一组项作为Customer对象的值范围,那么该Customer实例的PreviousStandle可能只在该范围内。 就我而言,我有一些客户可能已经被分配了。我想限制搜索空间,这样分配的行程就不会浪费时间与其他车辆匹