“is_chordal(graph)” 总是返回 False。

huangapple go评论118阅读模式
英文:

is_chordal(graph) always returns False

问题

我正在尝试编写一个函数来检查图是否是弦图,但它总是返回False。 有什么想法吗?

英文:

I am trying to write a function to check if a graph is chordal but it always returns False.

def lexbfs(graph):
    queue = deque()  
    result = []  
    
    if len(graph) == 0:
        return result
    
    visited = set() 
        
    start_node = next(iter(graph))  
    
    queue.append(start_node)
    visited.add(start_node)

    while queue:
        node = queue.popleft()
        result.append(node)
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)

    return result

def is_chordal(graph):
    reversed_bfs_order = lexbfs(graph)[::-1]
    
    for u in reversed_bfs_order:
        neighbors_u = set(graph[u]) 
        
        for v in reversed_bfs_order:  
            if v in neighbors_u:      
                neighbors_v = set(graph[v])  
               
                A = neighbors_u - {v}
                if not A.issubset(neighbors_v):   
                    return False
    
    return True

Any idea?

答案1

得分: 1

I had a look at the algorithm on wikipedia, and it seems your code for is_chordal is off on a few points: you should look for the earlier neighbors of u and v, not all neighbors; furthermore, you shouldn't restart from the initial neighbors_u for every v, but from the last one. Here's my fixed version of the function (note that I only tested it on a basic diamond shape and on a triangle, so I may have overlooked something):

我查看了维基百科上的算法,发现您的is_chordal代码存在一些问题:您应该查找u和v的较早邻居,而不是所有邻居;此外,您不应该为每个v从初始的neighbors_u重新开始,而应该从上一个邻居继续。以下是我修复的函数版本(请注意,我只在基本的菱形和三角形上进行了测试,所以可能有遗漏的地方):

def is_chordal(graph):
    reversed_bfs_order = lexbfs(graph)[::-1]
    
    for i, u in enumerate(reversed_bfs_order):
        neighbors_u = set(graph[u]).intersection(reversed_bfs_order[i+1:]) 
        
        for j, v in enumerate(reversed_bfs_order[i+1:]):  
            if v in neighbors_u:      
                neighbors_v = set(graph[v]).intersection(reversed_bfs_order[i+j+1:])
               
                neighbors_u.remove(v)
                if not neighbors_u.issubset(neighbors_v):   
                    return False
    
    return True

Examples

示例:

diamond = {'A':('B', 'C', 'D'), 'B':('A','C'), 'C':('A','B', 'D'), 'D':('A','C')}
is_chordal(diamond)
Out[80]: True
triangle = {'A':('B', 'C'), 'B':('A','C'), 'C':('A','B')}
is_chordal(triangle)
Out[80]: True
英文:

I had a look at the algorithm on wikipedia, and it seems your code for is_chordal is off on a few points: you should look for the earlier neighbors of u and v, not all neighbors; furthermore, you shouldn't restart from the initial neighbors_u for every v, but from the last one. Here's my fixed version of the function (note that I only tested it on a basic diamond shape and on a triangle, so I may have overlooked something):

def is_chordal(graph):
    reversed_bfs_order = lexbfs(graph)[::-1]
    
    for i, u in enumerate(reversed_bfs_order):
        neighbors_u = set(graph[u]).intersection(reversed_bfs_order[i+1:]) 
        
        for j, v in enumerate(reversed_bfs_order[i+1:]):  
            if v in neighbors_u:      
                neighbors_v = set(graph[v]).intersection(reversed_bfs_order[i+j+1:])
               
                neighbors_u.remove(v)
                if not neighbors_u.issubset(neighbors_v):   
                    return False
    
    return True

Examples

diamond = {'A':('B', 'C', 'D'), 'B':('A','C'), 'C':('A','B', 'D'), 'D':('A','C')}
is_chordal(diamond)
Out[80]: True
triangle = {'A':('B', 'C'), 'B':('A','C'), 'C':('A','B')}
is_chordal(triangle)
Out[80]: True

答案2

得分: 0

以下是翻译好的部分:

def is_chordal(graph):
    reversed_bfs_order = lexbfs(graph)[::-1]
    
    for u in reversed_bfs_order:
        neighbors_u = set(graph[u]) 
        
        for v in reversed_bfs_order:  
            if v in neighbors_u:      
                neighbors_v = set(graph[v])  
               
                A = neighbors_u - {v}
                if not A <= neighbors_v:   # corrected condition
                    return False
    
    return True

在你的代码中,条件是 if not A.issubset(neighbors_v): return False,这个条件检查的是除了 v 外,u 的所有邻居是否也是 v 的邻居,但它并没有考虑到那些既不是 u 的邻居也不是 v 的邻居之间的关系。这可能导致误报,就像在你的情况中发生的那样。

相比之下,在修正后的条件中,它会检查除了 v 外,u 的所有邻居是否也是 v 的邻居,包括那些既不是 u 的邻居也不是 v 的邻居的情况。

英文:

There is an issue with your is_chordal function. Perhaps this could be the correct implementation:

def is_chordal(graph):
    reversed_bfs_order = lexbfs(graph)[::-1]
    
    for u in reversed_bfs_order:
        neighbors_u = set(graph[u]) 
        
        for v in reversed_bfs_order:  
            if v in neighbors_u:      
                neighbors_v = set(graph[v])  
               
                A = neighbors_u - {v}
                if not A &lt;= neighbors_v:   # corrected condition
                    return False
    
    return True

In your code, where the condition is 'if not A.issubset(neighbors_v): return False', this condition checks if all the neighbours of u except v are also neighbors of v, but it doesn't consider the relationship between the neighbors of u that are not neighbors of v. This can lead to a false negative, as is happening in your case.

Whereas in the corrected condition, the condition checks if all the neighbors of u except v are also neighbors of v, including the neighbors of u that are not neighbors of v.

huangapple
  • 本文由 发表于 2023年5月14日 01:48:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定