mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
prepare release 1.5
This commit is contained in:
parent
9938a6a123
commit
1458b03be7
13 changed files with 253 additions and 1502 deletions
|
|
@ -1,182 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
package jsprit.core.problem.io;
|
||||
|
||||
/**
|
||||
* Created by stefan on 03.11.14.
|
||||
*/
|
||||
public class JsonConstants {
|
||||
|
||||
public static final String PROBLEM = "vrp";
|
||||
|
||||
public static final String SOLUTION = "solution";
|
||||
|
||||
public static final String SERVICES = "services";
|
||||
|
||||
public static final String FLEET = "fleet_size";
|
||||
|
||||
public static final String VEHICLES = "vehicles";
|
||||
|
||||
public static final String VEHICLE_TYPES = "vehicle_types";
|
||||
|
||||
public static final String META = "meta-info";
|
||||
|
||||
public static class MetaInfo {
|
||||
|
||||
public static final String DISTANCE_UNIT = "distance-unit";
|
||||
|
||||
public static final String TIME_UNIT = "time-unit";
|
||||
}
|
||||
|
||||
public static class Solution {
|
||||
|
||||
public static final String COSTS = "costs";
|
||||
|
||||
public static final String DISTANCE = "distance";
|
||||
|
||||
public static final String TIME = "time";
|
||||
|
||||
public static final String ROUTES = "routes";
|
||||
|
||||
public static final String NO_ROUTES = "no_routes";
|
||||
|
||||
public static final String NO_UNASSIGNED = "no_unassigned_jobs";
|
||||
|
||||
public static final String FIXED_COSTS = "fixed_costs";
|
||||
|
||||
public static final String VARIABLE_COSTS = "variable_costs";
|
||||
|
||||
public static class Route {
|
||||
|
||||
public static final String COSTS = "costs";
|
||||
|
||||
public static final String DISTANCE = "distance";
|
||||
|
||||
public static final String TIME = "time";
|
||||
|
||||
public static final String VEHICLE_ID = "vehicle_id";
|
||||
|
||||
public static final String START_TIME = "start_time";
|
||||
|
||||
public static final String END_TIME = "end_time";
|
||||
|
||||
public static final String ACTIVITY = "act";
|
||||
|
||||
public static final String FIXED_COSTS = "fixed_costs";
|
||||
|
||||
public static final String VARIABLE_COSTS = "variable_costs";
|
||||
|
||||
public static final String NO_ACTIVITIES = "no_activities";
|
||||
|
||||
public static final String UNASSIGNED = "unassigned_jobs";
|
||||
|
||||
public static class Activity {
|
||||
|
||||
public static final String TYPE = "type";
|
||||
|
||||
public static final String SERVICE_ID = "job_id";
|
||||
|
||||
public static final String ARR_TIME = "arr_time";
|
||||
|
||||
public static final String END_TIME = "end_time";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Address {
|
||||
|
||||
public static String ID = "id";
|
||||
|
||||
public static String LON = "lon";
|
||||
|
||||
public static String LAT = "lat";
|
||||
|
||||
}
|
||||
|
||||
public static class TimeWindow {
|
||||
|
||||
public static final String START = "start";
|
||||
|
||||
public static final String END = "end";
|
||||
}
|
||||
|
||||
public static class Job {
|
||||
|
||||
public static final String SIZE = "size";
|
||||
|
||||
public static final String ADDRESS = "address";
|
||||
|
||||
public static final String ID = "id";
|
||||
|
||||
|
||||
public static final String SERVICE_DURATION = "service_duration";
|
||||
|
||||
public static final String NAME = "name";
|
||||
|
||||
public static final String SKILLS = "required_skills";
|
||||
|
||||
public static final String TIME_WINDOW = "time_window";
|
||||
|
||||
public static final String TYPE = "type";
|
||||
|
||||
public static final String PICKUP = "pickup";
|
||||
|
||||
public static final String DELIVERY = "delivery";
|
||||
|
||||
public static final String SERVICE = "service";
|
||||
}
|
||||
|
||||
public static class Vehicle {
|
||||
|
||||
public static final String ID = "id";
|
||||
|
||||
public static final String START_ADDRESS = "start_address";
|
||||
|
||||
public static final String END_ADDRESS = "end_address";
|
||||
|
||||
public static final String EARLIEST_START = "earliest_start";
|
||||
|
||||
public static final String LATEST_END = "latest_end";
|
||||
|
||||
public static final String SKILLS = "skills";
|
||||
|
||||
public static final String CAPACITY = "capacity";
|
||||
|
||||
public static final String TYPE_ID = "type_id";
|
||||
|
||||
public static final String RETURN_TO_DEPOT = "return_to_depot";
|
||||
|
||||
public static class Type {
|
||||
|
||||
public static final String ID = "id";
|
||||
|
||||
public static final String CAPACITY = "capacity";
|
||||
|
||||
public static final String FIXED_COSTS = "fixed_costs";
|
||||
|
||||
public static final String DISTANCE = "distance_dependent_costs";
|
||||
|
||||
public static final String TIME = "time_dependent_costs";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
package jsprit.core.problem.io;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Delivery;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Pickup;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads vehicle routing problem from json file.
|
||||
*/
|
||||
public class VrpJsonReader {
|
||||
|
||||
private final VehicleRoutingProblem.Builder vrpBuilder;
|
||||
|
||||
private final Map<String, VehicleType> vehicle_type_map = new HashMap<String,VehicleType>();
|
||||
|
||||
public VrpJsonReader(VehicleRoutingProblem.Builder vrpBuilder) {
|
||||
this.vrpBuilder = vrpBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads json file.
|
||||
*
|
||||
* @param jsonFile to be read
|
||||
* @throws java.lang.IllegalStateException if there is a service without id and proper location spec OR
|
||||
* if there is a vehicle without id and proper location spec OR if there is a vehicle type without id
|
||||
*/
|
||||
public void read(File jsonFile){
|
||||
JsonNode root = buildTree_and_getRoot_fromFile(jsonFile);
|
||||
parse(root);
|
||||
}
|
||||
|
||||
public void read(String jsonContent){
|
||||
JsonNode root = buildTree_and_getRoot_fromContent(jsonContent);
|
||||
parse(root);
|
||||
}
|
||||
|
||||
public void parse(JsonNode problemRoot) {
|
||||
setFleetSize(problemRoot);
|
||||
parse_and_map_vehicle_types(problemRoot);
|
||||
parse_vehicles(problemRoot);
|
||||
parse_services(problemRoot);
|
||||
}
|
||||
|
||||
private JsonNode buildTree_and_getRoot_fromContent(String jsonContent){
|
||||
JsonNode node = null;
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
node = objectMapper.readTree(jsonContent).path(JsonConstants.PROBLEM);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private JsonNode buildTree_and_getRoot_fromFile(File jsonFile){
|
||||
JsonNode node = null;
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
node = objectMapper.readTree(new FileReader(jsonFile)).path(JsonConstants.PROBLEM);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param root node
|
||||
* @throws java.lang.IllegalStateException if service id is missing OR neither location id nor location coordinate are set
|
||||
*/
|
||||
private void parse_services(JsonNode root) {
|
||||
JsonNode services = root.path(JsonConstants.SERVICES);
|
||||
for(JsonNode serviceNode : services){
|
||||
//type
|
||||
JsonNode typeNode = serviceNode.path(JsonConstants.Job.TYPE);
|
||||
//service id
|
||||
JsonNode jobIdNode = serviceNode.path(JsonConstants.Job.ID);
|
||||
if(jobIdNode.isMissingNode()) throw new IllegalStateException("service-id is missing");
|
||||
|
||||
Service.Builder serviceBuilder;
|
||||
if(typeNode.isMissingNode()) serviceBuilder = Service.Builder.newInstance(jobIdNode.asText());
|
||||
else if(typeNode.asText().equals(JsonConstants.Job.SERVICE)) serviceBuilder = Service.Builder.newInstance(jobIdNode.asText());
|
||||
else if(typeNode.asText().equals(JsonConstants.Job.PICKUP)) serviceBuilder = Pickup.Builder.newInstance(jobIdNode.asText());
|
||||
else if(typeNode.asText().equals(JsonConstants.Job.DELIVERY)) serviceBuilder = Delivery.Builder.newInstance(jobIdNode.asText());
|
||||
else throw new IllegalStateException("type of service ("+typeNode.asText()+") is not supported");
|
||||
|
||||
//service address
|
||||
JsonNode addressIdNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.ID);
|
||||
boolean either_locationId_or_coord = false;
|
||||
if(!addressIdNode.isMissingNode()){
|
||||
serviceBuilder.setLocationId(addressIdNode.asText());
|
||||
either_locationId_or_coord = true;
|
||||
}
|
||||
{
|
||||
JsonNode lonNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LON);
|
||||
JsonNode latNode = serviceNode.path(JsonConstants.Job.ADDRESS).path(JsonConstants.Address.LAT);
|
||||
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
||||
serviceBuilder.setCoord(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||
either_locationId_or_coord = true;
|
||||
}
|
||||
}
|
||||
if(!either_locationId_or_coord) throw new IllegalStateException("location missing. either locationId or locationCoordinate is required");
|
||||
//service name
|
||||
JsonNode nameNode = serviceNode.path(JsonConstants.Job.NAME);
|
||||
if(!nameNode.isMissingNode()) serviceBuilder.setName(nameNode.asText());
|
||||
//service duration
|
||||
serviceBuilder.setServiceTime(serviceNode.path(JsonConstants.Job.SERVICE_DURATION).asDouble());
|
||||
//service tw
|
||||
JsonNode start_tw_node = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.START);
|
||||
JsonNode end_tw_node = serviceNode.path(JsonConstants.Job.TIME_WINDOW).path(JsonConstants.TimeWindow.END);
|
||||
if(!start_tw_node.isMissingNode() && !end_tw_node.isMissingNode()){
|
||||
serviceBuilder.setTimeWindow(TimeWindow.newInstance(start_tw_node.asDouble(),end_tw_node.asDouble()));
|
||||
}
|
||||
//service size
|
||||
JsonNode sizeNode = serviceNode.path(JsonConstants.Job.SIZE);
|
||||
int size_index = 0;
|
||||
for(JsonNode sizeValNode : sizeNode){
|
||||
int size_value = sizeValNode.intValue();
|
||||
serviceBuilder.addSizeDimension(size_index,size_value);
|
||||
size_index++;
|
||||
}
|
||||
//service skills
|
||||
JsonNode reqSkills = serviceNode.path(JsonConstants.Job.SKILLS);
|
||||
for(JsonNode skillNode : reqSkills){
|
||||
serviceBuilder.addRequiredSkill(skillNode.asText());
|
||||
}
|
||||
//add service
|
||||
vrpBuilder.addJob(serviceBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param root node
|
||||
* @throws java.lang.IllegalStateException if vehicle id is missing OR if neither start location id nor start location
|
||||
* coordinate are set
|
||||
*/
|
||||
private void parse_vehicles(JsonNode root) {
|
||||
JsonNode vehicles = root.path(JsonConstants.VEHICLES);
|
||||
for(JsonNode vehicleNode : vehicles){
|
||||
//vehicle id
|
||||
JsonNode vehicle_id_node = vehicleNode.path(JsonConstants.Vehicle.ID);
|
||||
if(vehicle_id_node.isMissingNode()) throw new IllegalStateException("vehicle id missing");
|
||||
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicle_id_node.asText());
|
||||
//vehicle type
|
||||
VehicleType type = vehicle_type_map.get(vehicleNode.path(JsonConstants.Vehicle.TYPE_ID).asText());
|
||||
vehicleBuilder.setType(type);
|
||||
//earliest start
|
||||
JsonNode earliestStartNode = vehicleNode.path(JsonConstants.Vehicle.EARLIEST_START);
|
||||
if(!earliestStartNode.isMissingNode()) vehicleBuilder.setEarliestStart(earliestStartNode.asDouble());
|
||||
//latest end
|
||||
JsonNode latestEndNode = vehicleNode.path(JsonConstants.Vehicle.LATEST_END);
|
||||
if(!latestEndNode.isMissingNode()) vehicleBuilder.setLatestArrival(latestEndNode.asDouble());
|
||||
//start
|
||||
//location id
|
||||
boolean either_id_or_coord = false;
|
||||
JsonNode startAddressId = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.ID);
|
||||
if(!startAddressId.isMissingNode()){
|
||||
vehicleBuilder.setStartLocationId(startAddressId.asText());
|
||||
either_id_or_coord = true;
|
||||
}
|
||||
//location coordinate
|
||||
{
|
||||
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LON);
|
||||
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.START_ADDRESS).path(JsonConstants.Address.LAT);
|
||||
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
||||
vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||
either_id_or_coord = true;
|
||||
}
|
||||
}
|
||||
if(!either_id_or_coord) throw new IllegalStateException("start location of vehicle missing. either id or coordinate required");
|
||||
//end
|
||||
//location id
|
||||
JsonNode endAddressId = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.ID);
|
||||
if(!endAddressId.isMissingNode()){
|
||||
if(!startAddressId.asText().equals(endAddressId.asText())){
|
||||
vehicleBuilder.setEndLocationId(endAddressId.asText());
|
||||
}
|
||||
}
|
||||
//location coordinate
|
||||
{
|
||||
JsonNode lonNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LON);
|
||||
JsonNode latNode = vehicleNode.path(JsonConstants.Vehicle.END_ADDRESS).path(JsonConstants.Address.LAT);
|
||||
if (!lonNode.isMissingNode() && !latNode.isMissingNode()) {
|
||||
vehicleBuilder.setEndLocationCoordinate(Coordinate.newInstance(lonNode.asDouble(), latNode.asDouble()));
|
||||
}
|
||||
}
|
||||
//skills
|
||||
JsonNode skillsNode = vehicleNode.path(JsonConstants.Vehicle.SKILLS);
|
||||
for(JsonNode skillNode : skillsNode){
|
||||
String skill = skillNode.asText();
|
||||
vehicleBuilder.addSkill(skill);
|
||||
}
|
||||
|
||||
vrpBuilder.addVehicle(vehicleBuilder.build());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param root node
|
||||
* @throws java.lang.IllegalStateException if type id is missing
|
||||
*/
|
||||
private void parse_and_map_vehicle_types(JsonNode root) {
|
||||
JsonNode types = root.path(JsonConstants.VEHICLE_TYPES);
|
||||
for(JsonNode typeNode : types){
|
||||
JsonNode typeIdNode = typeNode.path(JsonConstants.Vehicle.Type.ID);
|
||||
if(typeIdNode.isMissingNode()) throw new IllegalStateException("type id missing");
|
||||
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeIdNode.asText());
|
||||
typeBuilder.setFixedCost(typeNode.path(JsonConstants.Vehicle.Type.FIXED_COSTS).asDouble());
|
||||
typeBuilder.setCostPerDistance(typeNode.path(JsonConstants.Vehicle.Type.DISTANCE).asDouble());
|
||||
typeBuilder.setCostPerTime(typeNode.path(JsonConstants.Vehicle.Type.TIME).asDouble());
|
||||
JsonNode capacity = typeNode.path(JsonConstants.Vehicle.Type.CAPACITY);
|
||||
Iterator<JsonNode> capacity_dimension_iterator = capacity.iterator();
|
||||
int capacity_index = 0;
|
||||
while(capacity_dimension_iterator.hasNext()){
|
||||
JsonNode capacity_value = capacity_dimension_iterator.next();
|
||||
int capacity_val = capacity_value.asInt();
|
||||
typeBuilder.addCapacityDimension(capacity_index,capacity_val);
|
||||
capacity_index++;
|
||||
}
|
||||
VehicleTypeImpl type = typeBuilder.build();
|
||||
vehicle_type_map.put(type.getTypeId(),type);
|
||||
}
|
||||
}
|
||||
|
||||
private void setFleetSize(JsonNode root) {
|
||||
String fleetsize = root.path(JsonConstants.FLEET).asText();
|
||||
if(fleetsize.equals("INFINITE")) vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.INFINITE);
|
||||
else vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpJsonReader(vrpBuilder).read(new File("output/vrp.json"));
|
||||
VehicleRoutingProblem problem = vrpBuilder.build();
|
||||
for(Job j : problem.getJobs().values()) System.out.println(j);
|
||||
for(Vehicle v : problem.getVehicles()) System.out.println(v);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,360 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
package jsprit.core.problem.io;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonEncoding;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||
import jsprit.core.algorithm.box.GreedySchrimpfFactory;
|
||||
import jsprit.core.analysis.SolutionAnalyser;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Pickup;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
import jsprit.core.util.Solutions;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by stefan on 03.11.14.
|
||||
*/
|
||||
public class VrpJsonWriter {
|
||||
|
||||
private final VehicleRoutingProblem vrp;
|
||||
|
||||
private final VehicleRoutingProblemSolution solution;
|
||||
|
||||
private SolutionAnalyser solutionAnalyzer;
|
||||
|
||||
public VrpJsonWriter(VehicleRoutingProblem vrp) {
|
||||
this.vrp = vrp;
|
||||
this.solution = null;
|
||||
}
|
||||
|
||||
public VrpJsonWriter(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, SolutionAnalyser.DistanceCalculator distanceCalculator){
|
||||
this.vrp = vrp;
|
||||
this.solution = solution;
|
||||
this.solutionAnalyzer = new SolutionAnalyser(vrp,solution,distanceCalculator);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
try {
|
||||
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(stringWriter);
|
||||
if(solution == null) writeProblem(jsonGenerator);
|
||||
else writeSolution(jsonGenerator);
|
||||
jsonGenerator.flush();
|
||||
jsonGenerator.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
public void addTo(JsonGenerator jsonGenerator){
|
||||
try {
|
||||
if(solution == null) writeProblem(jsonGenerator);
|
||||
else writeSolution(jsonGenerator);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Writer writer){
|
||||
try {
|
||||
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(writer);
|
||||
jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
|
||||
jsonGenerator.writeStartObject();
|
||||
if(solution == null) writeProblem(jsonGenerator);
|
||||
else writeSolution(jsonGenerator);
|
||||
jsonGenerator.writeEndObject();
|
||||
jsonGenerator.flush();
|
||||
jsonGenerator.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(File jsonFile){
|
||||
try {
|
||||
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(new FileOutputStream(jsonFile), JsonEncoding.UTF8);
|
||||
jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
|
||||
jsonGenerator.writeStartObject();
|
||||
if(solution == null) writeProblem(jsonGenerator);
|
||||
else writeSolution(jsonGenerator);
|
||||
jsonGenerator.writeEndObject();
|
||||
jsonGenerator.flush();
|
||||
jsonGenerator.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSolution(JsonGenerator jsonGenerator) {
|
||||
try {
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.SOLUTION);
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.COSTS,solution.getCost());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.FIXED_COSTS,solutionAnalyzer.getFixedCosts());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.VARIABLE_COSTS, solutionAnalyzer.getVariableTransportCosts());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.DISTANCE,solutionAnalyzer.getDistance());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.TIME, solutionAnalyzer.getTransportTime());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.NO_ROUTES,solution.getRoutes().size());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.NO_UNASSIGNED,solution.getUnassignedJobs().size());
|
||||
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Solution.ROUTES);
|
||||
for(VehicleRoute route : solution.getRoutes()){
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.FIXED_COSTS,solutionAnalyzer.getFixedCosts(route));
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.VARIABLE_COSTS,solutionAnalyzer.getVariableTransportCosts(route));
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.NO_ACTIVITIES,route.getActivities().size());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.START_TIME,route.getStart().getEndTime());
|
||||
for(TourActivity act : route.getActivities()) {
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.Solution.Route.ACTIVITY);
|
||||
jsonGenerator.writeStringField(JsonConstants.Solution.Route.Activity.TYPE,act.getName());
|
||||
if(act instanceof TourActivity.JobActivity){
|
||||
jsonGenerator.writeStringField(JsonConstants.Solution.Route.Activity.SERVICE_ID,((TourActivity.JobActivity) act).getJob().getId());
|
||||
}
|
||||
else throw new IllegalStateException("act of class " + act.getClass().toString() + " not supported.");
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.Activity.ARR_TIME, act.getArrTime());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.Activity.END_TIME,act.getEndTime());
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeNumberField(JsonConstants.Solution.Route.END_TIME, route.getEnd().getArrTime());
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
//unassigned jobs
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Solution.Route.UNASSIGNED);
|
||||
for(Job j : solution.getUnassignedJobs()){
|
||||
jsonGenerator.writeString(j.getId());
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
jsonGenerator.writeEndObject();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeProblem(JsonGenerator jsonGenerator) throws IOException {
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.PROBLEM);
|
||||
jsonGenerator.writeStringField(JsonConstants.FLEET, vrp.getFleetSize().toString());
|
||||
writeVehicles(jsonGenerator);
|
||||
writeVehicleTypes(jsonGenerator);
|
||||
writeServices(jsonGenerator);
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
|
||||
private void writeVehicleTypes(JsonGenerator jsonGenerator) {
|
||||
try {
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.VEHICLE_TYPES);
|
||||
Collection<VehicleType> types = getTypes(vrp.getVehicles());
|
||||
|
||||
for(VehicleType type : types){
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeStringField(JsonConstants.Vehicle.Type.ID, type.getTypeId());
|
||||
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Vehicle.Type.CAPACITY);
|
||||
for(int i=0;i<type.getCapacityDimensions().getNuOfDimensions();i++){
|
||||
jsonGenerator.writeNumber(type.getCapacityDimensions().get(i));
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
|
||||
jsonGenerator.writeNumberField(JsonConstants.Vehicle.Type.FIXED_COSTS, type.getVehicleCostParams().fix);
|
||||
jsonGenerator.writeNumberField(JsonConstants.Vehicle.Type.DISTANCE, type.getVehicleCostParams().perDistanceUnit);
|
||||
jsonGenerator.writeNumberField(JsonConstants.Vehicle.Type.TIME, type.getVehicleCostParams().perTimeUnit);
|
||||
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<VehicleType> getTypes(Collection<Vehicle> vehicles) {
|
||||
Set<VehicleType> types = new HashSet<VehicleType>();
|
||||
for(Vehicle v : vehicles) types.add(v.getType());
|
||||
return types;
|
||||
}
|
||||
|
||||
private void writeVehicles(JsonGenerator jsonGenerator) {
|
||||
try {
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.VEHICLES);
|
||||
for(Vehicle vehicle : vrp.getVehicles()){
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeStringField(JsonConstants.Vehicle.ID,vehicle.getId());
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.Vehicle.START_ADDRESS);
|
||||
jsonGenerator.writeStringField(JsonConstants.Address.ID, vehicle.getStartLocationId());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LON, vehicle.getStartLocationCoordinate().getX());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LAT,vehicle.getStartLocationCoordinate().getY());
|
||||
jsonGenerator.writeEndObject();
|
||||
jsonGenerator.writeBooleanField(JsonConstants.Vehicle.RETURN_TO_DEPOT,vehicle.isReturnToDepot());
|
||||
if(!(vehicle.getStartLocationCoordinate().equals(vehicle.getEndLocationCoordinate())
|
||||
&& vehicle.getStartLocationId().equals(vehicle.getEndLocationId()))){
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.Vehicle.END_ADDRESS);
|
||||
jsonGenerator.writeStringField(JsonConstants.Address.ID, vehicle.getEndLocationId());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LON, vehicle.getEndLocationCoordinate().getX());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LAT,vehicle.getEndLocationCoordinate().getY());
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeNumberField(JsonConstants.Vehicle.EARLIEST_START,vehicle.getEarliestDeparture());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Vehicle.LATEST_END,vehicle.getLatestArrival());
|
||||
|
||||
jsonGenerator.writeStringField(JsonConstants.Vehicle.TYPE_ID,vehicle.getType().getTypeId());
|
||||
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Vehicle.SKILLS);
|
||||
for(String skill : vehicle.getSkills().values()){
|
||||
jsonGenerator.writeString(skill);
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeServices(JsonGenerator jsonGenerator) {
|
||||
try {
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.SERVICES);
|
||||
for(Job job : vrp.getJobs().values()){
|
||||
if(!(job instanceof Service)) continue;
|
||||
Service service = (Service)job;
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeStringField(JsonConstants.Job.ID, service.getId());
|
||||
jsonGenerator.writeStringField(JsonConstants.Job.TYPE,service.getType());
|
||||
jsonGenerator.writeStringField(JsonConstants.Job.NAME,service.getName());
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.Job.ADDRESS);
|
||||
jsonGenerator.writeStringField(JsonConstants.Address.ID, service.getLocationId());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LON, service.getCoord().getX());
|
||||
jsonGenerator.writeNumberField(JsonConstants.Address.LAT,service.getCoord().getY());
|
||||
jsonGenerator.writeEndObject();
|
||||
jsonGenerator.writeNumberField(JsonConstants.Job.SERVICE_DURATION, service.getServiceDuration());
|
||||
|
||||
jsonGenerator.writeObjectFieldStart(JsonConstants.Job.TIME_WINDOW);
|
||||
jsonGenerator.writeNumberField(JsonConstants.TimeWindow.START,service.getTimeWindow().getStart());
|
||||
jsonGenerator.writeNumberField(JsonConstants.TimeWindow.END,service.getTimeWindow().getEnd());
|
||||
jsonGenerator.writeEndObject();
|
||||
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Job.SIZE);
|
||||
for(int i=0;i<service.getSize().getNuOfDimensions();i++){
|
||||
jsonGenerator.writeNumber(service.getSize().get(i));
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
|
||||
jsonGenerator.writeArrayFieldStart(JsonConstants.Job.SKILLS);
|
||||
for(String skill : service.getRequiredSkills().values()){
|
||||
jsonGenerator.writeString(skill);
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
jsonGenerator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Service service = Service.Builder.newInstance("s1").setLocationId("s1_loc").setCoord(Coordinate.newInstance(40, 10))
|
||||
.addSizeDimension(0, 20).addSizeDimension(1, 40)
|
||||
.setServiceTime(1.)
|
||||
.addRequiredSkill("joo-foo")
|
||||
.build();
|
||||
Pickup service2 = (Pickup) Pickup.Builder.newInstance("pickup2").setLocationId("s2_loc").setCoord(Coordinate.newInstance(40, 10))
|
||||
.addSizeDimension(0, 10).addSizeDimension(1, 30)
|
||||
.setServiceTime(2.)
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 200))
|
||||
.addRequiredSkill("screw-driver").build();
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("small").addCapacityDimension(0,100).addCapacityDimension(1,400)
|
||||
.setCostPerTime(20.).build();
|
||||
|
||||
VehicleType type2 = VehicleTypeImpl.Builder.newInstance("medium").addCapacityDimension(0,1000).addCapacityDimension(1,4000)
|
||||
.setCostPerTime(200.).setFixedCost(1000.).build();
|
||||
|
||||
VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("startLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0))
|
||||
.setEndLocationId("endLoc").setEndLocationCoordinate(Coordinate.newInstance(12, 12))
|
||||
.addSkill("screw-driver")
|
||||
.setType(type)
|
||||
.setLatestArrival(1000.)
|
||||
.build();
|
||||
|
||||
VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("startLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0))
|
||||
.setType(type2)
|
||||
.setReturnToDepot(false)
|
||||
.addSkill("joo")
|
||||
.build();
|
||||
|
||||
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addJob(service2)
|
||||
.addVehicle(v1).addVehicle(v2).build();
|
||||
new VrpJsonWriter(vrp).write(new File("output/vrp.json"));
|
||||
// System.out.println(new VrpJsonWriter(vrp).toString());
|
||||
|
||||
VehicleRoutingProblem.Builder vrpBuilder_ = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpJsonReader(vrpBuilder_).read(new File("output/vrp.json"));
|
||||
VehicleRoutingProblem vrp_ = vrpBuilder_.build();
|
||||
|
||||
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp_);
|
||||
VehicleRoutingProblemSolution solutions = Solutions.bestOf(vra.searchSolutions());
|
||||
|
||||
FileWriter fileWriter = new FileWriter(new File("output/vrp-solution.json"));
|
||||
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(fileWriter);
|
||||
jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
|
||||
jsonGenerator.writeStartObject();
|
||||
jsonGenerator.writeObjectFieldStart("meta-info");
|
||||
jsonGenerator.writeStringField("distance-unit", "m");
|
||||
jsonGenerator.writeStringField("time-unit","sec");
|
||||
jsonGenerator.writeEndObject();
|
||||
new VrpJsonWriter(vrp,solutions,new SolutionAnalyser.DistanceCalculator() {
|
||||
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
}).addTo(jsonGenerator);
|
||||
jsonGenerator.writeEndObject();
|
||||
jsonGenerator.flush();
|
||||
jsonGenerator.close();
|
||||
fileWriter.close();
|
||||
// .write(new File("output/vrp-solution.json"));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
package jsprit.core.problem.io;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.util.DistanceUnit;
|
||||
import jsprit.core.util.TimeUnit;
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class VrpJsonReaderTest {
|
||||
|
||||
private File jsonFile;
|
||||
|
||||
VehicleRoutingProblem vrp;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
jsonFile = new File("src/test/resources/vrp.json");
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpJsonReader(vrpBuilder).read(jsonFile);
|
||||
vrp = vrpBuilder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noVehiclesShouldBeCorrect(){
|
||||
Assert.assertEquals(2,vrp.getVehicles().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noJobsShouldBeCorrect(){
|
||||
Assert.assertEquals(2, vrp.getJobs().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noTypesShouldBeCorrect(){
|
||||
Assert.assertEquals(2, vrp.getTypes().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldBeOfTypeSmall(){
|
||||
Assert.assertEquals("small",getVehicle("v1").getType().getTypeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle2ShouldBeOfTypeMedium(){
|
||||
Assert.assertEquals("medium",getVehicle("v2").getType().getTypeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectStartAddress(){
|
||||
Assert.assertEquals("startLoc", getVehicle("v1").getStartLocationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectEndAddress(){
|
||||
Assert.assertEquals("endLoc",getVehicle("v1").getEndLocationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectEndLocCoordinate(){
|
||||
Assert.assertEquals(12.,getVehicle("v1").getEndLocationCoordinate().getX(),0.01);
|
||||
Assert.assertEquals(13.,getVehicle("v1").getEndLocationCoordinate().getY(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectEarliestStart(){
|
||||
Assert.assertEquals(0.,getVehicle("v1").getEarliestDeparture());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectLatestStart(){
|
||||
Assert.assertEquals(1000., getVehicle("v1").getLatestArrival());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vehicle1ShouldHaveCorrectSkills(){
|
||||
Assert.assertEquals("screw-driver", getVehicle("v1").getSkills().values().iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fleetSizeShouldBeCorrect(){
|
||||
Assert.assertTrue(VehicleRoutingProblem.FleetSize.FINITE.equals(vrp.getFleetSize()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnToDepotShouldBeCorrect(){
|
||||
Assert.assertTrue(getVehicle("v1").isReturnToDepot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceTypeShouldBeCorrect(){
|
||||
Assert.assertEquals("pickup", getService("pickup2").getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceNameShouldBeCorrect(){
|
||||
Assert.assertEquals("no-name", getService("pickup2").getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startLocShouldBeCorrect(){
|
||||
Assert.assertEquals("s2_loc", getService("pickup2").getLocationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void coordinateShouldBeCorrect(){
|
||||
Assert.assertEquals(40., getService("pickup2").getCoord().getX());
|
||||
Assert.assertEquals(10., getService("pickup2").getCoord().getY());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceDurationShouldBeCorrect(){
|
||||
Assert.assertEquals(2., getService("pickup2").getServiceDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceTWShouldBeCorrect(){
|
||||
Assert.assertEquals(10., getService("pickup2").getTimeWindow().getStart());
|
||||
Assert.assertEquals(200., getService("pickup2").getTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeShouldBeCorrect(){
|
||||
Assert.assertEquals(10, getService("pickup2").getSize().get(0));
|
||||
Assert.assertEquals(30, getService("pickup2").getSize().get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skillsShouldBeCorrect(){
|
||||
Assert.assertEquals("screw-driver", getService("pickup2").getRequiredSkills().values().iterator().next());
|
||||
}
|
||||
|
||||
private Service getService(String jobId) {
|
||||
for(Job s : vrp.getJobs().values()){
|
||||
if(s.getId().equals(jobId)) return (Service)s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readMetaInfo(){
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
try {
|
||||
JsonNode meta = om.readTree(jsonFile).path(JsonConstants.META);
|
||||
Assert.assertEquals(DistanceUnit.Meter.abbreviation(),meta.path(JsonConstants.MetaInfo.DISTANCE_UNIT).asText());
|
||||
Assert.assertEquals(TimeUnit.SEC.abbreviation(),meta.path(JsonConstants.MetaInfo.TIME_UNIT).asText());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Vehicle getVehicle(String id) {
|
||||
for(Vehicle v : vrp.getVehicles()){
|
||||
if(v.getId().equals(id)) return v;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
package jsprit.core.problem.io;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jsprit.core.algorithm.box.GreedySchrimpfFactory;
|
||||
import jsprit.core.analysis.SolutionAnalyser;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
import jsprit.core.util.Solutions;
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 04.12.14.
|
||||
*/
|
||||
public class VrpJsonWriterTest {
|
||||
|
||||
private VehicleRoutingProblem vrp;
|
||||
|
||||
private VehicleRoutingProblemSolution solution;
|
||||
|
||||
private JsonNode root;
|
||||
|
||||
@Before
|
||||
public void doBefore(){
|
||||
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").addCapacityDimension(0,20).build();
|
||||
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setStartLocationCoordinate(Coordinate.newInstance(10,40))
|
||||
.setEndLocationId("end").setEndLocationCoordinate(Coordinate.newInstance(50,20)).setReturnToDepot(true)
|
||||
.setType(type)
|
||||
.build();
|
||||
Service s = Service.Builder.newInstance("s").setCoord(Coordinate.newInstance(50,60)).addSizeDimension(0,10).build();
|
||||
vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v).addJob(s).build();
|
||||
solution = Solutions.bestOf(new GreedySchrimpfFactory().createAlgorithm(vrp).searchSolutions());
|
||||
File out = new File("src/test/resources/vrp-solution.json");
|
||||
new VrpJsonWriter(vrp,solution,new SolutionAnalyser.DistanceCalculator() {
|
||||
@Override
|
||||
public double getDistance(String fromLocationId, String toLocationId) {
|
||||
return vrp.getTransportCosts().getTransportCost(fromLocationId,toLocationId,0.,null,null);
|
||||
}
|
||||
}).write(out);
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
try {
|
||||
root = om.readTree(out).path("solution");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solutionValShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getCost(),root.path("costs").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixShouldBeCorrect(){
|
||||
Assert.assertEquals(0.,root.path("fixed_costs").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void varShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getCost(),root.path("variable_costs").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timeShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getCost(),root.path("time").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getCost(),root.path("distance").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRoutesShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getRoutes().size(),root.path("no_routes").asDouble(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noUnassignedShouldBeCorrect(){
|
||||
Assert.assertEquals(solution.getUnassignedJobs().size(),root.path("no_unassigned").asDouble(),0.01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue