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

时间:2015-05-08 09:38:36

标签: optaplanner

对于时间窗口VRP的解决方案,我编辑了已解决的XML文件,并为所有客户设置了<locked>true</locked>

我添加了一个SelctionFiler类并按照建议配置它。 在解决的xml数据文件的最后,我添加了一些新的未分配客户。

我预计只有新的未分配客户才会被优化,并且会在现有链的末尾插入 - 但事实并非如此 - 链断裂了。

问题:处理不可移动的客户约会所需的6.2究竟是什么?

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

Geoffrey写道:在6.2中,对这个IIRC进行了一些改进,但并未在所有情况下都得到解决。 对时间窗口VRP有哪些改进?

这个问题属于我的问题:Can optaplanner solve partly pre-assigned planning entities using Drools rules?

祝你好运, 米伦科

1 个答案:

答案 0 :(得分:2)

这是我们与optaplanner 6.2.0一起使用的配置。为了保持客户锁定,除了CustomerEntitySelectionFilter之外,还必须为changeMoveSelector,swapMoveSelector和tailChainSwapMoveSelector实现过滤器。

<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;
    }
}