Ruby中的嵌套循环问题

时间:2015-04-12 21:06:36

标签: ruby graph nested-loops

所以我现在有一个图表边缘列表。通过这个列表,我试图构建一个邻接映射,其中的键是一个边,值是一个与边相邻的边列表。我使用嵌套循环将列表中的每个边缘与列表中的每个其他边缘进行比较。但是,这并没有构建我期望的地图。以下是我的代码:

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">]

2 个答案:

答案 0 :(得分:0)

以下是奇怪的:

:"#{start_path}".to_s

您的对象start_path的类是什么,通过插值将其转换为字符串,而不是将其转换为符号,然后再将其转换为字符串。您可以只使用字符串作为哈希键。在致电has_key?时,您没有使用冒号。 (通常应该没有区别)

另外,如果您不确定是否正确实现了条件,我建议创建一个封装它的方法。特别是当条件具有语义含义时。

答案 1 :(得分: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