package lastkilometer.O_four; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.dom4j.DocumentException; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.box.Jsprit; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; import jsprit.core.problem.Location; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.job.Job; 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.TimeWindow; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity; 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.reporting.SolutionPrinter; import jsprit.core.problem.vehicle.VehicleImpl.Builder; import jsprit.core.util.Coordinate; import jsprit.core.util.Solutions; import lastkilometer.readCSV.ReadAssignedOrder_id; import lastkilometer.readCSV.ReadCSVForParse; import lastkilometer.readCSV.ReadOrderFromOrder_id; import lastkilometer.readCSV.ReadResults_cache; /** * * 最后一公里配送 * * */ public class LastKilometer_three extends ReadData{ //读取已经配送的订单id ReadAssignedOrder_id readAssignedOrder_id =new ReadAssignedOrder_id(); public LastKilometer_three() throws NumberFormatException, IOException { super(); // TODO Auto-generated constructor stub } /** * 配送 * @return * * @throws IOException * @throws NumberFormatException * @throws DocumentException * */ public int pickupAndDeliver(int number) throws NumberFormatException, IOException, DocumentException{ int n=1; int step=124; for(int i=0;i<Site_Lng_Lat.size();i+=step){ List<String> Site_id_list=new ArrayList<>(); for(int j=0;j<step;j++){ if(n<=124){ //获取网点id String cahce=n+""; StringBuffer buffer = new StringBuffer("A000"); buffer.replace(4-cahce.length(),4, cahce); String Site_id=buffer.toString(); Site_id_list.add(Site_id); n++; } } System.out.println("设置网点------>"+Site_id_list); //设置网点 List<VehicleImpl> sites=setSite(Site_id_list); //设置订单 List<Shipment> orders=setOrder(Site_id_list); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addAllVehicles(sites); vrpBuilder.addAllJobs(orders); //设置初始路径 List<VehicleRoute> vehicleRoutes=setInitialVehicleRoute(vrpBuilder); vrpBuilder.addInitialVehicleRoutes(vehicleRoutes); // vrpBuilder.setFleetSize(FleetSize.FINITE); VehicleRoutingProblem problem = vrpBuilder.build(); /* * get the algorithm */ // VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem); // VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem); VehicleRoutingAlgorithm algorithm =VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem,"input/algorithmConfig.xml"); //迭代次数 algorithm.setMaxIterations(10); /* * and search a solution */ Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions(); /* * get the best */ number=writePostFile(number, solutions); // VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); // SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE); // // String pathAndName="output/results_"+i+"_"+step+".xml"; // new VrpXMLWriter(problem, solutions).write(pathAndName); // // //解析output目录下的文件得出结果 // ParseXMLForPost_three pxps=new ParseXMLForPost_three(); // boolean bool=pxps.savePostFormat(pathAndName, number); // if(bool){ // number=pxps.number; // } } return number; } private int writePostFile(int number,Collection<VehicleRoutingProblemSolution> solutions) throws IOException { ReadCSVForParse read = new ReadCSVForParse(); Map<String, List<Object>> ESO = read.readElectricitySuppliersOrder(); Map<String, List<Object>> OO = read.readO2OOrder(); if (solutions == null) return number; int counter = 0; for (VehicleRoutingProblemSolution solution : solutions) { if (counter == solutions.size() - 1) {// 取最后一个路径 System.out.println("solution.getCost()--->" + solution.getCost()); for (VehicleRoute route : solution.getRoutes()) { // 设置快递员id String cahce = (number + 1) + ""; StringBuffer buffer = new StringBuffer("D0000"); buffer.replace(5 - cahce.length(), 5, cahce); String Courier_id = buffer.toString(); for (TourActivity act : route.getTourActivities().getActivities()) { Job job = ((JobActivity) act).getJob(); String Order_id = job.getId(); List<Object> list = null; if (ESO.get(Order_id) != null) { list = ESO.get(Order_id); } else { list = OO.get(Order_id); } int Num = (int) list.get(2); // act.getName()--->pickupShipment、deliverShipment 取还是送 // act.getArrTime()--->到达时间 // act.getEndTime()--->离开时间 String pickupORdeliver=act.getName(); if ("pickupShipment".equals(pickupORdeliver)) { // 根据订单号和pickup判断来取网点或商户id、 取/送货量(取为+,送为-) String Addr = (String) list.get(0); save("results/", "post_last", Courier_id + "," + Addr + "," + (int)act.getArrTime() + "," + (int)act.getEndTime() + "," + Num + "," + Order_id); } else if ("deliverShipment".equals(pickupORdeliver)) { // 根据订单号和deliver判断来取配送点、 取/送货量(取为+,送为-) String Addr = (String) list.get(1); save("results/", "post_last", Courier_id + "," + Addr + "," + (int)act.getArrTime() + "," + (int)act.getEndTime() + ",-" + Num + "," + Order_id); } } number++; } // 未配送订单 for (Job unassignedJob : solution.getUnassignedJobs()) { System.out.println("unassignedJob.getId():" + unassignedJob.getId()); } } counter++; } return number; } /** * 设置订单 * * @param Site_id 网点id * @throws IOException * @throws NumberFormatException * */ private List<Shipment> setOrder(List<String> Site_id_list) throws NumberFormatException, IOException{ List<String> assignedOrder_idWithAll=readAssignedOrder_id.readAssignedOrder_idWithAll(); List<Shipment> shipments=new ArrayList<Shipment>(); for(String Site_id:Site_id_list){ Map<String, Map<String, Integer>> twoESO=ESO.get(Site_id); for(Entry<String, Map<String, Integer>> eTwo:twoESO.entrySet()){ String Spot_id=eTwo.getKey(); Map<String, Integer> three=eTwo.getValue(); for(Entry<String, Integer> eThree:three.entrySet()){ String Order_id=eThree.getKey(); //设置 // if(!assignedOrder_idWithAll.contains(Order_id)){ // int Num=eThree.getValue(); // //网点的经纬度 // double[] Lng_Lat_Site=Site_Lng_Lat.get(Site_id); // //配送点的经纬度 // double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); // // Shipment shipment = Shipment.Builder.newInstance(Order_id) // .addSizeDimension(0, Num) // .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Site[0], Lng_Lat_Site[1]))) // .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) // .setDeliveryTimeWindow(TimeWindow.newInstance(0, 12*60)) // .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) // .build(); // shipments.add(shipment); // } int Num=eThree.getValue(); //网点的经纬度 double[] Lng_Lat_Site=Site_Lng_Lat.get(Site_id); //配送点的经纬度 double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); Shipment shipment = Shipment.Builder.newInstance(Order_id) .addSizeDimension(0, Num) .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Site[0], Lng_Lat_Site[1]))) .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) .setDeliveryTimeWindow(TimeWindow.newInstance(0, 12*60)) .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) .build(); shipments.add(shipment); } } //取离当前网点最近的商户id List<String> Shop_id_list=OIB.get(Site_id); if(Shop_id_list!=null){ for(String Shop_id:Shop_id_list){ Map<String, Map<String, List<Object>>> twoOO=OO.get(Shop_id); for(Entry<String, Map<String, List<Object>>> eTwo:twoOO.entrySet()){ String Spot_id=eTwo.getKey(); Map<String, List<Object>> three=eTwo.getValue(); for(Entry<String, List<Object>> eThree:three.entrySet()){ String Order_id=eThree.getKey(); //设置 // if(!assignedOrder_idWithAll.contains(Order_id)){ // List<Object> list=eThree.getValue(); // int Pickup_time=(int) list.get(0); // int Delivery_time=(int) list.get(1); // int Num=(int)list.get(2); // // //商户的经纬度 // double[] Lng_Lat_Shop=Shop_Lng_Lat.get(Shop_id); // //配送点的经纬度 // double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); // Shipment shipment = Shipment.Builder.newInstance(Order_id) // .addSizeDimension(0, Num) // .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Shop[0], Lng_Lat_Shop[1]))) // .setPickupTimeWindow(TimeWindow.newInstance(Pickup_time,Pickup_time)) // .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) // .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) // .setDeliveryTimeWindow(TimeWindow.newInstance(Pickup_time, Delivery_time)) // .build(); // // shipments.add(shipment); // } List<Object> list=eThree.getValue(); int Pickup_time=(int) list.get(0); int Delivery_time=(int) list.get(1); int Num=(int)list.get(2); //商户的经纬度 double[] Lng_Lat_Shop=Shop_Lng_Lat.get(Shop_id); //配送点的经纬度 double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); Shipment shipment = Shipment.Builder.newInstance(Order_id) .addSizeDimension(0, Num) .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Shop[0], Lng_Lat_Shop[1]))) .setPickupTimeWindow(TimeWindow.newInstance(Pickup_time,Pickup_time)) .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) .setDeliveryTimeWindow(TimeWindow.newInstance(Pickup_time, Delivery_time)) .build(); shipments.add(shipment); } } } } } return shipments; } /** * 设置网点 * * @param Site_id 网点id * @throws IOException * @throws NumberFormatException * @return List<VehicleImpl> * */ private List<VehicleImpl> setSite(List<String> Site_id_list) throws NumberFormatException, IOException{ List<VehicleImpl> vehicles=new ArrayList<>(); for(String Site_id:Site_id_list){ int bearLoad=140;//设置快递员负重容量 double[] Lng_Lat=Site_Lng_Lat.get(Site_id); double lng=Lng_Lat[0]; double lat=Lng_Lat[1]; VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance(Site_id+"Type").addCapacityDimension(0, bearLoad); // vehicleTypeBuilder.setCostPerServiceTime(1.0);//设置,计算cost时的设置 VehicleType vehicleType = vehicleTypeBuilder.build(); Builder vehicleBuilder = VehicleImpl.Builder.newInstance(Site_id); vehicleBuilder.setStartLocation(loc(Coordinate.newInstance(lng, lat))); // vehicleBuilder.setLatestArrival(12*60);//十二个小时,设置快递员工作时间 vehicleBuilder.setType(vehicleType); // vehicleBuilder.setReturnToDepot(false);//设置车辆不返回 VehicleImpl vehicle = vehicleBuilder.build(); vehicles.add(vehicle); } return vehicles; } /** * 设置初始路径 * @throws IOException * */ private List<VehicleRoute> setInitialVehicleRoute(VehicleRoutingProblem.Builder vrpBuilder) throws IOException{ List<VehicleRoute> vehicleRoutes=new ArrayList<>(); ReadOrderFromOrder_id readOFO=new ReadOrderFromOrder_id(); Map<String,List<Object>> ofo=readOFO.readOrder(); //读取第一次配送的结果数据 ReadResults_cache read=new ReadResults_cache(); Map<String, List<List<Object>>> post_res=read.readResults_cahce(); for(Entry<String, List<List<Object>>> entry:post_res.entrySet()){ List<List<Object>> listFirst=entry.getValue(); String Addr=null; for(List<Object> listSecond_C:listFirst){ Addr=(String) listSecond_C.get(0); if("A".equals(Addr.substring(0,1))){ break; } } Vehicle vehicle=getVehicle((String)listFirst.get(0).get(0), vrpBuilder); if(vehicle!=null){ jsprit.core.problem.solution.route.VehicleRoute.Builder vehicleRouteBuilder = VehicleRoute.Builder.newInstance(vehicle); for(List<Object> listSecond:listFirst){ String Order_id=(String) listSecond.get(2); int Amount=(int) listSecond.get(1); //根据订单id读取订单信息 List<Object> listThird=ofo.get(Order_id); if(listThird.size()==3){//电商的订单 String Spot_id=(String) listThird.get(0); String Site_id=(String) listThird.get(1); int Num=(int) listThird.get(2); //网点的经纬度 double[] Lng_Lat_Site=Site_Lng_Lat.get(Site_id); //配送点的经纬度 double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); Shipment shipment = Shipment.Builder.newInstance(Order_id) .addSizeDimension(0, Num) .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Site[0], Lng_Lat_Site[1]))) .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) .setDeliveryTimeWindow(TimeWindow.newInstance(0, 12*60)) .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) .build(); if(Amount>0){//判断是Pickup还是Delivery vehicleRouteBuilder.addPickup(shipment); }else{ vehicleRouteBuilder.addDelivery(shipment); } }else{//O2O的订单 String Spot_id=(String) listThird.get(0); String Shop_id=(String) listThird.get(1); int Pickup_time=(int) listThird.get(2); int Delivery_time=(int) listThird.get(3); int Num=(int) listThird.get(4); //商户的经纬度 double[] Lng_Lat_Shop=Shop_Lng_Lat.get(Shop_id); //配送点的经纬度 double[] Lng_Lat_Spot=Spot_Lng_Lat.get(Spot_id); Shipment shipment = Shipment.Builder.newInstance(Order_id) .addSizeDimension(0, Num) .setPickupLocation(loc(Coordinate.newInstance(Lng_Lat_Shop[0], Lng_Lat_Shop[1]))) .setPickupTimeWindow(TimeWindow.newInstance(Pickup_time,Pickup_time)) .setDeliveryLocation(loc(Coordinate.newInstance(Lng_Lat_Spot[0], Lng_Lat_Spot[1]))) .setDeliveryServiceTime(Math.round(3*Math.sqrt(Num)+5)) .setDeliveryTimeWindow(TimeWindow.newInstance(Pickup_time, Delivery_time)) .build(); if(Amount>0){//判断是Pickup还是Delivery vehicleRouteBuilder.addPickup(shipment); }else{ vehicleRouteBuilder.addDelivery(shipment); } } } VehicleRoute vehicleRoute=vehicleRouteBuilder.build(); vehicleRoutes.add(vehicleRoute); } } return vehicleRoutes; } private static Location loc(Coordinate coordinate) { return Location.Builder.newInstance().setCoordinate(coordinate).build(); } private static Vehicle getVehicle(String vehicleId, VehicleRoutingProblem.Builder vrpBuilder) { for (Vehicle v : vrpBuilder.getAddedVehicles()) { if (v.getId().equals(vehicleId)) return v; } return null; } }