Search code examples
javadroolsoptaplanner

OptaPlanner Vehicle Routing - Time Window for vehicles


First of all, thanks to the ones who are invoved on this great library.

My constraints are:

  • I have customers which have ready and due times.
  • And vehicles which also have ready and due times.

I am not experienced in Java and I try to use OptaPlanner by sending and recieving xml using the example project provided. For the customers time window, I have used "VrmTimeWindowedCustomer" and there was no problem with that. And for the vehicles time window constraint, I tried to use "VrpTimeWindowedDepot"

What was in my mind is: When a depot is available (ReadyTime) the vehicle start to work from that depot and go to the customers. However in my tries OptaPlanner did not gave the results I was expecting:

<depotList id="139">
    <VrpTimeWindowedDepot id="140">
      <id>1</id>
      <location class="VrpRoadLocation" reference="3"/>
      <readyTime>540000</readyTime>
      <dueTime>1020000</dueTime>
    </VrpTimeWindowedDepot>
    <VrpTimeWindowedDepot id="141">
      <id>2</id>
      <location class="VrpRoadLocation" reference="5"/>
      <readyTime>540000</readyTime>
      <dueTime>1020000</dueTime>
    </VrpTimeWindowedDepot>
  </depotList>

Result is:

<VrpVehicle id="143">
      <id>1</id>
      <capacity>100001002</capacity>
      <depot class="VrpTimeWindowedDepot" reference="140"/>
      <nextCustomer class="VrpTimeWindowedCustomer" id="144">
        <id>42</id>
        <location class="VrpRoadLocation" reference="85"/>
        <demand>206</demand>
        <previousStandstill class="VrpVehicle" reference="143"/>
        <nextCustomer class="VrpTimeWindowedCustomer" id="146">
           ...
        <vehicle reference="143"/>
        <readyTime>0</readyTime>
        <dueTime>1440000</dueTime>
        <serviceDuration>12000</serviceDuration>
        <arrivalTime>22137</arrivalTime>
      </nextCustomer>
      <vehicle reference="143"/>
      <readyTime>0</readyTime>
      <dueTime>1440000</dueTime>
      <serviceDuration>12000</serviceDuration>
      <arrivalTime>8527</arrivalTime>
    </nextCustomer>
  </VrpVehicle>

ArrivalTime on the customers are OK for the customers, but smaller than the Depot ReadyTime of that vehicle.

I couldn't find out what am I doing wrong here. I have read Optaplanner - availability of Vehicles and OptaPlanner documents; but could not understand and figure out what to do for my situation.

I also couldn't understand the syntax of a drl file and couldn't find a document that explains how to write it.

Edit - Another Question to Geoffrey De Smet

Geoffrey De Smet, thank you very much for your fast respose, it is very appreciated. I have tried your changes. The arrival times are now OK according to the Depot's ReadyTime. However there might be another problem about the Depot's DueTime:

   <VrpTimeWindowedDepot id="144">
      <id>3</id>
      <location class="VrpRoadLocation" reference="7"/>
      <readyTime>540000</readyTime>
      <dueTime>1020000</dueTime>
    </VrpTimeWindowedDepot>

The last customer to be visited for a vehicle from this depot is:

<nextCustomer class="VrpTimeWindowedCustomer" id="183">
  <id>36</id>
  <location class="VrpRoadLocation" reference="73"/>
  <demand>187</demand>
  <previousStandstill class="VrpTimeWindowedCustomer" reference="182"/>
  <vehicle reference="146"/>
  <readyTime>0</readyTime>
  <dueTime>1440000</dueTime>
  <serviceDuration>10000</serviceDuration>
  <arrivalTime>1082091</arrivalTime>
</nextCustomer>

Shouldn't the arrival time be less than 1020000? (There are 3 vehicles on 3 depots. In the solution only 2 vehicles were involved, both having such finish times.)

I have tried to add this as a comment to the PLANNER-680 JIRA issue, but I was unable to sing up and login. I hope the this edit is ok according to the Stackoverflow's format.


Solution

  • I remember doing a hack in the example related to due time of a vehicle/depot in the txt importer (see this line). That hasn't been cleaned up yet, so the XML can punch through it. But that's not your issue here.

    It seems like there is a bug on this line in ArrivalTimeUpdatingVariableListener:

        protected void updateArrivalTime(ScoreDirector scoreDirector, TimeWindowedCustomer sourceCustomer) {
            Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
            Long departureTime = (previousStandstill instanceof TimeWindowedCustomer)
    ? ((TimeWindowedCustomer) previousStandstill).getDepartureTime() : null;
    

    that doesn't take vehicle.getDepot().getReadyTime() into account.