package vroom.common.modeling.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import vroom.common.modeling.dataModel.Depot;
import vroom.common.modeling.dataModel.DiscreteTimeStamp;
import vroom.common.modeling.dataModel.DynamicInstance;
import vroom.common.modeling.dataModel.Fleet;
import vroom.common.modeling.dataModel.Node;
import vroom.common.modeling.dataModel.Request;
import vroom.common.modeling.dataModel.Vehicle;
import vroom.common.modeling.dataModel.VehicleRoutingProblemDefinition;
import vroom.common.modeling.dataModel.attributes.DefaultReleaseDate;
import vroom.common.modeling.dataModel.attributes.DeterministicDemand;
import vroom.common.modeling.dataModel.attributes.ILocation;
import vroom.common.modeling.dataModel.attributes.PointLocation;
import vroom.common.modeling.dataModel.attributes.RequestAttributeKey;
/**
* The Class VRPInstanceBuilder is a utility class to build random VRP instances
*/
public class VRPInstanceBuilder {
/** The rnd. */
private static Random rnd = new Random();
/** The Constant CENTRAL_DEPOT. */
private static final Depot CENTRAL_DEPOT = new Depot(0, "CentralDepot", new PointLocation(0, 0));
private static final Depot CIRCLE_DEPOT = new Depot(0, "CircleDepot", new PointLocation(1, 0));
/**
* New simple dynamic instance.
*
* @param nRequests
* the n requests
* @param vehicleCap
* the vehicle cap
* @param maxDem
* the max dem
* @param horizon
* the horizon
* @param seed
* the seed
* @param randomPoints
* <code>true</code> if the nodes are to be randomly distributed
* @return a instance with a fleet composed of a single vehicle of capacity , with requests associated with
* different nodes, each with a single random demand between 1 and . The instance has a reference to a
* {@link EuclidianDistance} for the calulation of costs
*/
public static DynamicInstance newSimpleDynamicInstance(int nRequests, int vehicleCap, int maxDem, int horizon,
long seed, boolean randomPoints) {
Fleet<?> fleet = Fleet.newHomogenousFleet(1, new Vehicle(0, "DefaultVehicle", vehicleCap));
List<Depot> depots = new ArrayList<Depot>();
if (randomPoints) {
depots.add(CENTRAL_DEPOT);
} else {
depots.add(CIRCLE_DEPOT);
}
DynamicInstance instance = new DynamicInstance("SimpleInstance_" + nRequests, 0, fleet, depots,
VehicleRoutingProblemDefinition.DynVRP, new EuclidianDistance());
for (int n = 1; n <= nRequests; n++) {
instance.addRequest(generateRequest(maxDem, horizon, true, n, nRequests));
}
return instance;
}
/**
* Rnd location.
*
* @param rnd
* the rnd
* @return a random location with coordinates between -100 and 100
*/
public static ILocation rndLocation(Random rnd) {
return new PointLocation((0.5 - rnd.nextDouble()) * 200, (0.5 - rnd.nextDouble()) * 200);
}
/**
* Generate request.
*
* @param maxDem
* the max dem
* @param horizon
* the horizon
* @param rndPoint
* @param id
* @param nRequests
* @return the request
*/
public static Request generateRequest(int maxDem, int horizon, boolean rndPoint, int id, int nRequests) {
ILocation loc;
if (rndPoint) {
loc = rndLocation(rnd);
} else {
loc = new PointLocation(Math.cos(2 * Math.PI * id / nRequests), Math.sin(2 * Math.PI * id / nRequests));
}
Request r = new Request(id, new Node(id, "Node" + (id), loc));
r.setAttribute(RequestAttributeKey.DEMAND, new DeterministicDemand(1 + rnd.nextInt(maxDem)));
r.setAttribute(RequestAttributeKey.RELEASE_DATE,
new DefaultReleaseDate(new DiscreteTimeStamp(rnd.nextInt(horizon))));
return r;
}
}