2013-12-13 27 views
0

迅速建立結構的列表,我試圖建立一些基本的對象來存儲圖:在一個新的結構

Vertex = Struct.new(:parent, :rank) 
Graph = Struct.new(:vertexes, :edges) 
Edge = Struct.new(:weight, :endpoints) 

這裏的想法是,:endpoints(和:parent)爲頂點,並且,自然,Graph存儲頂點和邊的列表。我試圖設置此,我遇到了麻煩:

[47] pry(main)> t_graph = Graph.new() 
=> #<struct Graph vertexes=nil, edges=nil> 
[48] pry(main)> t_graph[:vertexes] = Array.new(Vertex.new()) 
TypeError: can't convert Vertex into Integer 
from (pry):48:in `initialize' 

在另一方面,這個工程:

[49] pry(main)> t_graph[:vertexes] = [Vertex.new(), Vertex.new()] 
=> [#<struct Vertex parent=nil, rank=nil>, 
#<struct Vertex parent=nil, rank=nil>] 

有什麼有效的方法來生成一個圖表空頂點的質量(或任何這樣的關係)進行測試?

回答

0

的一種方式頂點列表將被使用.times,這似乎有點笨拙,但創建一個列表(我增加了一個:id值):

t_verts = [] 
9.times do t_verts << Vertex.new end 
[10] pry(main)> t_verts 
=> [#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>, 
#<struct Vertex parent=nil, rank=nil, id=nil>] 

這將創建不同的對象。

[11] pry(main)> t_verts.each do |vert| 
[11] pry(main)* vert.id = rand 
[11] pry(main)* end 
=> [#<struct Vertex parent=nil, rank=nil, id=0.755245226082449>, 
#<struct Vertex parent=nil, rank=nil, id=0.0167377598961559>, 
#<struct Vertex parent=nil, rank=nil, id=0.759799975185007>, 
#<struct Vertex parent=nil, rank=nil, id=0.613897002692335>, 
#<struct Vertex parent=nil, rank=nil, id=0.0407847317079812>, 
#<struct Vertex parent=nil, rank=nil, id=0.549475744759297>, 
#<struct Vertex parent=nil, rank=nil, id=0.571876769381891>, 
#<struct Vertex parent=nil, rank=nil, id=0.270800829904956>, 
#<struct Vertex parent=nil, rank=nil, id=0.814754555208641>] 

爲了集體添加這些到圖形,Simone的方法可以用來頂點的列表添加到圖表:

def add_vertex(new_verts) # Adds or updates vertexes non-destructively 
    new_verts.each do |new_vert| 
     # first case, redundant insert 
     if self.vertexes.include?(new_vert) 
     warn "Vertex already exists in graph, no replacement done" 
     # second case, update 
     elsif not (update_vert = self.vertexes.select { |vert| vert.id == new_vert.id }).empty? 
     self.vertexes[self.vertexes.index(update_vert)] = new_vert 
     # third case, append new 
     else 
     self.vertexes ||= [] 
     self.vertexes << vertex 
     end 
    end 
    end 

它看起來像我需要建立一個建立一個構造函數方法來自鄰接列表和權重列表的圖形;我沒有看到一個簡單的方法來完成這一步。

2

Array.new不是用數值初始化數組的標準方法。如果你想創建一個頂點例如數組,使用

t_graph[:vertexes] = [Vertex.new] 

如文檔中所描述的,Array.new需要數組或數組的一個Fixnum大小。

new(size=0, obj=nil) 
new(array) 
new(size) {|index| block } 

返回一個新數組。

在第一種形式中,如果未發送任何參數,則新數組將爲 爲空。當發送大小和可選的obj時,會創建一個大小爲obj的副本的數組 。請注意,所有元素都將引用 相同的對象obj。

第二種形式創建作爲參數傳遞的數組副本(通過在參數上調用#to_ary生成 數組)。

還有一件事:當沒有參數時可以省略括號。

t_graph[:vertexes] = [Edge.new, Edge.new] 

代替

t_graph[:vertexes] = [Edge.new(), Edge.new()] 

請記住,您可以添加方法的Structs。

Graph = Struct.new(:vertexes, :edges) do 
    def add_vertex(vertex) 
    self.vertexes ||= [] 
    self.vertexes << vertex 
    end 
end 

g = Graph.new 
g.add_vertex(Vertex.new) 
+0

所以,我只需要編寫一個函數,它需要一個父類和行列的數組來創建用於填充測試圖的頂點?看起來過於複雜。 –

+1

我更新了一下我的代碼。我並不完全明白你想要達到的目標,但我舉了一個例子來給你一些基本的想法。 –

+0

我嘗試過使用上面給出的附加方法,但它似乎解開了輸入;我最終在'a_graph.edges'中得到了一個平坦的數組,並在每個Vertex中存儲了每個值。 –

1

我不同意Array.new在這裏沒有用處。在下面找到解決了海報的問題我的使用情況下,即使這已經顯示,但是上面沒有得到很好的解釋:

[31] pry(main)> Vertex = Struct.new(:parent, :rank) 
    => Vertex 
    [32] pry(main)> Graph = Struct.new(:vertexes, :edges) 
    => Graph 
    [33] pry(main)> Edge = Struct.new(:weight, :endpoints) 
    => Edge 
    [34] pry(main)> t_graph = Graph.new() 
    => #<struct Graph vertexes=nil, edges=nil> 
    [35] pry(main)> t_graph[:vertexes] = Array.new(2) { Vertex.new } 
    => [#<struct Vertex parent=nil, rank=nil>, #<struct Vertex parent=nil, rank=nil>] 
    [36] pry(main)> t_graph[:vertexes] = Array.new(2, Vertex.new) 
    => [#<struct Vertex parent=nil, rank=nil>, #<struct Vertex parent=nil, rank=nil>] 

如行[35]您可以撥打Array.new提供您的陣列中希望元素的顯示數量這種情況下,2,哪些元素應該是在這種情況下Vertex.new

詹姆斯·愛德華·格雷II做了Avdi格林播客談話(無廣告的意圖在這裏),清楚地說明了一個非常類似的例子來簡單地填充

+0

這似乎創建了多個對同一'Vertex'對象的引用。 –

+0

@TrevorAlexander我給了2種方法,第一種創建不同的對象,而第二種創建多個引用 – bjhaid

+0

Wierd!我認爲我犯了一個錯誤。 –