英文:
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 <= 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论