有没有办法在集合中找到相同的值

问题描述

这是我目前拥有的算法,它在 O(1) 时间内运行,但使用了 n^2 个内核:

for i = 0 to n-1 do in parallel
   for j = 0 to n-1 do in parallel
      if (A[i]>A[j]) or (A[i]=A[j] and i>j) then
         wins[i] = 1;
      else
         wins[i] = 0;
for i = 0 to n-1 do in parallel
   A[wins[i]] = A[i];

for i = 0 to n-1 do in parallel
   if win[i] == win[i - 1] or win[i] == win[i + 1]
      return true
   return false

解决方法

在 CRCW 机器上,您可以很好地执行所有比较并写出是否为真。

result= false;
for i = 0 to n-1 do in parallel
   for j = 0 to n-1 do in parallel
      if A[i] == A[j] then
         result= true;

使用较少的处理器似乎很困难,因为除非您使用传递性来推断新的关系,否则特定比较的结果几乎不会为您提供其他比较的信息。可以通过形成两倍大小的“链”来利用传递性,但我不知道如何在恒定时间内完成。


如果存储的值是限制在 [1,n] 范围内的整数,您可以使用直方图:

result= false;
for i = 0 to n-1 do in parallel
   H[i]= 0;
for i = 0 to n-1 do in parallel
   H[A[i]]++;
for i = 0 to n-1 do in parallel
   if H[i] > 1
      result= true;

这假设并发 ++ 可用。如果没有,您可以改用辅助数组,将 i 存储在 A[i] 的位置,假设并发写入导致写入其中一个值。然后在第二遍中,您检查是否还有另一个 A[i]

result= false;
for i = 0 to n-1 do in parallel
   B[i]= 0;
for i = 0 to n-1 do in parallel
   B[A[i]]= i;
for i = 0 to n-1 do in parallel
   if B[A[i]] > 0 and B[A[i]] != i
      result= true;
,

这个想法是利用所有值都在 1n 之间的事实。

假设一个 PRAM 以及并发写入和并发读取。

dup = false
for i = 1 to n do in parallel
    if (A[abs(A[i])]) < 0 : dup = true; stop;
    A[abs(A[i])] = - A[abs(A[i])]
return dup

这种虚构的内存处理并发写入的方式尚不清楚。
我假设内存会通过序列化写入来处理它。 这是一个新的解决方案,更准确地考虑了它。

dup = false
for i = 1 to n do in parallel
    k = A[i]
    A[k] = - A[k]
    If (A[k]) > 0 : dup = true; stop;
return dup

这是另一个版本,以防内存工作方式仍然不确定:

for i = 1 to n do in parallel
    k = A[i]
    A[k] = 0
dup = false
for i = 1 to n do in parallel
    If (A[k]) !=  0 : dup = true;
return dup

注意:在所有提案中,我假设所有读取 k = A[i] 在所有写入之前执行。