[英]Find the shortest distance between two squares on a game board
我將游戲板上的路徑存儲在字典中,其格式如下所示:
{1: [2,3,4], 2: [1,3,5], 3: [1,2,4], ...}
這意味着如果您位於空間1,則可以移至空間2、3或4,依此類推。 每個鍵都鏈接到列表中的至少兩個值。 許多有四個或更多。 板上總共有199個空間。 一個值得注意的收獲是,有時您可能可以跳過空格,所以在...
{1:[2,3,4], 2:[3]}
...您可以執行1-> 2-> 3,也可以執行1-> 3。
我正在尋找一種算法來查找任何兩個正方形之間的最短距離。 顯而易見的想法是查找起始空格的鍵,然后獲取列表中的第一個數字,查找可能的空格,依此類推,當遇到先前看到的數字時,停止並返回上一個列表或最后一個平方(如果到達結果平方則存儲路徑和距離,完成后進行比較)。
不過,我對如何開始實施此計划知之甚少。 (如果只有兩個步驟,我將使用嵌套循環,但是顯然這在這里不起作用,因為我不知道它可能會深入多少層)。
歡迎更好的解決方案或涉及其他數據結構的優化; 我將數據存儲在類似於此字典的CSV文件中,因此如果可以更好地工作,我可以輕松地將其轉換為其他內容。
這是我正在使用的董事會圖片的鏈接: http : //goo.gl/Rasq6
編輯:好的,我正在嘗試實現Dijkstra的算法。 這是我得到的:
1 movedict, transdict = boardstruct.prepare_board()
2
3 source = 87
4 dest = 88
5
6 dist = {}
7 prev = {}
8 for v in movedict.keys():
9 dist[v] = float('inf')
10 prev[v] = None
11
12 dist[source] = 0
13 q = movedict.keys()
14
15 while q:
16 smallest = float('inf')
17 for i in q:
18 dist_to = dist[i]
19 if dist_to < smallest:
20 smallest = dist_to
21 print smallest
22 u = q.pop(smallest)
23 print u
24
25 if dist[u] == float('inf'):
26 break
27
28 for v in movedict[u]:
29 alt = dist[u] + 1 # distance = flat 1
30 if alt < dist[v]:
31 dist[v] = alt
32 prev[v] = u
33 # reorder queue?
(21和23是我忘記刪除的調試語句)
我正在從Wikipedia(http://en.wikipedia.org/wiki/Dijkstra's_algorithm#Pseudocode)處理偽代碼,因為我找不到與我所需的數據格式相匹配的任何現有實現(每一步都有固定成本,因此距離不會存儲在任何地方)。
我知道我需要在最后對隊列重新排序,但是我不確定如何進行排序。 我也不明白第25行和第26行是什么意思(評論說“從源頭無法訪問所有其余的頂點”,這是否會使它在確保已經找到最佳路徑的情況下無法繼續運行?)。 我可能也弄亂了其他東西,所以如果您可以查看一下,我將不勝感激。
您所描述的是最短路徑問題 。 有幾種解決方法。 Dijkstra的算法是最簡單的算法之一,但是對於您的應用程序來說卻是過大的選擇。 (它找到從一個節點到所有其他節點的最短路徑。)有一個稱為A *的相關算法,它稍微復雜一點,但是它確實可以滿足您的需求。
使用networkx 。 它易於安裝。
從游戲板上的圖片可以看出蘇格蘭場游戲。
評論您與@Bill the Lizard的對話:
您確實可以預先計算所有最短的路徑。 節點和邊緣都不會改變。
您可以通過5個出租車台階或1個地下台階從13
到達46
。
我可能會使用一個包含所有邊(出租車,公共汽車,地鐵)的“大”圖,以及幾個將出租車+公共汽車,出租車+地下和出租車相結合的圖表(我不太記得游戲規則...您必須弄清楚什么才有意義)。
我不確定networkx中的算法如何處理聯系!
因此,請預先計算所有最短的路徑。
然后只需在需要時查找它們。
import networkx as nx
# simplified example
# data is in the format as you specified
data = data = {1: [2,3,4],
2: [1,3,5],
3: [1,2,4],
4: [1,3,5],
5: [2,4]}
# initialize empty graph
G = nx.graph()
# now we're adding all edges
# don't bother about duplicates -- they're ignored
for n1, n in data.items():
for n2 in n:
G.add_edge(n1, n2)
# get ALL shortest paths
p = nx.shortest_path(G)
# lookup when needed, e.g. from 1 to 5
p[1][5]
# gives [1, 2, 5]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.