多边形顶点权重算法及其对边的操作

3

我在考虑以下问题的算法(在carrercup上找到):

给定一个具有N个顶点和N条边的多边形。每个顶点上都有一个int数值(可以是负数),每条边上都有一个集合中的操作(*,+)。每次从多边形中删除边E时,将由该边连接的两个顶点(V1,V2)合并成一个新的顶点,并使用以下公式计算其值:V1 op(E) V2。最后一种情况是两个带有两条边的顶点,则结果是更大的那个。 返回给定多边形可以获得的最大结果值。

我认为我们可以采用贪心方法。即对于具有k条边的多边形,找到一个产生最大数字的配对(p,q):(p,q)= max({i操作j:i,j-相邻边})

然后只需在多边形上调用递归: 1. 让函数CollapseMaxPair(P(k)) - 获取具有k条边的多边形并返回具有k-1条边的“折叠”多边形 2. 然后我们的递归:

 P = P(N);
 Releat until two edges left
     P =  CollapseMaxPair( P )
 maxvalue = max ( two remained values)

你认为呢?

3个回答

5
我已经在这里回答了此问题:Google面试:找到多边形的最大和,有人指出这个问题是一个重复的问题。由于还没有人完整回答这个问题,我决定在这里添加答案。
正如你所标记的那样,这确实与矩阵乘法问题非常相似(按什么顺序乘矩阵才能快速完成)。
这可以使用动态规划算法多项式地解决。
我将解决一个类似的、更经典的(并且相同的)问题,即给出一个带有数字、加法和乘法的公式,哪种括号方式会给出最大值,例如 6+1 * 2 变成(6+1)*26+(1*2)大。
我们将用a1到an表示输入实数,o(1),...o(n-1)是*+。我们的方法如下,我们将观察子问题F(i,j),它表示a1,...aj的最大公式(括号化后)。我们将创建这些子问题的表,并观察到F(1,n)正好是我们要寻找的结果。
定义
F(i,j)

 - If i>j return 0 //no sub-formula of negative length
 - If i=j return ai // the maximal formula for one number is the number
 - If i<j return the maximal value for all m between i (including) and j (not included) of:
     F(i,m) (o(m)) F(m+1,j) //check all places for possible parenthasis insertion

这段内容涉及IT技术,将讨论一个算法和其运行时间分析。证明正确性可通过对大小为n=j-i的问题进行归纳来完成,而这是相当平凡的。
现在让我们进行运行时间分析:
如果我们不为较小的子问题保存动态值,则运行速度会很慢,但我们可以使这个算法在O(n^3)时间内表现得相对快速。
我们创建一个n*n的表T,其中索引i,j处的单元格包含F(i,j),填充F(i,i)和j小于i的F(i,j)可以在每个单元格中以O(1)的时间计算出来,然后我们沿着对角线填充F(i+1,i+1)(由于我们已经知道了递归公式中的所有先前值,因此我们可以快速地完成这项工作),我们重复这个过程n次,用于n个对角线(实际上是表中的所有对角线),每个单元格的填充需要(O(n)),由于每个单元格都有O(n)个单元格,所以我们在O(n^2)的时间内填充每个对角线,这意味着我们在O(n^3)的时间内填充了整个表。填充表后,我们显然知道F(1,n),这就是您的问题的解决方案。
现在回到您的问题:
如果您将多边形转化为n个不同的公式(每个公式从一个顶点开始),并在其上运行该算法,则可以得到所需的值。

我认为OP的问题与您解决的问题不同。如果给定一个数组,您不能对a[0]a[n-1]进行操作,但对于多边形的顶点是有效的。 - laike9m

1
这是一个贪心算法失败的案例:
假设你的多边形是一个正方形,顶点为A、B、C、D(左上角、右上角、右下角、左下角)。这给我们带来了边缘(A,B)、(A,D)、(B,C)和(C,D)。
让权重为A=-1,B=-1,C=-1,D=1,000,000。
A (-1) ------ B (-1)  
|             |  
|             |  
|             |  
|             |  
D(1000000) ---C (-1)  

显然,最好的策略是先将 (A,B) 合并,再合并 (B,C),这样就可以得到单独的 D。不过你的算法会从 (A,D) 或者 (D,C) 开始,这样不是最优的。

贪心算法结合最小和也有类似的弱点,所以我们需要考虑其他方案。

我开始明白我们想要将所有正数放在一边,所有负数放在另一边。

如果我们将初始多边形看做一个状态,那么我们可以想象所有可能的子状态是折叠边缘后的图像。这样就创建了一个树形结构。广度优先搜索或深度优先搜索最终会给我们提供最优解,但最坏情况下需要遍历整个树,这可能不太高效。

你需要寻找的是一种贪心最佳优先搜索方法来搜索这棵树,这是可证明的最优解。也许你可以通过创建一种类似于 A* 的搜索方法来实现,但我不确定你的合理启发式方法会是什么。


这真的很有趣!我在思考一些DP解决方案(类似于“最大化括号”),但是无法想出解决方案。 - Vitaliy
我认为在这种情况下使用动态规划会是一个非常好的主意! - AndyG

0

我认为贪心算法并不适用。让顶点为A=0,B=1,C=2,边为AB=a-5b,BC=b+c,CA=-20。贪心算法首先选择要评估的是BC,价值为3。然后是AB,价值为-15。但是,有更好的顺序可以使用。首先评估AB,价值为-5。然后再评估BC,价值为-3。我不知道是否有更好的算法。


AB = a - 5b,BC = b + c,CA = -20是什么意思?边缘没有权重。如果您有A = 0,B = 1,C = 2,并且边缘AB = AC = BC = {+},那么我的方法会给您A = 0,B' = collapsed BC = 3,我们得到了它。或者我漏掉了什么? - Vitaliy
哦,我误解了你的问题。我以为边缘只是使用+和的函数。所以只有一个+或 - Henry Swanson
是的,这只是一个操作,而不是一个函数。 - Vitaliy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接