如何解决教科书Union-Find算法的实现不起作用
我有两种 union-find 的实现:一种是我自己提出的(它有效),另一种是基于教科书的解释(令人惊讶的是,它不起作用)。当我在输入此代码时调试有问题的实现时,也许有人能够指出一个到目前为止我无法理解的错误。
我一直在使用以下内容:
https://www.cl.cam.ac.uk/teaching/1415/Algorithms/disjointsets.pdf
可以在以下位置找到更多信息:
https://en.wikipedia.org/wiki/Disjoint-set_data_structure
https://cp-algorithms.com/data_structures/disjoint_set_union.html
实现代码:
from collections import Counter
def edges2vertices(edges):
return sorted(list({vertex for edge in edges for vertex in edge}))
class UnionFindTextbook:
def __init__(self,vertices):
self._parents = {vertex: vertex for vertex in vertices}
def find(self,s):
if s == self._parents[s]:
return s
self._parents[s] = self.find(self._parents[s])
return self._parents[s]
def union(self,a,b):
a = self.find(a)
b = self.find(b)
if a != b:
self._parents[b] = a
@property
def partitions(self):
return Counter(self._parents.values()).values()
class UnionFindOwn:
def __init__(self,vertices):
self._lookup = {v: idx for idx,v in enumerate(vertices)}
self._forest = [[vertex] for vertex in vertices]
def union(self,b):
a = self.find(a)
b = self.find(b)
if self._should_merge(a,b) and self._can_merge(a,b):
self._forest[a].extend(self._forest[b])
for i in self._forest[b]:
self._lookup[i] = a
self._forest[b] = []
def find(self,a):
return self._lookup[a]
def _should_merge(self,b):
return a != b
def _can_merge(self,b):
return self._forest[a] and self._forest[b]
@property
def partitions(self):
return [len(tree) for tree in self._forest if tree]
def unionfind_min_max(edges,strategy):
vertices = edges2vertices(edges)
uf = strategy(vertices)
for a,b in edges:
uf.union(a,b)
return min(uf.partitions),max(uf.partitions)
测试代码:
import unittest
from typing import List,Tuple
import ddt
from unionfind import unionfind_min_max,UnionFindOwn as STRATEGY
DATA_UNIONFIND_MIN_MAX = [
{ # 1.
# 5
# 3-8
# 4-9
# 1-6-2-7
"edges": [
(1,6),(2,7),(3,8),(4,9),],"strategy": STRATEGY,"expected": (2,4),},]
@ddt.ddt
class TestUnionFind(unittest.TestCase):
@ddt.unpack
@ddt.data(*DATA_UNIONFIND_MIN_MAX)
def test_unionfind_min_max(self,edges: List[Tuple[int]],strategy,expected: Tuple[int]) -> None:
actual = unionfind_min_max(edges,strategy)
self.assertEqual(expected,actual)
有人可以指出 UnionFindTextbook
中的错误吗?
最小可重现示例:
from collections import Counter
def edges2vertices(edges):
return sorted(list({vertex for edge in edges for vertex in edge}))
class UnionFindTextbook:
def __init__(self,b):
a = self.find(a)
b = self.find(b)
if a != b:
self._parents[b] = a
@property
def partitions(self):
return Counter(self._parents.values()).values()
def unionfind_min_max(edges,strategy=UnionFindTextbook):
vertices = edges2vertices(edges)
uf = strategy(vertices)
for a,max(uf.partitions)
edges = [
(1,]
assert unionfind_min_max(edges) == (2,4)
解决方法
我已经设法适当地修改了代码,但我不确定为什么所有的消息来源都没有提到在 union()
操作之后数据结构不会处于所需的状态。
@property
def partitions(self):
return Counter(self.find(i) for i in self._parents).values()
有什么想法吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。