1
0
Fork 0
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:
oblonski 2014-12-12 10:55:56 +01:00
parent 9938a6a123
commit 1458b03be7
13 changed files with 253 additions and 1502 deletions

View file

@ -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";
}
}
}

View file

@ -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);
}
}

View file

@ -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"));
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}