[英]What is the most efficient way to represent edge weights for Dijkstra's algorithm
我正在做一個小游戲,我要在一個可以移動的網格上放置一個角色。 當它們四處移動時,我將使用Dijkstra的算法進行路徑選擇。 唯一的問題是我要像這樣制作薄壁(而不是僅僅刪除節點): http : //i.gyazo.com/85d110c17cf027d3ad0219fa26938305.png
我當時想最好的方法是將2個正方形之間的邊緣權重編輯得很高,以至於永遠都不會被交叉。 無論如何,要問一個問題:
將邊緣權重分配給網格中每個連接的最有效方法是什么?
我曾考慮過使用鄰接矩陣,但對於15x6的網格,這是90x90的矩陣,似乎...過多。 任何幫助都很好,謝謝(:
您只需要在直線正方形之間存儲邊,並且一個正方形最多可以有4個鄰居,每個方向一次。 將節點訪問的邊存儲為最多4個枚舉項(上,下,左,右)。 小於90 x 4。
一些可以幫助您決定應該做什么的指針:
double
作為權重,則許多語言都具有可以使用的無窮大值。 在Java中為Double.POSITIVE_INFINITY
。 關於無限的美麗-與您添加的無限一樣,它保持無限(並且不會像整數一樣溢出)。 O(V^2)
而不是O(V+E)
(在您的情況下實際上為O(V)
),和O(V^2)
用於Dijkstra的算法,而不是O(E + VlogV)
(對於您的圖形是O(VlogV)
) 我同意Rocky的回答-只需將每個正方形的四個方向的權重存儲在一個數組中(每個數組元素將是一個包含四個權重的結構/元組)。 要查找兩個任意正方形之間的邊緣,請首先檢查它們是否相鄰,如果是,則使用數組中的適當權重。 不知道為什么有人提到鄰接表或矩陣,在這里是多余的。
嘗試下面的代碼來創建您的游戲。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
object[,] input = {
{
new object[] { 0, -1, -1, 1, 6}, //index, left, up, right, down
new object[] { 1, 0, -1, -1, 7}, //index, left, up, right, down
new object[] { 2, -1, -1, 3, 8}, //index, left, up, right, down
new object[] { 3, 2, -1, 4, 9}, //index, left, up, right, down
new object[] { 4, 3, -1, -1, 10}, //index, left, up, right, down
new object[] { 5, -1, -1, -1, 11} //index, left, up, right, down
},
{
new object[] { 6, -1, 0, 7, -1}, //index, left, up, right, down
new object[] { 7, 6, 1, -1, 13}, //index, left, up, right, down
new object[] { 8, -1, 2, 9, 14}, //index, left, up, right, down
new object[] { 9, 8, 3, -1, -1}, //index, left, up, right, down
new object[] {10, -1, 4, 11, -1}, //index, left, up, right, down
new object[] {11, 10, 5, -1, 17} //index, left, up, right, down
},
{
new object[] {12, -1, -1, 13, 19}, //index, left, up, right, down
new object[] {13, 12, 7, 14, 20}, //index, left, up, right, down
new object[] {14, 13, 8, 15, 21}, //index, left, up, right, down
new object[] {15, 14, -1, -1, 22}, //index, left, up, right, down
new object[] {16, -1, -1, 17, 23}, //index, left, up, right, down
new object[] {17, 16, 11, -1, 24} //index, left, up, right, down
},
{
new object[] {18, -1, 12, 19, 24}, //index, left, up, right, down
new object[] {19, 18, 13, -1, 25}, //index, left, up, right, down
new object[] {20, -1, 14, 21, 26}, //index, left, up, right, down
new object[] {21, 20, 15, -1, 27}, //index, left, up, right, down
new object[] {22, -1, 16, 23, 28}, //index, left, up, right, down
new object[] {23, 22, 17, -1, 29} //index, left, up, right, down
},
{
new object[] {24, -1, 18, 25, -1}, //index, left, up, right, down
new object[] {25, 24, 19, 26, -1}, //index, left, up, right, down
new object[] {26, -1, 20, 27, -1}, //index, left, up, right, down
new object[] {27, 26, 21, 28, -1}, //index, left, up, right, down
new object[] {28, 27, 22, 29, -1}, //index, left, up, right, down
new object[] {29, 28, 23, -1, -1} //index, left, up, right, down
},
};
cell game = new cell(input);
}
}
public class cell
{
public static cell[,] board = new cell[5, 6];
public int index { get; set; } //row number * 6 + col
public int row { get; set;}
public int col { get; set;}
public cell up { get; set; }
public cell down { get; set; }
public cell left { get; set; }
public cell right { get; set; }
public cell() { }
public cell(object[,] input)
{
int cellNumber = 0;
int boardRow = 0;
int boardCol = 0;
int cellRow = 0;
int cellCol = 0;
for (int row = 0; row < 5; row++)
{
for (int col = 0; col < 6; col++)
{
board[row, col] = new cell();
}
}
for (int row = 0; row < 5; row++)
{
for (int col = 0; col < 6; col++)
{
object[] items = (object[])input[row, col];
cellNumber = (int)items[0];
boardRow = cellNumber / 6;
boardCol = cellNumber % 6;
board[boardRow, boardCol].index = cellNumber;
board[boardRow, boardCol].row = row;
board[boardRow, boardCol].col = col;
cellNumber = (int)items[1];
cellRow = cellNumber / 6;
cellCol = cellNumber % 6;
if (cellNumber == -1)
{
board[boardRow, boardCol].left = null;
}
else
{
board[boardRow, boardCol].left = board[cellRow, cellCol];
}
cellNumber = (int)items[2];
cellRow = cellNumber / 6;
cellCol = cellNumber % 6;
if (cellNumber == -1)
{
board[boardRow, boardCol].up = null;
}
else
{
board[boardRow, boardCol].up = board[cellRow, cellCol];
}
cellNumber = (int)items[3];
cellRow = cellNumber / 6;
cellCol = cellNumber % 6;
if (cellNumber == -1)
{
board[boardRow, boardCol].right = null;
}
else
{
board[boardRow, boardCol].right = board[cellRow, cellCol];
}
cellNumber = (int)items[4];
cellRow = cellNumber / 6;
cellCol = cellNumber % 6;
if (cellNumber == -1)
{
board[boardRow, boardCol].down = null;
}
else
{
board[boardRow, boardCol].down = board[cellRow, cellCol];
}
}
}
}
}
}
使用此代碼初始化大型陣列的游戲板。 然后為牆的位置添加空值,確保將牆添加到兩個單元格中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
cell game = new cell(90, 100);
}
}
public class cell
{
public static cell[,] board = null;
public int index { get; set; } //row number * 6 + col
public int row { get; set;}
public int col { get; set;}
public cell up { get; set; }
public cell down { get; set; }
public cell left { get; set; }
public cell right { get; set; }
public bool visited { get; set; }
public cell() { }
public cell(int rows, int cols)
{
board = new cell[rows, cols];
int cellNumber = 0;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
board[row, col] = new cell();
board[row, col].visited = false;
}
}
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
cellNumber = (row * cols) + col;
board[row, col].index = cellNumber;
board[row, col].row = row;
board[row, col].col = col;
if (col == 0)
{
board[row, col].left = null;
}
else
{
board[row, col].left = board[row, col - 1];
}
if (row == 0)
{
board[row, col].up = null;
}
else
{
board[row, col].up = board[row - 1, col];
}
if (col == cols - 1)
{
board[row, col].right = null;
}
else
{
board[row, col].right = board[row, col + 1];
}
if (row == rows - 1)
{
board[row, col].down = null;
}
else
{
board[row, col].down = board[row + 1, col];
}
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.