package vroom.trsp.io;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import vroom.common.modeling.dataModel.Depot;
import vroom.common.modeling.dataModel.IVRPInstance;
import vroom.common.modeling.dataModel.IVRPRequest;
import vroom.common.modeling.dataModel.Vehicle;
import vroom.common.modeling.dataModel.attributes.Duration;
import vroom.common.modeling.dataModel.attributes.ITimeWindow;
import vroom.common.modeling.dataModel.attributes.NodeAttributeKey;
import vroom.common.modeling.dataModel.attributes.OpenTimeWindow;
import vroom.common.modeling.dataModel.attributes.RequestAttributeKey;
import vroom.common.modeling.dataModel.attributes.SimpleTimeWindow;
import vroom.common.modeling.dataModel.attributes.VehicleAttributeKey;
import vroom.common.modeling.io.ChristofidesPersistenceHelper;
import vroom.common.modeling.io.IPersistenceHelper;
import vroom.common.utilities.dataModel.ObjectWithIdComparator;
import vroom.trsp.datamodel.TRSPInstance;
import vroom.trsp.datamodel.TRSPRequest;
import vroom.trsp.datamodel.Technician;
import vroom.trsp.datamodel.TechnicianFleet;
import vroom.trsp.util.TRSPLogging;
/**
* <code>ConvertionPersistenceHelper</code>
* <p>
* Creation date: Nov 7, 2011 - 3:01:00 PM
*
* @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a
* href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
* href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
* @version 1.0
*/
public class ConvertionPersistenceHelper implements ITRSPPersistenceHelper {
private final IPersistenceHelper<File> mHelper;
/**
* Creates a new <code>ConvertionPersistenceHelper</code>
*
* @param helper
*/
public ConvertionPersistenceHelper(IPersistenceHelper<File> helper) {
mHelper = helper;
}
/**
* Reads an instance from a flat file
*
* @param file
* the {@link File} containing the instance to be read
* @return a {@link TRSPInstance} containing the instance defined in <code>file</code>
* @throws IOException
*/
@Override
public TRSPInstance readInstance(File file, Object... params) throws Exception {
IVRPInstance vrpIns = mHelper.readInstance(file);
return convertInstance(vrpIns, params);
}
public static TRSPInstance convertInstance(IVRPInstance vrpIns, Object... params) {
boolean cvrptw = params.length == 0 || (Boolean) params[0];
int fleetSize = vrpIns.getFleet().isUnlimited() ? vrpIns.getRequestCount() : vrpIns.getFleet().size();
List<Depot> depots = new ArrayList<Depot>(1 + fleetSize);
int nodeId = 0;
Depot mainDepot = vrpIns.getDepot(0);
ITimeWindow tw = vrpIns.getDepot(0).getAttribute(NodeAttributeKey.TIME_WINDOW);
if (tw == null) {
tw = new OpenTimeWindow();
} else {
tw = new SimpleTimeWindow(tw.startAsDouble(), tw.endAsDouble());
}
mainDepot = new Depot(nodeId++, mainDepot.getLocation());
mainDepot.setAttribute(NodeAttributeKey.TIME_WINDOW, tw);
depots.add(mainDepot);
boolean hasCap = vrpIns.getFleet().getVehicle().getCompartmentCount() > 0;
// CREW
List<Technician> crew = new ArrayList<Technician>(fleetSize);
for (int i = 1; i <= fleetSize; i++) {
Vehicle v = vrpIns.getFleet().getVehicle(i - 1);
Depot home = v.getAttribute(VehicleAttributeKey.DEPOT);
if (home == null) {
home = new Depot(nodeId++, vrpIns.getDepot(0).getLocation());
home.setAttribute(NodeAttributeKey.TIME_WINDOW, mainDepot.getTimeWindow());
} else {
tw = home.getTimeWindow();
home = new Depot(nodeId++, home.getLocation());
if (tw == null) {
tw = new OpenTimeWindow();
} else {
tw = new SimpleTimeWindow(tw.startAsDouble(), tw.endAsDouble());
}
home.setAttribute(NodeAttributeKey.TIME_WINDOW, tw);
}
depots.add(home);
int[] cap = hasCap ? new int[] { (int) vrpIns.getFleet().getVehicle(i - 1).getCapacity() } : new int[0];
Technician t = new Technician(i - 1, i + "", v.getFixedCost(), v.getVariableCost(), v.getSpeed(),
new int[0], new int[0], cap, home);
crew.add(t);
}
TechnicianFleet fleet = new TechnicianFleet(crew, true);
// REQUESTS
List<TRSPRequest> requests = new ArrayList<TRSPRequest>(vrpIns.getRequestCount());
List<IVRPRequest> originalReq = vrpIns.getRequests();
Collections.sort(originalReq, new ObjectWithIdComparator());
if (originalReq.get(0).getID() != 0 && originalReq.get(0).getID() != 1)
throw new IllegalStateException("The first request should have an id of 0 or 1");
for (IVRPRequest r : originalReq) {
tw = r.getAttribute(RequestAttributeKey.TIME_WINDOW);
if (tw == null)
tw = new OpenTimeWindow();
else {
tw = new SimpleTimeWindow(tw.startAsDouble(), tw.endAsDouble());
}
Duration st = r.getAttribute(RequestAttributeKey.SERVICE_TIME);
int servTime = st != null ? (int) st.getDuration() : 0;
int[] dem = hasCap ? new int[] { (int) r.getDemand() } : new int[0];
TRSPRequest req = new TRSPRequest(nodeId++, r.getNode(), new int[0], new int[0], dem, tw, servTime);
req.setAttribute(RequestAttributeKey.RELEASE_DATE, r.getAttribute(RequestAttributeKey.RELEASE_DATE));
requests.add(req);
}
TRSPInstance instance = new TRSPInstance(vrpIns.getName(), fleet, 0, 0, hasCap ? 1 : 0, depots, requests,
cvrptw);
// Roundup distances
instance.getCostDelegate().setPrecision(vrpIns.getCostDelegate().getPrecision(),
vrpIns.getCostDelegate().getRoundingMethod());
return instance;
}
public static void main(String[] args) {
ConvertionPersistenceHelper h = new ConvertionPersistenceHelper(new ChristofidesPersistenceHelper());
try {
TRSPInstance ins = h.readInstance(new File("../Instances/cvrp/christodifes-mingozzi-toth/vrpnc1.txt"));
System.out.println(ins);
} catch (Exception e) {
TRSPLogging.getBaseLogger().exception("ConvertionPersistenceHelper.main", e);
}
}
@Override
public boolean writeInstance(TRSPInstance instance, File file) throws IOException {
throw new UnsupportedOperationException();
}
}