server/startsh/admin_start.sh
@@ -19,4 +19,3 @@ cd /usr/local/ortools/java_or-tools tail -f /usr/local/jars/logs/visitsAdmin/info.2025-10-31.0.log server/startsh/Æô¶¯½Å±¾ºÍÈÕÖ¾´¦Àí½Å±¾ËµÃ÷.txt
@@ -17,3 +17,11 @@ Linuxç³»ç»å®è£ 对åºççæ¬æå¡ï¼ https://developers.google.cn/optimization/install/java/pkg_linux?hl=zh-cn#ubuntu https://modelers.csdn.net/68db8ec14b11580edfa299c6.html?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-5-134512600-blog-119785705.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-5-134512600-blog-119785705.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=10 #æ æ³èç½ vim /etc/resolv.conf (nameserve 8.8.8.8) tail -f /usr/local/jars/logs/visitsAdmin/info.2025-10-31.0.log server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/DistanceCalculator.java
@@ -22,10 +22,22 @@ public static void main(String[] args) { //118.363428,31.326485 //118.363312,31.326638 System.out.println(calculateDistance(39.326638d,116.363312d,31.326606,118.363272)); JkCustomer start = new JkCustomer(); start.setId(-1); start.setLongitude(new BigDecimal(118.39)); start.setLatitude(new BigDecimal(31.28)); JkCustomer c = new JkCustomer(); c.setId(-2); c.setLongitude(new BigDecimal(118.328593)); c.setLatitude(new BigDecimal(30.914289)); String url="https://restapi.amap.com/v3/direction/driving?origin=${long1},${lat1}&destination=${long2},${lat2}&extensions=basel&key=248ee35dcdfe3f399ffaf12ac4299eca"; DistanceCustomerModel dm = DistanceCalculator.calculateDistanceGaode(url,start,c); System.out.println(dm.getDistance()); } public static DistanceCustomerModel calculateDistanceGaode(String urlStr, JkCustomer c1, JkCustomer c2) { public static DistanceCustomerModel calculateDistanceGaode(String urlStr, JkCustomer c1, JkCustomer c2) { DistanceCustomerModel r =new DistanceCustomerModel(); r.setStart(c1); r.setEnd(c2); @@ -67,10 +79,10 @@ r.setCode(1); log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=============="); }else{ log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=====失败ï¼ï¼========="); log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=====失败ï¼ï¼========="+c1.getName()+"==="+c2.getName()+result); } }catch (Exception e){ log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=====失败=========="); log.error("è·å交éè§åçº¿è·¯ä¿¡æ¯æå=====失败=========="+c1.getName()+"==="+c2.getName()); } return r ; server/visits/dmvisit_service/src/main/java/com/doumee/core/tsp/TspSolver.java
@@ -4,6 +4,8 @@ import com.doumee.core.exception.BusinessException; import com.google.ortools.Loader; import com.google.ortools.constraintsolver.*; import com.google.protobuf.Duration; import com.google.protobuf.DurationOrBuilder; import lombok.extern.slf4j.Slf4j; import com.google.ortools.constraintsolver.mainJNI; @@ -85,7 +87,7 @@ RoutingModel routing = new RoutingModel(manager); // 注ååè°å½æ° final int transitCallbackIndex = /* final int transitCallbackIndex = routing.registerTransitCallback((long fromIndex, long toIndex) -> { int fromNode = manager.indexToNode(fromIndex); int toNode = manager.indexToNode(toIndex); @@ -94,25 +96,45 @@ // å®ä¹åè°å½æ°è³æ¯æ¡è·¯çº¿ routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex); // å¢å è·ç¦»ç»´åº¦çº¦æ routing.addDimension(transitCallbackIndex, 0, 300000000, routing.addDimension(transitCallbackIndex, 0, 30000000, true, "Distance"); RoutingDimension distanceDimension = routing.getMutableDimension("Distance"); distanceDimension.setGlobalSpanCostCoefficient(100); // // æ·»å 容ééå¶ distanceDimension.setGlobalSpanCostCoefficient(100);*/ // 注ååè°å½æ° final int transitCallbackIndex1 = routing.registerTransitCallback((long fromIndex, long toIndex) -> { return 1; }); for (int d = 0; d < data.vehicleMaxNodes.length; d++) { // å¢å è·ç¦»ç»´åº¦çº¦æ routing.addDimension(transitCallbackIndex1, 0, data.vehicleMaxNodes[d], true, "customer_"+d); RoutingDimension distanceDimension1 = routing.getMutableDimension("customer_"+d); distanceDimension1.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"); // routing.addDimensionWithVehicleTransits() Solver solver = routing.solver(); //设置æç´¢æ¹æ³ /* // æ·»å 容ééå¶ final int demandCallbackIndex1 = routing.registerUnaryTransitCallback((long fromIndex) -> { return 1; }); routing.addDimensionWithVehicleCapacity(demandCallbackIndex1, 0, data.vehicleMaxNodes, true, "Capacity"); */ Solver solver = routing.solver(); //设置æç´¢æ¹æ³( RoutingSearchParameters searchParameters = main.defaultRoutingSearchParameters() .toBuilder() .setTimeLimit(Duration.newBuilder().setSeconds(60*60).build())//æä¹ 1å°æ¶ .setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC) .build(); @@ -203,6 +225,7 @@ public long[] demands; //è½¦è¾æå¤§å®¹è½½ public long[] vehicleCapacities ; public long[] vehicleMaxNodes ; public long[][] distanceMatrix ; public List<TspSolverSolutions> getSolutions() { @@ -213,22 +236,25 @@ this.solutions = solutions; } public void initDataInfo(int vehicleNumber1, long[] demands1, long[] vehicleCapacities1, long[][] distanceMatrix1){ public void initDataInfo(int vehicleNumber1, long[] demands1, long[] vehicleCapacities1, long[][] distanceMatrix1,long[] vehicleMaxNodes){ this.demands = demands1; this.vehicleNumber = vehicleNumber1; this.vehicleCapacities=vehicleCapacities1; this.distanceMatrix=distanceMatrix1; this.vehicleMaxNodes =vehicleMaxNodes; } public void initDataList(){ lenght = 100; vehicleNumber = 7; lenght = 20; vehicleNumber = 5; demands = new long[lenght]; vehicleCapacities =new long[vehicleNumber]; vehicleMaxNodes =new long[vehicleNumber]; distanceMatrix = new long[lenght][lenght]; int total0 =0; for (int i = 0; i <vehicleNumber ; i++) { long tem = (long) (Math.random() * 1000 + 20000); vehicleCapacities[i] = tem; vehicleMaxNodes[i] =5; total0+=tem; System.out.print(tem+" ,"); } server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkSketchServiceImpl.java
@@ -261,7 +261,6 @@ Date date = new Date(); BigDecimal cLatitude =new BigDecimal(0); BigDecimal cLongitude =new BigDecimal(0); String location = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.COMPANY_LOCATION).getCode(); try { String[] ss = location.split(","); @@ -269,25 +268,55 @@ cLatitude = new BigDecimal(ss[1]); }catch (Exception e){ } int index =0; for(JkCustomer c : customerList){ try { log.info("交éè§å========"+c.getName()+"==========="+index++); dealDistancePerCustomer(c,url,date,cLatitude,cLongitude,customerList); }catch (Exception e){ } int circle = customerList.size()/100;// if(customerList.size()%100>0){ circle +=1; } boolean[] results = new boolean[circle] ; for (int i = 0; i < circle; i++) { final int start =i*100; final int end = (i+1)*100 > customerList.size()? customerList.size(): (i+1)*100; results[i] =false; BigDecimal finalCLatitude = cLatitude; BigDecimal finalCLongitude = cLongitude; log.error("交éè§å====线ç¨circleï¼"+i+"====start:"+start+"===========end:"+end); int finalI = i; Thread t1=new Thread(() -> { try { int index =0; for (int j = start; j < end; j++) { try { log.error("交éè§å========"+customerList.get(j).getName()+"========cirle:"+finalI+"==="+index++); dealDistancePerCustomer(customerList.get(j),url,date, finalCLatitude, finalCLongitude,customerList); }catch (Exception e){ } } }catch (Exception e){ }finally { results[finalI] =true; boolean isDone = false; for(boolean t : results){ isDone = isDone&&t; } if(isDone){ cate.setStatus(Constants.ZERO); categoryMapper.updateById(cate);//æ´æ°ä»»å¡æ§è¡ç¶æ } } }); t1.start(); } }catch (Exception e){ e.printStackTrace(); }finally { cate.setStatus(Constants.ZERO); categoryMapper.updateById(cate);//æ´æ°ä»»å¡æ§è¡ç¶æ } } private void dealDistancePerCustomer(JkCustomer c, String url, Date date, BigDecimal cLatitude, BigDecimal cLongitude, List<JkCustomer> customerList) { private void dealDistancePerCustomer(JkCustomer c, String url, Date date, BigDecimal cLatitude, BigDecimal cLongitude, List<JkCustomer> customerList) throws InterruptedException { List<JkCustomer> updateCustomerList = new ArrayList<>(); List<JkCustomerNavigation> navigationList = new ArrayList<>(); List<DistanceMapParam> tmpList = new ArrayList<>(); @@ -298,28 +327,34 @@ t0.setId(-2);//表示è¿åååº t0.setDistance(Constants.formatLongNum(c.getStartDistance()) ); if(Constants.formatLongNum(c.getStartDistance()) <= 0){ //ååºåå¾è¯¥å®¢æ·çè·ç¦»ï¼å¦æä¹åæªè·åè¿ //ååºåå¾è¯¥å®¢æ·çè·ç¦»ï¼å¦æä¹åæªè·å isNew = true; JkCustomer start = new JkCustomer(); start.setId(-1); start.setLongitude(cLongitude); start.setLatitude(cLatitude); DistanceCustomerModel dm = DistanceCalculator.calculateDistanceGaode(url,start,c); c.setStartDistance(dm.getDistance() ); t0.setDistance(dm.getDistance()); u.setStartDistance(dm.getDistance()); if(dm.getLocations().size()>0){ //妿æè·¯å¾ä¿¡æ¯ u.setStartSteps(dm.getPolyline()); if(dm.getCode() == 1){ //è§å失败 log.error("==============客æ·äº¤éè§åæåèµ·ç¹:"+c.getName()); c.setStartDistance(dm.getDistance() ); t0.setDistance(dm.getDistance()); u.setStartDistance(dm.getDistance()); if(dm.getLocations().size()>0){ //妿æè·¯å¾ä¿¡æ¯ u.setStartSteps(dm.getPolyline()); } } } tmpList.add(t0); for(JkCustomer cm : customerList){ //客æ·å客æ·ä¹é´çè·ç¦»ä¿¡æ¯ Thread.sleep(500); DistanceMapParam t = new DistanceMapParam(); t.setId(cm.getId()); DistanceMapParam param = getParamByCustomerIds( cm.getId(),distanceMapParamList); if(param!=null){//妿ä¹åå·²ç»è·åè¿ if(param!=null && param.getDistance()!=0){//妿ä¹åå·²ç»è·åè¿ t = param; }else{ JkCustomerNavigation navigation = new JkCustomerNavigation(); @@ -359,15 +394,19 @@ start.setId(-1); start.setLongitude(cLongitude); start.setLatitude(cLatitude); DistanceCustomerModel dm = DistanceCalculator.calculateDistanceGaode(url,c,start); c.setEndDistance(dm.getDistance() ); tt.setDistance(dm.getDistance()); u.setEndDistance(dm.getDistance()); if(dm.getLocations().size()>0){ //妿æè·¯å¾ä¿¡æ¯ u.setEndSteps(dm.getPolyline()); if(dm.getCode()== 1){ //è§å失败 log.error("==============客æ·äº¤éè§åæå2:"+c.getName()); c.setEndDistance(dm.getDistance() ); tt.setDistance(dm.getDistance()); u.setEndDistance(dm.getDistance()); if(dm.getLocations().size()>0){ //妿æè·¯å¾ä¿¡æ¯ u.setEndSteps(dm.getPolyline()); } } } tmpList.add(tt); if(isNew){// @@ -463,6 +502,7 @@ TspSolver.DataModel dataModel = new TspSolver.DataModel(); int vehicleNumber1 = lineList.size();//线路æ°é long[] vehicleCapacities1=new long[lineList.size()];//æ¯è¾è½¦çæå¤§è®¢åééå¶ long[] vehicleMaxNodes=new long[lineList.size()];//æ¯è¾è½¦çæå¤§è®¢åééå¶ long[] demands1 = new long[customerList.size()+1]; //å个ç¹ç订åé long[][] distanceMatrix1 = new long[customerList.size()+1][customerList.size()+1]; distanceMatrix1[0][0] = 0; @@ -488,9 +528,10 @@ } for (int i = 0; i < lineList.size(); i++) { vehicleCapacities1[i] = lineList.get(i).getMaxOrder();//æ¯è¾è½¦çæå¤§è®¢åééå¶ vehicleMaxNodes[i] =lineList.get(i).getMaxCustomer();//æå¤§å®¢æ·æ° } //æé ä¼åæ°æ®æ¨¡å dataModel.initDataInfo(vehicleNumber1,demands1,vehicleCapacities1,distanceMatrix1); dataModel.initDataInfo(vehicleNumber1,demands1,vehicleCapacities1,distanceMatrix1,vehicleMaxNodes); TspSolver.startSearch(dataModel); dealSearchSolution(model,dataModel); }catch (Exception e){ @@ -553,6 +594,7 @@ TspSolver.DataModel dataModel = new TspSolver.DataModel(); int vehicleNumber1 = 1;//线路æ°é long[] vehicleCapacities1=new long[]{line.getMaxOrder()};//æ¯è¾è½¦çæå¤§è®¢åééå¶ long[] vehicleMaxNodes=new long[]{line.getMaxCustomer()};//æ¯è¾è½¦çæå¤§è®¢åééå¶ long[] demands1 = new long[customerListParam.size()+1]; //å个ç¹ç订åé long[][] distanceMatrix1 = new long[customerListParam.size()+1][customerListParam.size()+1]; distanceMatrix1[0][0] = 0; @@ -567,7 +609,7 @@ } } //æé ä¼åæ°æ®æ¨¡å dataModel.initDataInfo(vehicleNumber1,demands1,vehicleCapacities1,distanceMatrix1); dataModel.initDataInfo(vehicleNumber1,demands1,vehicleCapacities1,distanceMatrix1,vehicleMaxNodes); TspSolver.startSearch(dataModel); if(dataModel.getSolutions()==null || dataModel.getSolutions().size()==0){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"线路ã"+line.getLineName()+"ãè°æ´å¤±è´¥ ï¼æªè·å¾æä¼äº¤éè§åæ¹æ¡ï¼");