永久联盟发现(偶尔删除)

时间:2018-12-16 20:05:36

标签: algorithm persistence union-find

我在数据库中存储了一套五十万个项目,需要执行以下操作:

  • union(x, y)就像在联合查找中一样
  • findAll(x)找到所有y使得find(x) == find(y)
  • ununion(x, y)恢复先前的联合操作

这是一个实际问题,已知以下知识

  • 分区通常很小(少于100个元素),但不能保证。
  • union操作的速度无关紧要。
  • findAll必须快速并且需要用SQL来实现(没有递归/ CONNECT BY)。
  • 有时我们发现,某些union实际上是错误的,需要撤消它,同时保留所有之前和之后的union。此操作非常罕见,因此速度无关紧要。
  • findAll不必立即查看其他操作所做的更改。可以进行一些后期处理。

经典的Union-Find算法需要路径压缩(或变体)以提高效率,并且不允许删除边缘(即使没有路径压缩)。我知道Dynamic connectivity,但似乎不适用于我的用例。

我想我们不能使用它,因为findAll的速度是最重要的。可能应该将所有节点直接链接到根。

关于ununion,我唯一的想法是分别存储所有union操作,然后在ununion上删除相应分区中的所有链接并重做所有相关的union

听起来像是蛮力的...


在开始执行任何操作之前,我会问是否有更智能的算法?

1 个答案:

答案 0 :(得分:0)

我建议您为集合创建一个哈希函数,并将其与每个root /var/www/; location / { return 301 https://www.example.com$request_uri; } location /l/ { rewrite ^/l/(.*)$ /index.php?p=$1 last; fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; #... } 一起存储在数据库的索引列中。构造x时,您可以计算并存储新的哈希值。在union(x, y)上,使用此索引意味着您将只比较很有可能相同的集合,这使它相当快。而且查询没有任何花哨的地方,因此您可以在朴素的SQL中合理地实现它。