如何解决Google OR-Tools 中不同的开始和结束位置
我一直在使用 Google 提供的 VRP,我希望在我的程序中允许不同的开始和结束位置。听起来很简单......但是当我添加不同的开始和结束位置时,我得到如下错误:
WARNING: Logging before InitGoogleLogging() is written to STDERR
F00-1 -1:-1:-1.529052 27172 routing.cc:1565] Check Failed: kUnassigned != indices[i] (-1 vs. -1)
*** Check failure stack trace: ***
Process finished with exit code -1073740791 (0xC0000409)
这是我的代码:
package com.google.ortools.constraintsolver.samples;
import com.google.ortools.Loader;
import com.google.ortools.constraintsolver.*;
import com.google.protobuf.Duration;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.*;
import java.util.ArrayList;
/** Minimal VRP.*/
public class MultipleStart {
private static Double[][] computeManhattandistance (Double[][] locations) {
Double[][] distanceMatrix = new Double[locations.length][locations.length];
for( int startNode = 0 ; startNode < locations.length ; startNode++ ) {
for( int endNode = 0 ; endNode < locations.length ; endNode++ ) {
distanceMatrix[startNode][endNode] = (Math.abs((locations[startNode][0] - locations[endNode][0])) +
Math.abs(locations[startNode][1] - locations[endNode][1]));
}
}
return distanceMatrix;
}
/// @brief Print the solution.
static void printSolution(
int vehicleNumber,RoutingModel routing,RoutingIndexManager manager,Assignment solution) {
// display dropped nodes.
JSONObject result = new JSONObject();
ArrayList<String> droppednodes = new ArrayList<>();
for (int node = 0; node < routing.size(); ++node) {
if (routing.isstart(node) || routing.isEnd(node)) {
continue;
}
if (solution.value(routing.nextvar(node)) == node) {
droppednodes.add( " " + manager.indexToNode(node) );
}
}
result.put("droppednodes",droppednodes);
// display routes
JSONObject routes = new JSONObject();
ArrayList<JSONObject> routingData = new ArrayList<>();
long totaldistance = 0;
for (int i = 0; i < vehicleNumber ; i++) {
long index = routing.start(i);
ArrayList<Long> vehicleRoute = new ArrayList<>();
long routedistance = 0;
while (!routing.isEnd(index)) {
long nodeIndex = manager.indexToNode(index);
vehicleRoute.add(nodeIndex);
long prevIoUsIndex = index;
index = solution.value(routing.nextvar(index));
routedistance += routing.getArcCostForVehicle(prevIoUsIndex,index,i);
}
vehicleRoute.add((long)manager.indexToNode(index));
routes.put("Vehicle " + (i+1),vehicleRoute);
totaldistance += routedistance;
}
routingData.add(routes);
result.put("routingData",routingData);
result.put("Total distance",totaldistance);
System.out.println(result);
}
public static void main(String[] args) throws Exception {
Loader.loadNativeLibraries();
JSONObject data = (JSONObject) new JSONParser().parse(args[0]);
JSONArray locationData = (JSONArray) data.get("locations");
Double[][] locations = new Double[locationData.size()][2];
for(int i=0 ; i<locationData.size() ; i++) {
JSONArray location = (JSONArray) locationData.get(i);
locations[i][0] = Double.valueOf((String) location.get(0));
locations[i][1] = Double.valueOf((String) location.get(1));
}
Double[][] distanceMatrix = computeManhattandistance(locations);
long vehicleNumbers = (long) data.get("vehicleNumber");
JSONArray starts = (JSONArray) data.get("starts");
JSONArray ends = (JSONArray) data.get("ends");
long[] starting = new long[starts.size()];
for(int i=0 ; i< starts.size() ; i++)
starting[i] = (long) starts.get(i);
int[] start = new int[starting.length];
for(int i=0 ; i< starting.length ; i++)
start[i] = (int) starting[i];
long[] endings = new long[ends.size()];
for(int i=0 ; i< ends.size() ; i++)
endings[i] = (long) ends.get(i);
int[] end = new int[endings.length];
for(int i=0 ; i< endings.length ; i++)
end[i] = (int) endings[i];
// Create Routing Index Manager
RoutingIndexManager manager =
new RoutingIndexManager(distanceMatrix.length,(int) vehicleNumbers,start,end);
// Create Routing Model.
RoutingModel routing = new RoutingModel(manager);
// Create and register a transit callback.
final int transitCallbackIndex = routing.registerTransitCallback((long fromIndex,long toIndex) -> {
// Convert from routing variable Index to user NodeIndex.
int fromNode = manager.indexToNode(fromIndex);
int toNode = manager.indexToNode(toIndex);
return (distanceMatrix[fromNode][toNode]).longValue();
});
if(data.get("demands") != null && data.get("vehicleCapacities") != null) {
JSONArray demandarray = (JSONArray) data.get("demands");
long[] demands = new long[demandarray.size()];
for(int i=0 ; i<demandarray.size() ; i++) {
demands[i] = (long) demandarray.get(i);
}
// Add Capacity constraint.
final int demandCallbackIndex = routing.registerUnaryTransitCallback((long fromIndex) -> {
// Convert from routing variable Index to user NodeIndex.
int fromNode = manager.indexToNode(fromIndex);
return demands[fromNode];
});
long capacities = (long) data.get("vehicleCapacities");
long[] vehicleCapacities = new long[(int)vehicleNumbers];
for(int i=0 ; i<vehicleNumbers ; i++)
vehicleCapacities[i] = capacities;
routing.addDimensionWithVehicleCapacity(demandCallbackIndex,vehicleCapacities,true,"Capacity");
long penalty = 1500;
for (int i = 1; i < distanceMatrix.length; ++i) {
routing.adddisjunction(new long[] {manager.nodetoIndex(i)},penalty);
}
}
// Define cost of each arc.
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
String priority = (String) data.get("priority");
// Add distance constraint.
routing.addDimension(transitCallbackIndex,20,3000,false,// start cumul to zero
priority);
RoutingDimension distanceDimension = routing.getMutableDimension(priority);
distanceDimension.setGlobalSpanCostCoefficient(100);
// Define Transportation Requests.
Solver solver = routing.solver();
if(data.get("pickupDeliveries") != null) {
JSONArray indexs = (JSONArray) data.get("pickupDeliveries");
long [][] pickupsDeliveries = new long[indexs.size()][2];
for(int i =0 ; i< indexs.size() ; i++) {
JSONArray temp = (JSONArray) indexs.get(i);
pickupsDeliveries[i][0] = (long) temp.get(0);
pickupsDeliveries[i][1] = (long) temp.get(1);
}
for (long[] request : pickupsDeliveries) {
long pickupIndex = manager.nodetoIndex((int)request[0]);
long deliveryIndex = manager.nodetoIndex((int)request[1]);
routing.addPickupAndDelivery(pickupIndex,deliveryIndex);
solver.addConstraint(
solver.makeEquality(routing.vehicleVar(pickupIndex),routing.vehicleVar(deliveryIndex)));
solver.addConstraint(solver.makeLessOrEqual(
distanceDimension.cumulVar(pickupIndex),distanceDimension.cumulVar(deliveryIndex)));
}
}
// Setting first solution heuristic.
RoutingSearchParameters searchParameters =
main.defaultRoutingSearchParameters()
.toBuilder()
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.GLOBAL_CHEApest_ARC)
.setLocalSearchMetaheuristic(LocalSearchMetaheuristic.Value.GUIDED_LOCAL_SEARCH)
.setTimeLimit(Duration.newBuilder().setSeconds(30).build())
.build();
// Solve the problem.
Assignment solution = routing.solveWithParameters(searchParameters);
// Print solution on console.
printSolution((int) vehicleNumbers,routing,manager,solution);
}
}
这是我的 JSON 数据:
{
"locations": [
[
"30.718785","76.810374"
],[
"30.704649","76.717873"
],[
"52.922530","-1.474619"
],[
"28.638604","77.209890"
],[
"23.766164","90.358873"
],[
"22.572646","88.363895"
],[
"50.674522","-120.327267"
],[
"19.220113","72.974845"
],[
"30.733315","76.779418"
],"76.779418"
]
],"pickupDeliveries": [
[
0,1
],[
5,6
]
],"demands": [
1,1,0
],"vehicleNumber": 2,"vehicleCapacities": 6,"priority": "distance","starts": [
9,11
],"ends": [
10,12
]
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。