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 (将#修改为@)