Package jsprit.core.problem.io

Source Code of jsprit.core.problem.io.VrpXMLWriter

/*******************************************************************************
* 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 jsprit.core.problem.Skills;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.job.Shipment;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
import jsprit.core.problem.vehicle.PenaltyVehicleType;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleType;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


public class VrpXMLWriter {
 
  static class XMLConf extends XMLConfiguration {
   
   
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public Document createDoc() throws ConfigurationException{
      return createDocument();
    }
  }
 
  private Logger log = LogManager.getLogger(VrpXMLWriter.class);
 
  private VehicleRoutingProblem vrp;
 
  private Collection<VehicleRoutingProblemSolution> solutions;
 
  public VrpXMLWriter(VehicleRoutingProblem vrp, Collection<VehicleRoutingProblemSolution> solutions) {
    this.vrp = vrp;
    this.solutions = solutions;
  }
 
  public VrpXMLWriter(VehicleRoutingProblem vrp) {
    this.vrp = vrp;
    this.solutions = null;
  }
 
  private static Logger logger = LogManager.getLogger(VrpXMLWriter.class);
 
  public void write(String filename){
    if(!filename.endsWith(".xml")) filename+=".xml";
    log.info("write vrp to " + filename);
    XMLConf xmlConfig = new XMLConf();
    xmlConfig.setFileName(filename);
    xmlConfig.setRootElementName("problem");
    xmlConfig.setAttributeSplittingDisabled(true);
    xmlConfig.setDelimiterParsingDisabled(true);
   
    writeProblemType(xmlConfig);
    writeVehiclesAndTheirTypes(xmlConfig);
   
    //might be sorted?
    List<Job> jobs = new ArrayList<Job>();
    jobs.addAll(vrp.getJobs().values());
    for(VehicleRoute r : vrp.getInitialVehicleRoutes()){
      jobs.addAll(r.getTourActivities().getJobs());
    }
   
    writeServices(xmlConfig,jobs);
    writeShipments(xmlConfig,jobs);
   
    writeInitialRoutes(xmlConfig);
    writeSolutions(xmlConfig);
   
   
    OutputFormat format = new OutputFormat();
    format.setIndenting(true);
    format.setIndent(5);
   
    try {
      Document document = xmlConfig.createDoc();
     
      Element element = document.getDocumentElement();
      element.setAttribute("xmlns", "http://www.w3schools.com");
      element.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
      element.setAttribute("xsi:schemaLocation","http://www.w3schools.com vrp_xml_schema.xsd");
           
    } catch (ConfigurationException e) {
      logger.error(e);
      e.printStackTrace();
      System.exit(1);
    }
   
    try {
      Writer out = new FileWriter(filename);
      XMLSerializer serializer = new XMLSerializer(out, format);
      serializer.serialize(xmlConfig.getDocument());
      out.close();
    } catch (IOException e) {
      logger.error(e);
      e.printStackTrace();
      System.exit(1);
    }
   
   
  }

  private void writeInitialRoutes(XMLConf xmlConfig) {
    if(vrp.getInitialVehicleRoutes().isEmpty()) return;
    String path = "initialRoutes.route";
    int routeCounter = 0;
    for(VehicleRoute route : vrp.getInitialVehicleRoutes()){
      xmlConfig.setProperty(path + "(" + routeCounter + ").driverId", route.getDriver().getId());
      xmlConfig.setProperty(path + "(" + routeCounter + ").vehicleId", route.getVehicle().getId());
      xmlConfig.setProperty(path + "(" + routeCounter + ").start", route.getStart().getEndTime());
      int actCounter = 0;
      for(TourActivity act : route.getTourActivities().getActivities()){
        xmlConfig.setProperty(path + "(" + routeCounter + ").act("+actCounter+")[@type]", act.getName());
        if(act instanceof JobActivity){
          Job job = ((JobActivity) act).getJob();
          if(job instanceof Service){
            xmlConfig.setProperty(path + "(" + routeCounter + ").act("+actCounter+").serviceId", job.getId());
          }
          else if(job instanceof Shipment){
            xmlConfig.setProperty(path + "(" + routeCounter + ").act("+actCounter+").shipmentId", job.getId());
          }
          else{
            throw new IllegalStateException("cannot write solution correctly since job-type is not know. make sure you use either service or shipment, or another writer");
          }
        }
        xmlConfig.setProperty(path + "(" + routeCounter + ").act("+actCounter+").arrTime", act.getArrTime());
        xmlConfig.setProperty(path + "(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime());
        actCounter++;
      }
      xmlConfig.setProperty(path + "(" + routeCounter + ").end", route.getEnd().getArrTime());
      routeCounter++;
    }

  }

  private void writeSolutions(XMLConf xmlConfig) {
    if(solutions == null) return;
    String solutionPath = "solutions.solution";
    int counter = 0;
    for(VehicleRoutingProblemSolution solution : solutions){
      xmlConfig.setProperty(solutionPath + "(" + counter + ").cost", solution.getCost());
      int routeCounter = 0;
      for(VehicleRoute route : solution.getRoutes()){
//        xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").cost", route.getCost());
        xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").driverId", route.getDriver().getId());
        xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").vehicleId", route.getVehicle().getId());
        xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").start", route.getStart().getEndTime());
        int actCounter = 0;
        for(TourActivity act : route.getTourActivities().getActivities()){
          xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName());
          if(act instanceof JobActivity){
            Job job = ((JobActivity) act).getJob();
            if(job instanceof Service){
              xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", job.getId());
            }
            else if(job instanceof Shipment){
              xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").shipmentId", job.getId());
            }
            else{
              throw new IllegalStateException("cannot write solution correctly since job-type is not know. make sure you use either service or shipment, or another writer");
            }
          }
          xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").arrTime", act.getArrTime());
          xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime());
          actCounter++;
        }
        xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").end", route.getEnd().getArrTime());
        routeCounter++;
      }
            int unassignedJobCounter = 0;
            for(Job unassignedJob : solution.getUnassignedJobs()){
                xmlConfig.setProperty(solutionPath + "(" + counter + ").unassignedJobs.job(" + unassignedJobCounter + ")[@id]", unassignedJob.getId());
                unassignedJobCounter++;
            }
      counter++;
    }
  }

  private void writeServices(XMLConf xmlConfig, List<Job> jobs) {
    String shipmentPathString = "services.service";
    int counter = 0;
    for(Job j : jobs){
      if(!(j instanceof Service)) continue;
      Service service = (Service) j;
      xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", service.getId());
      xmlConfig.setProperty(shipmentPathString + "("+counter+")[@type]", service.getType());
      if(service.getLocationId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").locationId", service.getLocationId());
      if(service.getCoord() != null) {
        xmlConfig.setProperty(shipmentPathString + "("+counter+").coord[@x]", service.getCoord().getX());
        xmlConfig.setProperty(shipmentPathString + "("+counter+").coord[@y]", service.getCoord().getY());
      }
      for(int i=0;i<service.getSize().getNuOfDimensions();i++){
        xmlConfig.setProperty(shipmentPathString + "("+counter+").capacity-dimensions.dimension("+i+")[@index]", i);
        xmlConfig.setProperty(shipmentPathString + "("+counter+").capacity-dimensions.dimension("+i+")", service.getSize().get(i));
      }
      xmlConfig.setProperty(shipmentPathString + "("+counter+").duration", service.getServiceDuration());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").timeWindows.timeWindow(0).start", service.getTimeWindow().getStart());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").timeWindows.timeWindow(0).end", service.getTimeWindow().getEnd());

            //skills
            String skillString = getSkillString(service);
            xmlConfig.setProperty(shipmentPathString + "("+counter+").requiredSkills", skillString);

            //name
            if(service.getName() != null){
                if(!service.getName().equals("no-name")){
                    xmlConfig.setProperty(shipmentPathString + "("+counter+").name", service.getName());
                }
            }
      counter++;
    }
  }
 
  private void writeShipments(XMLConf xmlConfig, List<Job> jobs) {
    String shipmentPathString = "shipments.shipment";
    int counter = 0;
    for(Job j : jobs){
      if(!(j instanceof Shipment)) continue;
      Shipment shipment = (Shipment) j;
      xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", shipment.getId());
//      xmlConfig.setProperty(shipmentPathString + "("+counter+")[@type]", service.getType());
      if(shipment.getPickupLocationId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.locationId", shipment.getPickupLocationId());
      if(shipment.getPickupCoord() != null) {
        xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@x]", shipment.getPickupCoord().getX());
        xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@y]", shipment.getPickupCoord().getY());
      }
     
      xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.duration", shipment.getPickupServiceTime());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).start", shipment.getPickupTimeWindow().getStart());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).end", shipment.getPickupTimeWindow().getEnd());
     
     
      if(shipment.getDeliveryLocationId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.locationId", shipment.getDeliveryLocationId());
      if(shipment.getDeliveryCoord() != null) {
        xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@x]", shipment.getDeliveryCoord().getX());
        xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@y]", shipment.getDeliveryCoord().getY());
      }
     
      xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.duration", shipment.getDeliveryServiceTime());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).start", shipment.getDeliveryTimeWindow().getStart());
      xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).end", shipment.getDeliveryTimeWindow().getEnd());
     
      for(int i=0;i<shipment.getSize().getNuOfDimensions();i++){
        xmlConfig.setProperty(shipmentPathString + "("+counter+").capacity-dimensions.dimension("+i+")[@index]", i);
        xmlConfig.setProperty(shipmentPathString + "("+counter+").capacity-dimensions.dimension("+i+")", shipment.getSize().get(i));
      }

            //skills
            String skillString = getSkillString(shipment);
            xmlConfig.setProperty(shipmentPathString + "("+counter+").requiredSkills", skillString);

            //name
            if(shipment.getName() != null){
                if(!shipment.getName().equals("no-name")){
                    xmlConfig.setProperty(shipmentPathString + "("+counter+").name", shipment.getName());
                }
            }
      counter++;
    }
  }
 
  private void writeProblemType(XMLConfiguration xmlConfig){
    xmlConfig.setProperty("problemType.fleetSize", vrp.getFleetSize());
  }

  private void writeVehiclesAndTheirTypes(XMLConfiguration xmlConfig) {

    //vehicles
    String vehiclePathString = Schema.VEHICLES + "." + Schema.VEHICLE;
    int counter = 0;
    for(Vehicle vehicle : vrp.getVehicles()){
      if(vehicle.getType() instanceof PenaltyVehicleType){
        xmlConfig.setProperty(vehiclePathString + "("+counter+")[@type]", "penalty");
      }
      xmlConfig.setProperty(vehiclePathString + "("+counter+").id", vehicle.getId());
      xmlConfig.setProperty(vehiclePathString + "("+counter+").typeId", vehicle.getType().getTypeId());
      xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.id", vehicle.getStartLocationId());
      if(vehicle.getStartLocationCoordinate() != null){
        xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.coord[@x]", vehicle.getStartLocationCoordinate().getX());
        xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.coord[@y]", vehicle.getStartLocationCoordinate().getY());
      }
      xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.id", vehicle.getEndLocationId());
      if(vehicle.getEndLocationCoordinate() != null){
        xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.coord[@x]", vehicle.getEndLocationCoordinate().getX());
        xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.coord[@y]", vehicle.getEndLocationCoordinate().getY());
      }
      xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture());
      xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival());

      xmlConfig.setProperty(vehiclePathString + "("+counter+").returnToDepot", vehicle.isReturnToDepot());

            //write skills
            String skillString = getSkillString(vehicle);
            xmlConfig.setProperty(vehiclePathString + "("+counter+").skills", skillString);

      counter++;
    }

    //types
    String typePathString = Schema.builder().append(Schema.TYPES).dot(Schema.TYPE).build();
    int typeCounter = 0;
    for(VehicleType type : vrp.getTypes()){
      if(type instanceof PenaltyVehicleType){
        xmlConfig.setProperty(typePathString + "("+typeCounter+")[@type]", "penalty");
        xmlConfig.setProperty(typePathString + "("+typeCounter+")[@penaltyFactor]", ((PenaltyVehicleType)type).getPenaltyFactor());
      }
      xmlConfig.setProperty(typePathString + "("+typeCounter+").id", type.getTypeId());
     
      for(int i=0;i<type.getCapacityDimensions().getNuOfDimensions();i++){
        xmlConfig.setProperty(typePathString + "("+typeCounter+").capacity-dimensions.dimension("+i+")[@index]", i);
        xmlConfig.setProperty(typePathString + "("+typeCounter+").capacity-dimensions.dimension("+i+")", type.getCapacityDimensions().get(i));
      }
     
      xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.fixed", type.getVehicleCostParams().fix);
      xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.distance", type.getVehicleCostParams().perDistanceUnit);
      xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.time", type.getVehicleCostParams().perTimeUnit);
      typeCounter++;
    }


   
   
  }

    private String getSkillString(Vehicle vehicle) {
        return createSkillString(vehicle.getSkills());
    }

    private String getSkillString(Job job){
        return createSkillString(job.getRequiredSkills());
    }

    private String createSkillString(Skills skills) {
        if(skills.values().size() == 0) return null;
        String skillString = null;
        for(String skill : skills.values()){
            if(skillString == null) skillString = skill;
            else skillString += ", " + skill;
        }
        return skillString;
    }


}
TOP

Related Classes of jsprit.core.problem.io.VrpXMLWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.