2015-05-08 2 views
0

Для решения VRP с временным окном я отредактировал решенный файл XML и установил <locked>true</locked> для всех клиентов.OptaPlanner 6.2 - Объекты объектов для объектов с привязкой (VRP)

Я добавил класс SelctionFiler и настроил его, как было предложено. В конце разрешенного файла данных XML я добавил несколько новых неназначенных клиентов.

Я ожидал, что только новые неназначенные клиенты будут оптимизированы и будут вставлены в конце существующих цепей - это не так - цепи сломаны.

Вопрос: Что именно в 6.2 необходимо обрабатывать неподвижными клиентами?

Я думал, что вопрос о джире https://issues.jboss.org/browse/PLANNER-239 должен быть разрешен только для 6.0.1.

Geoffrey писал (а): В 6.2 был сделан ряд улучшений для этого IIRC, но он не решен во всех случаях. Каковы улучшения для VRP с временным окном?

Это вопросы принадлежит к моей проблеме: Can optaplanner solve partly pre-assigned planning entities using Drools rules?

С наилучшими пожеланиями, Миленко

ответ

2

Это конфигурация используется с optaplanner 6.2.0. Чтобы клиенты были заблокированы, фильтры должны были быть реализованы для changeMoveSelector, swapMoveSelector и tailChainSwapMoveSelector в дополнение к CustomerEntitySelectionFilter.

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

Хороший способ решения PLANNER-239 :) Слишком много людей работают в этом вопросе, я постараюсь, чтобы включить его в 6.3. –

+0

Уважаемый grundolf, что означает: ... ЭТО .... CustomerFilterChangeMove .... CustomerNearbyDistanceMeter ... ЭТО .... CustomerFilterSwapMove ... ЭТО ... CustomerFilterTailChainSwapMove Как это классы выглядят как? – mrz

+1

Я добавил классы фильтров. – grudolf