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

Algorithm 有没有办法在一个集合中找到相同的值,algorithm,parallel-processing,duplicates,computation-theory,Algorithm,Parallel Processing,Duplicates,Computation Theory,这是我目前使用的算法,运行时间为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

这是我目前使用的算法,运行时间为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;

其思想是利用所有值都在
1
n
之间这一事实

假设一个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
以下是另一个版本,以防内存如何工作仍存在不确定性:

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]
都是在所有的写作之前进行的。

您的机器型号是什么?您可以有多个副本吗?对于I=0到n-1,并行进行A[wins[I]]=A[I],
的目的是什么?CRCW PRAM在写入不同值时的行为是什么?能否使用n/2处理器将每个数字从0散列到n/2,然后使用n/2处理器对每个散列进行比较?关于沟通的一些细节需要解决,但这应该是预期的时间。(它还需要在O(1)时间内进行散列,因此您需要按照DE要求澄清机器型号)。我使用
abs(.)
来处理另一个处理器可能将
A[I]
设置为负值的事实。但是,如果所有的第一个操作都是并行执行的,然后是
k=A[i]
,然后是
A[k]…
,则不需要使用
abs(.)
。请参阅第二个版本。此代码没有意义。如果同时进行所有测试,则没有A为负值。否则,结果可能是随机的。@YvesDaoust当存在重复项时,在同一位置写入。我假设这种理论记忆能够通过序列化不同的作品来管理并发写作。这通常是用实内存完成的(例如C++的代码>原子< /代码>。结果不会受到一个特定访问在另一个之前执行的事实的影响。您错过了我的评论。1) 如果所有进程都执行第一个语句,则没有人停止(在第二轮中,所有人都停止!)。2) 序列化的文字可能会导致O(n)的复杂性。@YvesDaoust问题是这里的内存如何工作还没有明确定义。我修改了函数,使其更具弹性。关于第2点,我注意在检测到重复时立即停止整个过程,以避免重复。
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