Package rinde.sim.pdptw.generator.tw

Source Code of rinde.sim.pdptw.generator.tw.ProportionateUniformTWGenerator

/**
*
*/
package rinde.sim.pdptw.generator.tw;

import static com.google.common.base.Preconditions.checkArgument;
import static rinde.sim.pdptw.generator.Metrics.travelTime;

import java.math.RoundingMode;

import org.apache.commons.math3.random.RandomGenerator;

import rinde.sim.core.graph.Point;
import rinde.sim.util.TimeWindow;

import com.google.common.collect.ImmutableList;
import com.google.common.math.DoubleMath;

/**
* @author Rinde van Lon <rinde.vanlon@cs.kuleuven.be>
*
*/
public class ProportionateUniformTWGenerator implements TimeWindowGenerator {

  private final Point depotLocation;
  private final long endTime;
  private final long serviceTime;
  private final long minResponseTime;
  private final double vehicleSpeed; // km/h

  /**
   * @param depotLocation The location of the depot.
   * @param endTime
   * @param serviceTime
   * @param minResponseTime
   * @param vehicleSpeed
   */
  public ProportionateUniformTWGenerator(Point depotLocation, long endTime,
      long serviceTime, long minResponseTime, double vehicleSpeed) {
    this.depotLocation = depotLocation;
    this.endTime = endTime;
    this.serviceTime = serviceTime;
    this.minResponseTime = minResponseTime;
    this.vehicleSpeed = vehicleSpeed;
  }

  @Override
  public ImmutableList<TimeWindow> generate(long orderAnnounceTime,
      Point pickup, Point delivery, RandomGenerator rng) {
    checkArgument(
        orderAnnounceTime <= endTime
            - (minResponseTime + travelTime(pickup, delivery, vehicleSpeed)
                + (2 * serviceTime) + travelTime(delivery, depotLocation,
                  vehicleSpeed)), "The orderAnnounceTime is infeasible.");

    // largely inspired on Gendreau et al. method, but changed to ensure
    // feasibility and strictness of all time windows.
    /*
     * GLOBAL
     */
    final long intertt = travelTime(pickup, delivery, vehicleSpeed);
    final long earliestPickupStartTime = orderAnnounceTime + minResponseTime;
    final long latestDeliveryEndTime = endTime
        - (travelTime(delivery, depotLocation, vehicleSpeed) + serviceTime);
    final long latestPickupEndTime = latestDeliveryEndTime
        - (intertt + serviceTime);

    /*
     * PICKUP
     */
    final long middlePickup = earliestPickupStartTime
        + DoubleMath
            .roundToLong((latestPickupEndTime - earliestPickupStartTime) / 2,
                RoundingMode.HALF_EVEN);

    final double betaPickup = uniform(.6, 1.0, rng);

    long pickLeft;
    if (rng.nextDouble() <= betaPickup) {
      pickLeft = earliestPickupStartTime
          + DoubleMath.roundToLong((middlePickup - earliestPickupStartTime)
              * rng.nextDouble(), RoundingMode.HALF_EVEN);
    } else {
      pickLeft = middlePickup
          + DoubleMath.roundToLong((latestPickupEndTime - middlePickup)
              * rng.nextDouble(), RoundingMode.HALF_EVEN);
    }
    final long pickupRemainingTime = latestPickupEndTime - pickLeft;
    final double deltaPickup = uniform(.1, .8, rng);
    long pickRight = pickLeft
        + DoubleMath
            .roundToLong(deltaPickup * pickupRemainingTime,
                RoundingMode.HALF_EVEN);

    /*
     * DELIVERY
     */
    final long earliestDeliveryStartTime = pickLeft + serviceTime + intertt;
    final long middleDelivery = earliestDeliveryStartTime
        + DoubleMath
            .roundToLong(
                (latestDeliveryEndTime - earliestDeliveryStartTime) / 2,
                RoundingMode.HALF_EVEN);

    final double betaDeliver = uniform(.6, 1.0, rng);
    long deliverLeft;
    if (rng.nextDouble() <= betaDeliver) {
      deliverLeft = earliestDeliveryStartTime
          + DoubleMath.roundToLong((middleDelivery - earliestDeliveryStartTime)
              * rng.nextDouble(), RoundingMode.HALF_EVEN);
    } else {
      deliverLeft = middleDelivery
          + DoubleMath.roundToLong((latestDeliveryEndTime - middleDelivery)
              * rng.nextDouble(), RoundingMode.HALF_EVEN);
    }
    final long deliverRemainingTime = latestDeliveryEndTime - deliverLeft;
    final double deltaDeliver = uniform(.3, 1.0, rng);
    final long deliverRight = deliverLeft
        + DoubleMath
            .roundToLong(deltaDeliver * deliverRemainingTime,
                RoundingMode.HALF_EVEN);

    // adapt pickRight to make it strict
    pickRight = Math.min(pickRight, deliverRight - intertt - serviceTime);

    // if (deliverLeft < pickLeft + serviceTime + travelTime(pickup,
    // delivery)) {
    // System.out.println(earliestDeliveryStartTime);
    // System.out.println(latestDeliveryEndTime);
    // System.out.println(middleDelivery);
    // System.out.println(deliverRemainingTime);
    // System.out.println(deliverLeft);
    // }

    return ImmutableList
        .of(new TimeWindow(pickLeft, pickRight), new TimeWindow(deliverLeft,
            deliverRight));
  }

  /**
   * Draws a random number from the uniform distribution U(lb,ub)
   * @param lb
   * @param ub
   * @param rng
   * @return
   */
  static double uniform(double lb, double ub, RandomGenerator rng) {
    return lb + rng.nextDouble() * Math.abs(ub - lb);
  }

}
TOP

Related Classes of rinde.sim.pdptw.generator.tw.ProportionateUniformTWGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.