package com.zy.acs.manager.core.service.floyd; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.acs.manager.common.exception.BusinessException; import com.zy.acs.manager.manager.entity.Code; import com.zy.acs.manager.manager.entity.CodeGap; import com.zy.acs.manager.manager.entity.Route; import com.zy.acs.manager.manager.service.CodeGapService; import com.zy.acs.manager.manager.service.CodeService; import com.zy.acs.manager.manager.service.RouteService; import com.zy.acs.manager.system.service.ConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Created by vincent on 2023/6/15 */ @Slf4j @Component public class FloydNavigateService { public static final double INF = 999999.0; @Autowired private CodeService codeService; @Autowired private CodeGapService codeGapService; @Autowired private RouteService routeService; @Autowired private ConfigService configService; private List matrixHeader; private Double[][] adjacencyMatrix; private int[][] pathMatrix; private Double[][] floydMatrix; public List calculatePath(Integer origin, Integer destination) { List path = new ArrayList<>(); path.add(destination); Integer current = destination; while (!current.equals(origin)) { current = this.pathMatrix[origin][current]; path.add(current); } Collections.reverse(path); return path; } public int codeIdx(Long codeId) { return this.matrixHeader.indexOf(codeId); } public Long getCodeId(int idx) { return this.matrixHeader.get(idx); } // @PostConstruct @SuppressWarnings("all") public void generateMatrix() { log.info("【FLOYD】正在计算矩阵数据......"); List codeList = codeService.list(new LambdaQueryWrapper().eq(Code::getStatus, 1).eq(Code::getDeleted, false)); int size = codeList.size(); matrixHeader = new ArrayList<>(size); adjacencyMatrix = new Double[size][size]; pathMatrix = new int[size][size]; for (int i = 0; i < size; i++) { Code startCode = codeList.get(i); matrixHeader.add(startCode.getId()); for (int j = 0; j < size; j++) { Code endCode = codeList.get(j); Route route = routeService.findByCodeOfBoth(startCode.getId(), endCode.getId()); CodeGap codeGap = codeGapService.findByCodeOfBoth(startCode.getId(), endCode.getId()); double distance = INF; int path = -1; if (null != route && null != codeGap && codeGap.getDistance() > 0) { if (i != j) { distance = codeGap.getDistance(); } path = i; } adjacencyMatrix[i][j] = distance; pathMatrix[i][j] = path; } } floydMatrix = this.floydAlgorithm(adjacencyMatrix); } /** * Floyd */ @SuppressWarnings("all") private Double[][] floydAlgorithm(Double[][] graph) { int n = graph.length; Double[][] shortestPaths = new Double[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { shortestPaths[i][j] = graph[i][j]; } } for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (shortestPaths[i][k] + shortestPaths[k][j] < shortestPaths[i][j]) { shortestPaths[i][j] = shortestPaths[i][k] + shortestPaths[k][j]; pathMatrix[i][j] = pathMatrix[k][j]; } } } } return shortestPaths; } public Double[][] getAdjacencyMatrix() { if (null == adjacencyMatrix) { throw new BusinessException("核心算法还在进行中"); } return adjacencyMatrix; } public int[][] getPathMatrix() { if (null == pathMatrix) { throw new BusinessException("核心算法还在进行中"); } return pathMatrix; } public List getMatrixHeader() { if (null == matrixHeader) { throw new BusinessException("核心算法还在进行中"); } return matrixHeader; } public Double[][] getFloydMatrix() { if (null == floydMatrix) { throw new BusinessException("核心算法还在进行中"); } return floydMatrix; } }