package com.doumee.core.utils; import com.google.ortools.Loader; import com.google.ortools.constraintsolver.*; import lombok.extern.slf4j.Slf4j; @Slf4j public class TspSolver { public static void main(String[] args) throws Exception { // 初始化数据模型 Loader.loadNativeLibraries(); DataModel data = new DataModel(); data.initDataList();//构造数据 long start =System.currentTimeMillis(); System.out.println("=============start=========="+start); //创建求解器manager对象,初始化求解器数据 RoutingIndexManager manager = new RoutingIndexManager(data.distanceMatrix.length, data.vehicleNumber, data.depot); // 初始化求解器 RoutingModel routing = new RoutingModel(manager); // // 注册回调函数 final int transitCallbackIndex = routing.registerTransitCallback((long fromIndex, long toIndex) -> { int fromNode = manager.indexToNode(fromIndex); int toNode = manager.indexToNode(toIndex); return data.distanceMatrix[fromNode][toNode]; }); // 定义回调函数至每条路线 routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex); // 增加距离维度约束 routing.addDimension(transitCallbackIndex, 0, 30000, true, "Distance"); RoutingDimension distanceDimension = routing.getMutableDimension("Distance"); distanceDimension.setGlobalSpanCostCoefficient(100); // // 添加容量限制 final int demandCallbackIndex = routing.registerUnaryTransitCallback((long fromIndex) -> { int fromNode = manager.indexToNode(fromIndex); return data.demands[fromNode]; }); routing.addDimensionWithVehicleCapacity(demandCallbackIndex, 0, data.vehicleCapacities, true, "Capacity"); Solver solver = routing.solver(); //设置搜索方法 RoutingSearchParameters searchParameters = main.defaultRoutingSearchParameters() .toBuilder() .setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC) .build(); // 执行算法 Assignment solution = routing.solveWithParameters(searchParameters); // 打印路线 printSolution(data, routing, manager, solution); long end =System.currentTimeMillis(); System.out.println("=============end=========="+end); System.out.println("=============耗时=========="+(end -start)+"(ms)"+(end -start)/1000 +"s"+(end -start)/60/1000 +"m"); } static void printSolution( DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) { long maxRouteDistance = 0; for (int i = 0; i < data.vehicleNumber; ++i) { long index = routing.start(i); log.info("Route for Vehicle " + i + ":"); long routeDistance = 0; int routeDemand = 0; String route = ""; while (!routing.isEnd(index)) { route += manager.indexToNode(index) + " -> "; routeDemand += data.demands[manager.indexToNode(index)]; long previousIndex = index; index = solution.value(routing.nextVar(index)); routeDistance += routing.getArcCostForVehicle(previousIndex, index, i); } log.info(route + manager.indexToNode(index)); log.info("Distance of the route: " + routeDistance + "m"+" Capacity of the route:"+routeDemand+"/"+data.vehicleCapacities[i]); maxRouteDistance = Math.max(routeDistance, maxRouteDistance); } log.info("Maximum of the route distances: " + maxRouteDistance + "m"); } static class DataModel { //距离矩阵 public int lenght; //最大车辆限制 public int vehicleNumber; //起点 public static final int depot = 0; //每一个点的商品的数量 public long[] demands; //车辆最大容载 public long[] vehicleCapacities ; public long[][] distanceMatrix ; public void initDataList(){ lenght = 500; vehicleNumber = 8; demands = new long[lenght]; vehicleCapacities =new long[vehicleNumber]; distanceMatrix = new long[lenght][lenght]; int total0 =0; for (int i = 0; i