Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 当有无限多个CPU时,比较两个数组的最佳方法是什么?_Arrays_Algorithm_Parallel Processing - Fatal编程技术网

Arrays 当有无限多个CPU时,比较两个数组的最佳方法是什么?

Arrays 当有无限多个CPU时,比较两个数组的最佳方法是什么?,arrays,algorithm,parallel-processing,Arrays,Algorithm,Parallel Processing,这是我在面试中遇到的问题。有两个排序的数组A和B。检查数组A中的每个元素是否出现在数组B中。假设有无限个CPU核。采访者建议算法应该在O(1)中运行。我只提出了一个O(log(n))解。有什么想法吗 另一方面,我的O(log(n))解决方案是将A中的一个元素分配给一个CPU核心,每个CPU使用二进制搜索来检查数组B中是否存在该元素。我记得采访者可能曾建议,在给定无限多个CPU的情况下,二进制搜索可以优化为O(1)。但我不确定。以防万一。以下是通用CRCW模型中的O(1),即,仅当写入相同的值时,

这是我在面试中遇到的问题。有两个排序的数组A和B。检查数组A中的每个元素是否出现在数组B中。假设有无限个CPU核。采访者建议算法应该在O(1)中运行。我只提出了一个O(log(n))解。有什么想法吗

另一方面,我的O(log(n))解决方案是将A中的一个元素分配给一个CPU核心,每个CPU使用二进制搜索来检查数组B中是否存在该元素。我记得采访者可能曾建议,在给定无限多个CPU的情况下,二进制搜索可以优化为O(1)。但我不确定。以防万一。

以下是通用CRCW模型中的O(1),即,仅当写入相同的值时,才能进行并发写入。假设原始数组A有n个元素,而B有m个大小

found = new bool[n]
parallel for i in 0..n-1:
  found[i] = false
  parallel for j in 0..m-1: 
    if A[i] == B[j]:
      found[i] = true

result = true
parallel for i in 0..n-1:
  if !found[i]:
    result = false

print result ? "Yes": "No"
当然,我不完全确定这个模型有多实用。实际上,您可能没有并发写入。在具有独占写入的CREW模型中,您可以在O(logn)时间内计算AND和OR聚合,我认为相应的下限也存在


向面试官询问他感兴趣的平行模型的细节可能是个好主意。

让每个核心从a中选取一个元素,从B中选取一对相邻元素。对每个可能的组合使用不同的核心。每个核心将比较它们的三个元素。如果A中的元素介于B中的两个元素之间(且两者都不相等),则A中的一个元素不会出现在B中


这缺少一些明显的优化。例如,a1000不需要与b1和b2进行比较,但与无限机器相比,谁在乎呢。

为了补充Niklas B的非常好的答案,我补充说,对于O(1)解决方案,我怀疑在最坏的情况下,即使使用排序阵列,也不能使用小于Ω(MN)的内核

如果所有元素在两个数组中都出现一次(并且隐式地M=N),则可以在“面对”元素之间并行执行N个比较,即使用Θ(N)核

但是,当允许重复时,相等的元素可能会出现移位,移位可能会增大到Ω(M+N),并且事先不知道。要尝试所有元素的所有可能移位,您需要执行Ω(MN)比较。

让A有总A元素,B有总B元素(我假设这些元素可能会重复)

我们需要总计((a*b)+1)个内核:我们要检查b中a的每个元素。因此,我们需要为a的每个元素总计b个处理器,因此a*b。最后+1表示运行主程序的前置处理器

如果两个元素相等或不相等,每个处理器将简单地进行比较。如果是,则返回
true
,否则返回
false
。以[0]为例。我们只是比较B的任何元素是否等于A[0]。因此,我们将A[0]和B[0]传递给第一个处理器,将A[0]和B[1]传递给第二个处理器,依此类推,并对结果执行OR运算。相应地,将在每个核心上运行的
test()
方法的代码如下:

public static bool test (int aElement, int bElement)
{
    return aElement == bElement;
}
接下来我们对[1]做同样的处理,然后是[2]。。直到A[A-1]它们都并行

我们对这一结果进行了反复分析,如:

(test(A[0], B[0]) || test(A[0], B[1])...) && (test(A[1], B[0]) || test(A[1], B[1])... )
因此,
Main()
将如下所示:

public void Main (string[] args)
{
    //Read A and B arrays and create the next line dynamically
    var allPresent = (test(A[0], B[0]) || test(A[0], B[1]) ||... test(A[0], B[b-1]))
                  && (test(A[1], B[0]) || test(A[1], B[1]) ||... test(A[1], B[b-1]))
                  .
                  .
                  .
                  && (test(A[a-1], B[0]) || test(A[a-1], B[1]) ||... test(A[a-1], B[b-1]))
    Console.WriteLine("All Elements {0}", (allPresent ? "Found" : "Not Found"));
}

我们并行生成所有的
测试(A[k],B[l])
,在O(1)时间内给出结果。

找到的中间数组
需要什么<代码>如果[i]==A[j]结果=true就足够了。@yvesdao不一定。发现[我]必须对我所有的人都是真实的。至少我是这样理解这个问题的:A和B中可以有重复的元素吗?要真正得到解决方案O(logn),你需要描述如何在O(logn)时间内将这些n个CPU的答案组合成一个“是/否”答案。例如,您可以将CPU排列成二叉树结构,以便两个“子”CPU将其结果传递给共享的父CPU,共享的父CPU将结果传递到树上的根,根CPU计算最终答案。@displayName是的,可能有。@j_random_hacker因此汇总答案应导致额外的O(logn)时间?@SieKensou:那么请看看我的解决方案,让我知道你没有得到什么…还需要一个CPU来检查a的每个元素是在B的第一个元素之前,还是在最后一个元素之后。不过,这并没有太大的改变。我仍然认为你需要某种方法在O(1)时间内收集所有这些答案……当一个内核在值之间找到一个元素时,它可以向第一个内核发送信号(可能设置一个共享内存位),所以这就是O(1)。为了证明序列不匹配,您只需要第一个失败的例子,并且您知道如果没有人在一个周期内设置位,那么序列是好的@j_随机_hacker@IanMercer:根据Niklas B.的回答,如果我们有CRCW模型,这似乎是可行的,因为任何写入都会写入相同的值。我怀疑如果不允许并发、等值写入,那么就不可能有O(1)解决方案……我不太明白如何在O(1)时间内完成或超过结果?@SieKensou:更新了我的答案。感谢更新:)我知道如何在O(1)中完成所有测试(A[k],B[l]),但是为什么在ab元素上执行OR和and的过程需要O(1)时间而不是O(ab)?是否使用了一些特殊技术?@SieKensou:如果我对你说实话,这些问题对我来说似乎是错误的。因为,即使要测试A的元素,您也必须至少读取所有元素,这至少需要O(A)时间。然而,我假设通过某种魔法,数组的正确部分以恒定的时间到达处理器。没有使用特殊的技术。这是一个经常性的和或假定的失败和成功更快。。。与if one和is
false
类似,整个表达式都是
false
,如果one或is
true
,则OR不会进一步求值并被视为
true
@SieKensou:AND和OR需要一个位(设置为0或1),