最初,将0(w)= 0的所有节点w设置为采用者 (所有其他节点都以nonadopters开头) 直到采用者集合没有变化:
For each nonadopter w simultaneously:
If at least a O(w) fraction of nodes with edges to w are adopters then
0(w) becomes an adopter
Endif
Endfor
输出最终采用者集
答案 0 :(得分:0)
正如目前所写的那样,你的算法的复杂性会因多次处理非采用者节点而受到影响 - 如果你有一个折线图并且最后一个节点是唯一的采用者,那么在每次迭代时你都会按顺序处理N个节点,你将有N次迭代,因为你只是在每次迭代时将一个非采用者转变为采用者。您可以通过使用非采用者队列来改进这一点(例如,在Java中,您可以使用ConcurrentLinkedQueue) - 每次将非采用者转换为采用者时,您都会将其非采用者邻居排入队列
如果非采用者是两个非采用者的邻居,那么非采用者可能会被排队两次,因此您需要某种方法来防止非采用者被添加两次。一种方法是使用并发哈希映射,例如,在Java中ConcurrentHashMap,包含需要处理成采用者的非采用者。如果某个节点不在地图中,则将其添加(例如,使用putIfAbsent
作为Java地图),然后将其添加到工作队列中;如果它已经在地图中,那么它已经被添加到队列中,所以不要再添加它。一旦节点变成了采用者,那么将其从地图中删除可能是安全的,只要注意任何潜在的竞争条件。
如果你不想/需要这个并发,那么只需使用一个工作线程和一个不同步的队列和映射 - 我的假设是你想根据simultaneously
的使用同时处理节点在您的伪代码中。
向队列添加节点是O(1),并且由于映射,每个节点只能添加到队列一次,因此在最坏的情况下,您将所有节点添加到O(n)中的队列中。在最坏的情况下,每个节点都连接到每个其他节点,因此对于队列中的每个节点,您需要遍历图中的每个节点以查看它是否为非采用者,从而产生O(n ^ 2)算法