2014-02-07 43 views
0

所以我在這裏有這個代碼,它基本上在Python中的圖表上運行Dijkstra的Algortihm,然後打印距離並移動它從開始到結束所需的距離。我的問題是,我無法弄清楚如何使用sys.argv將圖形導入爲.txt文件,並讓它讀取它並在其上運行算法。這裏是我的代碼,其中有一個圖形,開始'a'和結束'b'已經填入它。 (它應該工作)。Python:導入圖表

import sys 

def shortestpath(graph,start,end,visited=[],distances={},predecessors={}): 
    """Find the shortest path between start and end nodes in a graph""" 
    # we've found our end node, now find the path to it, and return 
    if start==end: 
     path=[] 
     while end != None: 
      path.append(end) 
      end=predecessors.get(end,None) 
     return distances[start], path[::-1] 
    # detect if it's the first time through, set current distance to zero 
    if not visited: distances[start]=0 
    # process neighbors as per algorithm, keep track of predecessors 
    for neighbor in graph[start]: 
     if neighbor not in visited: 
      neighbordist = distances.get(neighbor,sys.maxsize) 
      tentativedist = distances[start] + graph[start][neighbor] 
      if tentativedist < neighbordist: 
       distances[neighbor] = tentativedist 
       predecessors[neighbor]=start 
    # neighbors processed, now mark the current node as visited 
    visited.append(start) 
    # finds the closest unvisited node to the start 
    unvisiteds = dict((k, distances.get(k,sys.maxsize)) for k in graph if k not in visited) 
    closestnode = min(unvisiteds, key=unvisiteds.get) 
    # now we can take the closest node and recurse, making it current 
    return shortestpath(graph,closestnode,end,visited,distances,predecessors) 



if __name__ == "__main__": 
    graph = {'a': {'w': 14, 'x': 7, 'y': 9}, 
      'b': {'w': 9, 'z': 6}, 
      'w': {'a': 14, 'b': 9, 'y': 2}, 
      'x': {'a': 7, 'y': 10, 'z': 15}, 
      'y': {'a': 9, 'w': 2, 'x': 10, 'z': 11}, 
      'z': {'b': 6, 'x': 15, 'y': 11}} 
    print(shortestpath(graph,'a','b')) 


    """ 
    Result: 
     (20, ['a', 'y', 'w', 'b']) 
     """ 

現在,這裏是我嘗試導入圖形,它被稱爲採樣的map.txt:

{'a': {'b': 5, 'c': 8}, 
'b': {'a': 5, 'd': 6}, 
'c': {'a': 8, 'd': 2}, 
'd': {'b': 6, 'c': 2, 'e': 12, 'f': 2}, 
'e': {'d': 12, 'g': 3}, 
'f': {'d': 2, 'g': 7}, 
'g': {'e': 3, 'f':7}} 

我只需要弄清楚如何使用sys.argv中導入,然後然後讓它代替.py中的圖形。此外,能夠使用sys.argv中定義一個起點和終點將是很好過,像在格式>蟒蛇file.py年底開始樣品的map.txt 凡

sys.argv[0] is file.py 
sys.argv[1] is start 
sys.argv[2] is end, 
and sys.argv[3] 

是圖我想導入。謝謝!

+0

爲什麼要「使用sys.argv導入它」? – Bach

+0

因此,用戶可以從他們自己的計算機導入任何圖形,而不必將其放入代碼中,然後運行它。 – nanowaffle

+0

您可以使用'ast.literal_eval'從字符串中解析字典格式(存儲在我假設的文件中)。 – Aleph

回答

0

如果sys.argv[3]是包含要導入的圖形文件的名稱,你可以使用ast.literal_eval

with open(sys.argv[3], "r") as f: 
    graph = ast.literal_eval(f.read()) 
# If you don't trust your users, check that graph is indeed a dict 
# and that it has the right structure 
+0

謝謝,這真的很好:) – nanowaffle

0

你有三個選擇:

  1. JSON編碼器/解碼器:Python字典非常相似JSON格式,你可以導入指定爲JSON格式的字典文件,然後將它們轉換成Python字典。這可能適用於你的情況。仔細看json.load(file)方法,使用類似json.load(sys.argv[3])的東西值得一試。看看http://docs.python.org/2/library/json.html
  2. 您也可以使用readlines讀取整個文件,並手動將行轉換爲字典。更笨重,但可行
  3. [編輯]我剛看到一條評論,談論ast.literal_eval。再說一遍,這不會直接給你一本字典。你將不得不編寫一些代碼將其轉換成字典。
0

我想你想要的文件「樣品地圖的內容傳送。 txt「轉換成字典。如果您可以確保該文件的內容服從Python的語法語法。您可以使用下面的代碼來做好這項工作:

# sys.argv[3] should be 'sample-map.txt' 
graph=eval(open(sys.argv[3],'r').read()) 
0

這個版本將工作:

import sys,json 

def shortestpath(graph,start,end,visited=[],distances={},predecessors={}): 
    ... 
    return shortestpath(graph,closestnode,end,visited,distances,predecessors) 

if __name__ == "__main__": 

    start_node=sys.argv[1] 
    end_node=sys.argv[2] 
    filename=sys.argv[3] 

    #here we load file text content 
    with open(filename,"r") as f: 
    cont= f.read() 

    #here we convert text content to dict 
    graph=json.loads(cont) 

    print(shortestpath(graph,start_node,end_node)) 

必須使用字符,而不是字符分隔鍵& 「sample-map.txt」文件中的值。(尊重JSON語法)

像這樣: {「a」:{「b」:5,「c」:8}, 「b」:{「a」:5,「d」:6 }, 「c」:{「a」:8,「d」:2}, 「d」:{「b」:6,「c」:2,「e」:12,「f」:2 }, 「e」:{「d」:12,「g」:3}, 「f」:{「d」:2,「g」:7}, 「g」:{「e」 3, 「F」:7}}

如果你尊重圖形文本文件中的JSON語法,當您從終端調用程序:

python shortestpath.py a b sample-map.txt 

你會得到很好的答案!

>>>(5, ['a', 'b'])