js迪傑斯特拉算法求最短路徑


 

1.后台生成矩陣

名詞解釋和下圖參考:https://blog.csdn.net/csdnxcn/article/details/80057574

 

double[,] arr = new double[allVertices.Count(), allVertices.Count()]; //矩陣 

//allVertices所有三維坐標點的集合

//lines 所有兩點的連線

 

 

for (int i = 0; i < allVertices.Count(); i++)
{
for (int j = 0; j < allVertices.Count(); j++)
{
var start1 = allVertices[i].Point; //起點
var end1 = allVertices[j].Point; //終點
//lines 兩點的連線集合
var line = lines.FirstOrDefault(ee => (ee.StartPoint == start1 && ee.EndPoint == end1)|| (ee.StartPoint == end1 && ee.EndPoint == start1/*起點終點互換*/));
if (start1 == end1)
{//同一個點
arr[i, j] = 0;
}
else
{
if (line != null)
{
arr[i, j] = double.Parse(line.Remark); //長度
}
else
{//兩點未連接 此路不通
arr[i, j] =1.0/0.0; //Infinity
}
}
}
}

return arr;

2.dijkstra算法

/**
* Dijkstra算法
*
* @author wupanpan@baidu.com
* @date 2014-03-26
*/

/**
* @const
*/
var POS_INFINITY = Infinity;

/**
* @param {number} sourceV 源點的索引,從0開始
* @param {Array} adjMatrix 圖的鄰接矩陣,是一個二維數組
*/

function dijkstra(sourceV, adjMatrix) {
var set = [],
path = [],

dist = [];
distCopy = [],
vertexNum = adjMatrix.length;

var temp, u,
count = 0;

// 初始化
for (var i = 0; i < vertexNum; i++) {
distCopy[i] = dist[i] = POS_INFINITY;
set[i] = false;
}
distCopy[sourceV] = dist[sourceV] = 0;

while (count < vertexNum) {
u = distCopy.indexOf(Math.min.apply(Math, distCopy));
set[u] = true;
distCopy[u] = POS_INFINITY;

for (var i = 0; i < vertexNum; i++) {
if (!set[i] && ((temp = dist[u] + adjMatrix[u][i]) < dist[i])) {
distCopy[i] = dist[i] = temp;
path[i] = u;
}
}
count++;
}

return {
path: path,
dist: dist
};
}

/**
* @param {number} v 源點索引, 從0開始
* @param {number} d 非源點索引, 從0開始
* @param {Array} adjMatrix 圖的鄰接矩陣,是一個二維數組
*/
function searchPath(v, d, adjMatrix) {
var graph = dijkstra(v, adjMatrix),
path = graph.path,
dist = graph.dist;

var prev = path[d],
queue = [],
str = '';

queue.push(d);
while(prev != v) {
queue.push(prev);
prev = path[prev];
}
queue.push(v);

for (var j = queue.length - 1; j >= 0; j--) {
str +=queue.pop() + '->';
}
console.log('path',str);
var arr=str.split('->');
if(str.endsWith('->')){
arr.pop();
}
var rarr=[];//字符串數組轉int數組
for(var i=0;i<arr.length;i++){
rarr.push(parseInt(arr[i]));
}
return rarr;
}


/**
* 測試數據
*/
var adjM = [
[0, 4, 2, POS_INFINITY, POS_INFINITY, POS_INFINITY],
[4, 0, 1, 5, POS_INFINITY, POS_INFINITY],
[2, 1, 0, 8, 10, POS_INFINITY],
[POS_INFINITY, 5, 8, 0, 2, 6],
[POS_INFINITY, POS_INFINITY, 10, 2, 0, 3],
[POS_INFINITY, POS_INFINITY, POS_INFINITY, 6, 3, 0]
];

3.使用算法求最短路徑

 

5個點坐標如上圖 虛線表示兩點相連

1:  0,0,0
2:  1,1,0
3:  -1,-1,0
4:  2,0,0
5:  0,-1,0

 

請求后台生成的矩陣為:

var pathMatrix = [
[
0,
1.73,
1.73,
"Infinity",
1
],
[
1.73,
0,
"Infinity",
1.73,
"Infinity"
],
[
1.73,
"Infinity",
0,
"Infinity",
"Infinity"
],
[
"Infinity",
1.73,
"Infinity",
0,
2.23
],
[
1,
"Infinity",
"Infinity",
2.23,
0
]
];

var ret = searchPath(4, 1, pathMatrix); //從第5點到第2點的最短路徑
console.log('index', ret);

 (索引從0開始,對應到圖上是 5->1->2)

 4.使用threejs畫出路徑

(黑色連線;  紅綠藍為xyz輔助線)

 

geometryPoint = new THREE.BoxGeometry(0.2, 0.2, 0.2);
var materialPoint = new THREE.MeshBasicMaterial({
color: 0xff00ff,
side: THREE.DoubleSide
});
circlePoint1 = new THREE.Mesh(geometryPoint, materialPoint);
circlePoint1.position.set(0, 0, 0);
scene.add(circlePoint1);

circlePoint2 = circlePoint1.clone();
circlePoint2.position.set(1, 1, 0);
scene.add(circlePoint2);

circlePoint3 = circlePoint1.clone();
circlePoint3.position.set(-1, 1, 0);
scene.add(circlePoint3);


circlePoint4 = circlePoint1.clone();
circlePoint4.position.set(2, 0, 0);
scene.add(circlePoint4);


circlePoint5 = circlePoint1.clone();
circlePoint5.position.set(0, -1, 0);
scene.add(circlePoint5);

scene.add(new THREE.AxesHelper(300));

//畫路徑

var ret = searchPath(4, 1, pathMatrix);   //從第5點到第2點的最短路徑
console.log('index', ret);

var geometry1 = new THREE.Geometry();
for (var i = 0; i < ret.length; i++) {
console.log("circlePoint" + (ret[i] + 1));
var pointObj = eval("circlePoint" + (ret[i] + 1));
console.log('position', pointObj.position);
geometry1.vertices.push(pointObj.position);
}
var line = new THREE.Line(geometry1, new THREE.LineBasicMaterial({
color: 'black'
}), THREE.LinePieces);
scene.add(line);

 

//補充

//threejs求三維兩點的距離

var distance = circlePoint4.position.distanceTo(circlePoint5.position);
console.log(distance);

 

From:https://www.cnblogs.com/xuejianxiyang/p/9776319.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM