簡體   English   中英

Dijkstra算法代表邊緣權重的最有效方法是什么

[英]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。

一些可以幫助您決定應該做什么的指針:

  1. 看來您的圖未加權,因此可以使用BFS ,在這種情況下,它比Dijkstra的算法更易於實現且效率更高。
  2. 對於現代機器,90x90矩陣幾乎不是問題(除非您要在非常緊密的循環中使用尋路算法)
  3. 如果您使用double作為權重,則許多語言都具有可以使用的無窮大值。 在Java中為Double.POSITIVE_INFINITY 關於無限的美麗-與您添加的無限一樣,它保持無限(並且不會像整數一樣溢出)。
  4. 您可以始終使用鄰接列表 ,該列表可以看作是矩陣的稀疏實現-大多數矩陣具有恆定的預定義權重(例如,對於不存在的邊緣為無窮大)。
  5. 請注意,對於非常稀疏的圖(如您的圖),使用鄰接矩陣而不是鄰接列表會使BFS的時間復雜度變為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM