2017-05-21 56 views
2

我對我的K最短路徑算法有某些問題。該代碼給出:K最短路徑Python不工作

def K_shortest_Paths(graph,S,T,K=4): 
    '''Initialize Variables Accordingly''' 
    B = {} 
    P = set() 
    count = {} 
    for U in graph.keys(): 
     count[U] = 0 
    B[S] = 0 
    '''Algorithm Starts''' 
    while(len(B)>=1 and count[T]<K): 
     PU = min(B,key=lambda x:B[x]) 
     cost = B[PU] 
     U = PU[len(PU)-1] 
     del B[PU] 
     count[U] += 1 
     if U==T: 
      P.add(PU) 
     if count[U]<=K: 
      V = graph[U].keys() 
      for v in V: 
       if v not in PU: 
        PV = PU+v 
        B[PV] = cost+1   
    return P 

這相當於https://en.wikipedia.org/wiki/K_shortest_path_routing它提供的僞碼實現。該圖給出爲: 現在,它運行良好,如果我有起始節點S < 10和終止節點T < 10,但與S和T> 10,它返回一個空集,而它應該返回路徑。請注意,我無法使用Networkx庫。我只需要使用基本庫在Python

此外,爲了生成圖表的代碼是這樣的:

def create_dictionary(graph): 
    D = {} 
    for item in graph.items(): 
     temp = {} 
     connected = list(item[1]) 
     key = item[0] 
     for V in connected: 
      temp[str(V)] = 1 
     D[str(key)] = temp 
    return D 

def gen_p_graph(nodes,prob): 
    if prob>1: 
     er='error' 
     return er 
    graph_matrix=np.zeros([nodes,nodes]) 
    num_of_connections=int(((nodes * (nodes-1)) * prob )/2) 
    num_list_row=list(range(nodes-1)) 
    while(np.sum(np.triu(graph_matrix))!=num_of_connections): 
      row_num=random.choice(num_list_row) 
      num_list_col=(list(range(row_num+1,nodes))) 
      col_num=random.choice(num_list_col) 
      if graph_matrix[row_num,col_num]==0: 
       graph_matrix[row_num,col_num]=1 
       graph_matrix[col_num,row_num]=1 

    #create dictionary 
    df=pd.DataFrame(np.argwhere(graph_matrix==1)) 
    arr=np.unique(df.iloc[:,0]) 
    dct={} 
    for i in range(graph_matrix.shape[0]): 
     dct[str(i)]=set() 
    for val in arr: 
     dct[str(val)].update(df.loc[df.iloc[:,0]==val].iloc[:,1].values) 

    return pd.DataFrame(graph_matrix),dct 

我運行它是這樣的:

graph= create_dictionary(gen_p_graph(100,0.8)[1]) 
K_shortest_Paths(graph,'11','10') 

返回一個空集,而它應該返回路徑。

+0

你爲T傳遞了什麼論點? – EyuelDK

+0

我給了它T = 10,和S = 11 ....非常感謝 –

回答

0

我認爲你正試圖實現。嘗試這個。

def k_shortest_paths(graph, src_node, dest_node, k=4): 
    result = [] 
    pathes = [[src_node]] 
    while len(pathes) > 0 and len(result) < k: 
    path = pathes.pop() 
    last_node = path[-1] 
    if last_node == dest_node: 
     result.append(path) 
    else: 
     for child_node in graph[last_node].keys(): 
     if child_node not in path: 
      pathes.append(path + [child_node]) 
    return result 
+0

好吧,它沒有返回最短路徑,例如,如果兩個節點立即連接(源和目標通過鏈接連接),那麼它不返回該路徑,而應該在我們有單位重量的路徑,所以這是最短的路徑... –

+0

嗯,你確定。我已經通過了邏輯,看起來它應該起作用,尤其是對於你所說的情況。你可以給圖表字典的打印輸出,以便我可以測試它。 – EyuelDK

+0

那麼,我現在得到的圖,在圖中,節點10和11立即連接,但該算法沒有路徑,如['10','11'] ...我也試過了其他情況下一樣,.... –

3

如果您致電K_shortest_Pathes(graph, "11", "10"),您將永遠不會在集合P中添加元素。閱讀我的內嵌評論。

def K_shortest_Paths(graph,S,T,K=4): 
    '''Initialize Variables Accordingly''' 
    B = {} 
    P = set() 
    count = {} 
    for U in graph.keys(): 
     count[U] = 0 

    # currently the B has only one item, i.e. { S: 0 } => { "11": 0 } 
    B[S] = 0 

    '''Algorithm Starts''' 
    while(len(B)>=1 and count[T]<K): 

     # results in the only key in B, i.e. PU = S => PU = "11" 
     PU = min(B,key=lambda x:B[x]) 

     cost = B[PU] 

     # U = PU[len(PU) - 1], where PU = "11" => 
     # U = "11"[len("11")-1] => 
     # *** U = "1" 
     U = PU[len(PU)-1] 

     del B[PU] 
     count[U] += 1 

     # *** U == T => "1" == T => "1" == "10" which is False 
     # Thus nothing is ever added to set P 
     if U==T: 
      P.add(PU) 

     if count[U]<=K: 
      V = graph[U].keys() 
      for v in V: 
       if v not in PU: 
        PV = PU+v 
        B[PV] = cost+1   
    return P 
+0

我明白了,這是因爲表示,但我該如何克服這個問題。 ? –

+0

我個人不懂這行代碼'U = PU [len(PU)-1]'你想達到什麼目的?我認爲這行代碼是完全沒有意義的......它打破了你試圖實現的邏輯。 – EyuelDK

+0

我試圖在路徑Pu中獲得頂點U,這將意味着路徑中的最後一個頂點,此頂點U稍後將用於連接路徑中的V並檢查是否已到達終止節點T. –