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<Long> matrixHeader; 
 | 
    private Double[][] adjacencyMatrix; 
 | 
    private int[][] pathMatrix; 
 | 
    private Double[][] floydMatrix; 
 | 
  
 | 
    public List<Integer> calculatePath(Integer origin, Integer destination) { 
 | 
        List<Integer> 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<Code> codeList = codeService.list(new LambdaQueryWrapper<Code>().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<Long> getMatrixHeader() { 
 | 
        if (null == matrixHeader) { 
 | 
            throw new BusinessException("核心算法还在进行中"); 
 | 
        } 
 | 
        return matrixHeader; 
 | 
    } 
 | 
  
 | 
    public Double[][] getFloydMatrix() { 
 | 
        if (null == floydMatrix) { 
 | 
            throw new BusinessException("核心算法还在进行中"); 
 | 
        } 
 | 
        return floydMatrix; 
 | 
    } 
 | 
} 
 |