2015-04-12 155 views
0

所以我現在有一個圖的邊緣列表。有了這個列表,我試圖建立一個鄰接圖,其中的關鍵是一個邊,值是一個與邊相鄰的邊的列表。我使用了一個嵌套循環,將列表中的每條邊與列表中的每條邊進行比較。但是,這並不是構建我期望的地圖。以下是我的代碼:Ruby中嵌套循環的問題

def build_adjacency 
     @paths.each do |start_path| 
      @paths.each do |end_path| 
       # 3 cases for edge adcency 
       if (start_path.end_node == end_path.start_node) || (start_path.start_node == end_path.end_node) || (start_path.start_node == end_path.start_node) 
        if @adjacency_map.has_key?("#{start_path}".to_s) 
         @adjacency_map[:"#{start_path}".to_s] << end_path 
        else 
         value = [end_path] 
         @adjacency_map[:"#{start_path}".to_s] = value 
        end 
       end 
      end 
     end 
end 

我也試過array.combination,但那也行不通。感謝您的幫助。

測試輸入:(開始節點,端節點,顏色,類型)

A B R C 
B E B C 
B C B T 
C D G T 

輸出爲@adjacency_map:

C:\Users\Jin\Documents\Mines\Algorithms (CSCI 406)\Project_3>ruby graph.rb 
Key: A B R C Value: [#<Path:0x2548a28 @start_node="A", @end_node="B", @color= 
"R", @type="C">, #<Path:0x2548968 @start_node="B", @end_node="E", @color="B", @t 
ype="C">, #<Path:0x25488a8 @start_node="B", @end_node="C", @color="B", @type="T" 
>, #<Path:0x25487e8 @start_node="C", @end_node="D", @color="G", @type="T">] 
Key: B E B C Value: [#<Path:0x2548a28 @start_node="A", @end_node="B", @color= 
"R", @type="C">, #<Path:0x2548968 @start_node="B", @end_node="E", @color="B", @t 
ype="C">, #<Path:0x25488a8 @start_node="B", @end_node="C", @color="B", @type="T" 
>, #<Path:0x25487e8 @start_node="C", @end_node="D", @color="G", @type="T">] 
Key: B C B T Value: [#<Path:0x2548a28 @start_node="A", @end_node="B", @color= 
"R", @type="C">, #<Path:0x2548968 @start_node="B", @end_node="E", @color="B", @t 
ype="C">, #<Path:0x25488a8 @start_node="B", @end_node="C", @color="B", @type="T" 
>, #<Path:0x25487e8 @start_node="C", @end_node="D", @color="G", @type="T">] 
Key: C D G T Value: [#<Path:0x2548a28 @start_node="A", @end_node="B", @color= 
"R", @type="C">, #<Path:0x2548968 @start_node="B", @end_node="E", @color="B", @t 
ype="C">, #<Path:0x25488a8 @start_node="B", @end_node="C", @color="B", @type="T" 
>, #<Path:0x25487e8 @start_node="C", @end_node="D", @color="G", @type="T">] 
+0

難道你還發布了輸入,輸出你得到和預期產出?它有助於這些細節。 –

+0

那麼,我正在閱讀的文本文件中包含邊緣(起始節點和結束節點)的輸入。我只是輸出我的整個地圖來檢查它是否構建了正確的地圖。這個帖子太長了。但是我的循環結構看起來是否正確,比較數組中的每個元素與數組中的每個其他元素? – JOH

+0

一個小例子就足夠了,就像你可以從文件中讀取的2-3個節點以及該鄰接圖應該是什麼樣的等等。 –

回答

0

以下是奇怪:

:"#{start_path}".to_s 

什麼永遠對你的對象start_path是,你通過插值將它轉換爲一個字符串,而不是將其轉換爲符號,在上然後再將其轉換爲字符串。你可以使用字符串作爲散列鍵。在您撥打has_key?時,您並未使用冒號。 (通常應該沒有區別)

此外,如果您不確定您是否正確實施了條件,我建議您創建一個封裝它的方法。特別是當條件具有語義意義時。

+0

沒有'to_s',它沒有做正確的比較(出於某種原因)。添加'to_s'後,它工作。我仍然不確定爲什麼。我可能已經解決了我自己的問題。謝謝。 – JOH

0

看來只有你的代碼有問題,它不檢查start_pathend_path是否相同。因此,它會將不必要的「A-B與A-B相鄰」添加到您的地圖中。

也許你應該嘗試只添加一行?

def build_adjacency 
    @paths.each do |start_path| 
     @paths.each do |end_path| 
      next if start_path == end_path # this one! 

      # 3 cases for edge adcency 
      if (start_path.end_node == end_path.start_node) || (start_path.start_node == end_path.end_node) || (start_path.start_node == end_path.start_node) 
       if @adjacency_map.has_key?("#{start_path}".to_s) 
        @adjacency_map[:"#{start_path}".to_s] << end_path 
       else 
        value = [end_path] 
        @adjacency_map[:"#{start_path}".to_s] = value 
       end 
      end 
     end 
    end 
end 

這裏是我完整的代碼,複製解決方案:https://gist.github.com/zverok/6785c213fd78430cd423