说我有这个非常常见的DP问题(动态编程) -
给定成本矩阵成本[] []和成本[] []中的位置(m,n),编写一个函数,返回从(0)到达(m,n)的最小成本路径的成本,0)。矩阵的每个单元表示遍历该单元的成本。到达路径的总成本(m,n)是该路径上所有成本的总和(包括源和目的地)。你只能从给定的单元格,即从给定的单元格(i,j),单元格(i + 1,j),(i,j + 1)和(i + 1),向下,向右和对角线地降低单元格。 j + 1)可以遍历。您可以假设所有成本都是正整数。
PS:回答这个问题 - 8
现在,在解决了这个问题之后......以下问题贯穿了我的脑海。
说我有1000 * 1000矩阵。并且O(n ^ 2)将需要一些时间(肯定是在英特尔i5上<1秒)。 但我可以进一步减少它。比如使用这个算法开始6-8个线程,然后将它们同步回来以获得答案?它会快速甚至在逻辑上得到答案,或者我应该抛弃这个想法
答案 0 :(得分:2)
一般来说,在这些小问题上(如你所说的那样),由于协议开销(线程启动和同步),并行计算的效率低于顺序。另一个问题可能是,您增加了缓存未命中率,因为您正在选择要从输入“随机”(非线性)操作的数据。然而,当涉及到更大的问题时,比如说10倍的条目的矩阵,肯定值得思考(或者两个)。
这是一种可能的解决方案。给定16x16矩阵,我们将其切割成4个相等的正方形。对于每个方块,一个线程负责。每个小方块中的数字表示在经过多少时间单位后,可以计算该平方的结果。
所以,总时间是33个单位(无论单位是多少)。与具有64个单元的顺序解决方案相比,它只是它的一半。您可以说服自己任何2 ^ k x 2 ^ k矩阵的运行时间为2 ^(2k - 1)+ 1。
但是,这只是我想到的第一个想法。我希望外面的世界有一个(更快)并行解决方案。
更重要的是,由于我在答案开头提到的原因,出于所有实际目的,你的解决方案不会达到2的加速。
答案 1 :(得分:2)
我从算法改进开始。没有必要测试N 2 解决方案。
一个键是您输入正方形的方向。如果您通过向下移动进入它,则无需检查右侧的方块。同样,如果您通过向右移动进入它,则无需从那里检查向下的路径。直角转弯的目的地总是可以通过对角线移动到达,留下一个正方形及其正重量/成本。
就线程而言,我可以看到(至少)两种分裂方式。一种方法是简单地排队进入广场时的请求。即,不是(例如)测试另一个方块,而是将请求排队以测试其两个或三个出口。 N个线程处理这些生成更多请求的请求,直到所有请求都到达终点。
这有一个明显的缺点,即你可能会在串行代码放弃之后继续遍历某些路由,因为它们已经比你到目前为止的最短路径长。
另一种可能性是启动两个线程,一个向前移动,另一个向后移动。在每一个中,你找到沿着对角线到达任何给定点的最短路径,然后你通过这些候选者进行纯线性扫描以找到最短的总和。