在进行三维管线连通性分析时,需要运用到最短路径算法,主要思路为首先初始化图,然后将查询到的管点以及管线分别作为图的顶点数以及边数。
export default {
PathMatirx: [], // 用于存储最短路径下标的数组,下标为各个顶点,值为下标顶点的前驱顶点
ShortPathTable: [], //用于存储到各点最短路径的权值和
G: {},
clear: function () {
this.G = {};
this.PathMatirx = [];
this.ShortPathTable = [];
},
//初始化图
init: function (points, lines) {
this.clear();
this.MGraph(this.G);
this.createMGraph(points, lines);
return this.G;
},
path(start, end) {
this.Dijkstra2(start);
return this.PrintVn(start, end);
},
//创建图
createMGraph: function (points, lines) {
let G = this.G;
G.numVertexes = points.length; //设置顶点数
G.numEdges = lines.length; //设置边数
//录入顶点信息
for (let i = 0; i < G.numVertexes; i++) {
G.vexs[i] = points[i].feature.attributes.WTDH;//'V' + i; //scanf('%s'); //ascii码转字符 //String.fromCharCode(i + 65);
}
// console.log(G.vexs); //打印顶点
//无向图构建
for (let i = 0; i < G.numVertexes; i++) {
G.arc[i] = [];
}
for (let i = 0; i < G.numVertexes; i++) {
for (let j = i; j < G.numVertexes; j++) {
if (i === j) {
G.arc[i][j] = 0;
} else {
G.arc[i][j] = Infinity;
G.arc[j][i] = Infinity;
for (let k = 0; k < G.numEdges; k++) {
let line = lines[k];
if ((line.feature.attributes.QDDH === G.vexs[i] && line.feature.attributes.ZDDH === G.vexs[j]) ||
(line.feature.attributes.QDDH === G.vexs[j] && line.feature.attributes.ZDDH === G.vexs[i])) {
G.arc[i][j] = parseFloat(line.feature.attributes.SHAPE_LENG || "0");
G.arc[j][i] = parseFloat(line.feature.attributes.SHAPE_LENG || "0");
}
}
}
}
}
//有向图构建
// for (let i = 0; i < G.numVertexes; i++) {
// G.arc[i] = [];
// for (let j = 0; j < G.numVertexes; j++) {
// if (i === j) {
// G.arc[i][j] = 0;
// } else {
// G.arc[i][j] = Infinity;
// for (let k = 0; k < G.numEdges; k++) {
// let line = lines[k];
// if ((line.QDDH === G.vexs[i] && line.ZDDH === G.vexs[j])) {
// G.arc[i][j] = line.SHAPE_Leng;
// }
// if ((line.QDDH === G.vexs[j] && line.ZDDH === G.vexs[i])) {
// G.arc[j][i] = line.SHAPE_Leng;
// }
// }
//
// }
// }
// }
//邻接矩阵初始化
// for (let i = 0; i < G.numVertexes; i++) {
// G.arc[i] = [];
// for (let j = 0; j < G.numVertexes; j++) {
// G.arc[i][j] = Arr2[i][j]; //INFINITY;
// }
// }
// console.log(G.arc); //打印邻接矩阵
},
// 定义图结构
MGraph: function (G) {
G.vexs = []; //顶点表
G.arc = []; // 边表
G.numVertexes = null; //图中当前的顶点数
G.numEdges = null; //图中当前的边数
},
Dijkstra2: function (n) {
let G = this.G;
let k, min;
let final = [];
for (let v = 0; v < G.numVertexes; v++) {
final[v] = 0;
this.ShortPathTable[v] = G.arc[n][v];
this.PathMatirx[v] = 0;
}
this.ShortPathTable[0] = 0;
final[0] = 1;
//初始化数据
for (let v = 0; v < G.numVertexes; v++) {
if (v === n) {
continue
}
min = Infinity;
for (let w = 0; w < G.numVertexes; w++) { //寻找离V0最近的顶点
if (!final[w] && this.ShortPathTable[w] < min) {
k = w;
min = this.ShortPathTable[w]; //w 顶点离V0顶点更近
}
}
// console.log("b " + ShortPathTable, k, min);
final[k] = 1; //将目前找到的最近的顶点置位1
for (let w = 0; w < G.numVertexes; w++) { //修正当前最短路径及距离
if (!final[w] && (min + G.arc[k][w] < this.ShortPathTable[w])) { //说明找到了更短的路径,修改PathMatirx[w]和ShortPathTable[w]
this.ShortPathTable[w] = min + G.arc[k][w];
this.PathMatirx[w] = k;
}
}
}
},
PrintVn: function (start, end) {
let G = this.G;
// console.log(this.ShortPathTable, this.PathMatirx);
//打印V0-Vn最短路径
// console.log("%s-%s 最小权值和: %d", G.vexs[start], G.vexs[end], this.ShortPathTable[end]);
//打印最短路线
let temp = end,
str = '';
let arr = [];
arr.push(end);
while (temp !== 0) {
str = '->' + G.vexs[temp] + str;
temp = this.PathMatirx[temp];
arr.push(temp);
}
str = G.vexs[start] + str;
// console.log('最短路线:' + str);
arr.pop();
arr.push(start);
// console.log(arr);
return {
ShortPathTable: this.ShortPathTable,
PathMatirx: this.PathMatirx,
path: str,
pathArr: arr,
Graphic: this.G,
}
}
}