1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

enhance TSPLIBReader to read most of the tsp instances

This commit is contained in:
oblonski 2015-02-21 20:28:20 +01:00
parent 16085ab97a
commit a0ac5b9935

View file

@ -19,10 +19,14 @@ package jsprit.instance.reader;
import jsprit.core.problem.Location; import jsprit.core.problem.Location;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.problem.vehicle.VehicleTypeImpl; import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.util.Coordinate; import jsprit.core.util.Coordinate;
import jsprit.core.util.FastVehicleRoutingTransportCostsMatrix;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -33,6 +37,7 @@ public class TSPLIB95Reader {
private VehicleRoutingProblem.Builder vrpBuilder; private VehicleRoutingProblem.Builder vrpBuilder;
public TSPLIB95Reader(VehicleRoutingProblem.Builder vrpBuilder) { public TSPLIB95Reader(VehicleRoutingProblem.Builder vrpBuilder) {
this.vrpBuilder = vrpBuilder; this.vrpBuilder = vrpBuilder;
} }
@ -43,13 +48,18 @@ public class TSPLIB95Reader {
Coordinate[] coords = null; Coordinate[] coords = null;
int[] demands = null; int[] demands = null;
Integer capacity = null; Integer capacity = null;
String edgeType = null;
String edgeWeightFormat = null;
List<Integer> depotIds = new ArrayList<Integer>(); List<Integer> depotIds = new ArrayList<Integer>();
boolean isCoordSection = false; boolean isCoordSection = false;
boolean isDemandSection = false; boolean isDemandSection = false;
boolean isDepotSection = false; boolean isDepotSection = false;
boolean isEdgeWeightSection = false;
List<Double> edgeWeights = new ArrayList<Double>();
int dimensions = 0; int dimensions = 0;
while( ( line = getLine(reader) ) != null ){ while( ( line = getLine(reader) ) != null ){
if(line.startsWith("EOF")){ if(line.startsWith("EOF") || line.contains("EOF")){
break; break;
} }
if(line.startsWith("DIMENSION")){ if(line.startsWith("DIMENSION")){
@ -61,26 +71,53 @@ public class TSPLIB95Reader {
continue; continue;
} }
if(line.startsWith("CAPACITY")){ if(line.startsWith("CAPACITY")){
String[] tokens = line.split(":"); String[] tokens = line.trim().split(":");
capacity = Integer.parseInt(tokens[1].trim()); capacity = Integer.parseInt(tokens[1].trim());
continue; continue;
} }
if(line.startsWith("EDGE_WEIGHT_TYPE")){
String[] tokens = line.trim().split(":");
edgeType = tokens[1].trim();
continue;
}
if(line.startsWith("EDGE_WEIGHT_FORMAT")){
String[] tokens = line.trim().split(":");
edgeWeightFormat = tokens[1].trim();
continue;
}
if(line.startsWith("NODE_COORD_SECTION")){ if(line.startsWith("NODE_COORD_SECTION")){
isCoordSection = true; isCoordSection = true;
isDemandSection = false; isDemandSection = false;
isDepotSection = false; isDepotSection = false;
isEdgeWeightSection = false;
continue; continue;
} }
if(line.startsWith("DEMAND_SECTION")){ if(line.startsWith("DEMAND_SECTION")){
isDemandSection = true; isDemandSection = true;
isCoordSection = false; isCoordSection = false;
isDepotSection = false; isDepotSection = false;
isEdgeWeightSection = false;
continue; continue;
} }
if(line.startsWith("DEPOT_SECTION")){ if(line.startsWith("DEPOT_SECTION")){
isDepotSection = true; isDepotSection = true;
isDemandSection = false; isDemandSection = false;
isCoordSection = false; isCoordSection = false;
isEdgeWeightSection = false;
continue;
}
if(line.startsWith("EDGE_WEIGHT_SECTION")){
isDepotSection = false;
isCoordSection = false;
isDemandSection = false;
isEdgeWeightSection = true;
continue;
}
if(line.startsWith("DISPLAY_DATA_SECTION")){
isDepotSection = false;
isCoordSection = true;
isDemandSection = false;
isEdgeWeightSection = false;
continue; continue;
} }
if(isCoordSection){ if(isCoordSection){
@ -102,10 +139,16 @@ public class TSPLIB95Reader {
else{ else{
depotIds.add(Integer.parseInt(line)); depotIds.add(Integer.parseInt(line));
} }
continue;
}
if(isEdgeWeightSection){
String[] tokens = line.trim().split("\\s+");
for (String s : tokens) edgeWeights.add(Double.parseDouble(s));
continue;
} }
} }
close(reader); close(reader);
vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.INFINITE); vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
for(Integer depotId : depotIds){ for(Integer depotId : depotIds){
VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("typeId").addCapacityDimension(0,capacity).build(); VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("typeId").addCapacityDimension(0,capacity).build();
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("vehicle").setStartLocationId(depotId.toString()) VehicleImpl vehicle = VehicleImpl.Builder.newInstance("vehicle").setStartLocationId(depotId.toString())
@ -119,22 +162,130 @@ public class TSPLIB95Reader {
if(i==0) { if(i==0) {
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("start") VehicleImpl vehicle = VehicleImpl.Builder.newInstance("start")
.setStartLocation(Location.Builder.newInstance().setId(id) .setStartLocation(Location.Builder.newInstance().setId(id)
.setCoordinate(coords[i]).build()) .setCoordinate(coords[i]).setIndex(i).build())
.build(); .build();
vrpBuilder.addVehicle(vehicle); vrpBuilder.addVehicle(vehicle);
continue; continue;
} }
} }
Service service = Service.Builder.newInstance(id) Service service = Service.Builder.newInstance(id)
.setLocation(Location.Builder.newInstance().setId(id).setCoordinate(coords[i]).build()) .setLocation(Location.Builder.newInstance().setId(id)
.setCoordinate(coords[i]).setIndex(i).build())
.addSizeDimension(0, demands[i]).build(); .addSizeDimension(0, demands[i]).build();
vrpBuilder.addJob(service); vrpBuilder.addJob(service);
} }
if(edgeType.equals("GEO")){
List<Location> locations = new ArrayList<Location>();
for(Vehicle v : vrpBuilder.getAddedVehicles()) locations.add(v.getStartLocation());
for(Job j : vrpBuilder.getAddedJobs()) locations.add(((Service)j).getLocation());
vrpBuilder.setRoutingCost(getGEOMatrix(locations));
}
else if(edgeType.equals("EXPLICIT")){
if(edgeWeightFormat.equals("UPPER_ROW")){
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(dimensions,true);
int fromIndex = 0;
int toIndex = 1;
for(int i=0;i<edgeWeights.size();i++){
if(toIndex == dimensions){
fromIndex++;
toIndex = fromIndex + 1;
}
matrixBuilder.addTransportDistance(fromIndex, toIndex, edgeWeights.get(i));
matrixBuilder.addTransportTime(fromIndex,toIndex,edgeWeights.get(i));
toIndex++;
}
vrpBuilder.setRoutingCost(matrixBuilder.build());
}
else if(edgeWeightFormat.equals("UPPER_DIAG_ROW")){
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(dimensions,true);
int fromIndex = 0;
int toIndex = 0;
for(int i=0;i<edgeWeights.size();i++){
if(toIndex == dimensions){
fromIndex++;
toIndex = fromIndex;
}
matrixBuilder.addTransportDistance(fromIndex,toIndex,edgeWeights.get(i));
matrixBuilder.addTransportTime(fromIndex,toIndex,edgeWeights.get(i));
toIndex++;
}
vrpBuilder.setRoutingCost(matrixBuilder.build());
}
else if(edgeWeightFormat.equals("LOWER_DIAG_ROW")){
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(dimensions,true);
int fromIndex = 0;
int toIndex = 0;
for(int i=0;i<edgeWeights.size();i++){
if(toIndex > fromIndex){
fromIndex++;
toIndex = 0;
}
matrixBuilder.addTransportDistance(fromIndex,toIndex,edgeWeights.get(i));
matrixBuilder.addTransportTime(fromIndex,toIndex,edgeWeights.get(i));
toIndex++;
}
vrpBuilder.setRoutingCost(matrixBuilder.build());
}
else if(edgeWeightFormat.equals("FULL_MATRIX")){
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(dimensions,true);
int fromIndex = 0;
int toIndex = 0;
for(int i=0;i<edgeWeights.size();i++){
if(toIndex == dimensions){
fromIndex++;
toIndex = 0;
}
matrixBuilder.addTransportDistance(fromIndex,toIndex,edgeWeights.get(i));
matrixBuilder.addTransportTime(fromIndex,toIndex,edgeWeights.get(i));
toIndex++;
}
vrpBuilder.setRoutingCost(matrixBuilder.build());
}
}
} }
private VehicleRoutingTransportCosts getGEOMatrix(List<Location> noLocations) {
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(noLocations.size(),true);
for(Location i : noLocations){
for(Location j : noLocations){
matrixBuilder.addTransportDistance(i.getIndex(),j.getIndex(),getDistance(i,j));
matrixBuilder.addTransportTime(i.getIndex(), j.getIndex(), getDistance(i, j));
}
}
return matrixBuilder.build();
}
private double getDistance(Location from, Location to) {
double longitude_from = getLongitude(from);
double longitude_to = getLongitude(to);
double latitude_from = getLatitude(from);
double latitude_to = getLatitude(to);
double q1 = Math.cos( longitude_from - longitude_to);
double q2 = Math.cos( latitude_from - latitude_to);
double q3 = Math.cos( latitude_from + latitude_to);
return 6378.388 * Math.acos( .5 * ( ( 1. + q1 ) * q2 - ( 1. - q1 ) * q3 ) ) + 1.;
}
private double getLatitude(Location loc) {
int deg = (int) loc.getCoordinate().getX();
double min = loc.getCoordinate().getX() - deg;
return Math.PI * (deg + 5. * min / 3.) / 180.;
}
private double getLongitude(Location loc) {
int deg = (int) loc.getCoordinate().getY();
double min = loc.getCoordinate().getY() - deg;
return Math.PI * (deg + 5. * min / 3.) / 180.;
}
private void close(BufferedReader reader) { private void close(BufferedReader reader) {
try { try {
reader.close(); reader.close();