简体   繁体   English

具有顶点权重和边缘运算的多边形算法

[英]Algorithm for polygon with weight on vertices and operations on edges

I am thinking about the algorithm for the following problem (found on carrercup): 我正在考虑以下问题的算法(在carrercup上找到):

Given a polygon with N vertexes and N edges. 给定具有N个顶点和N个边的多边形。 There is an int number(could be negative) on every vertex and an operation in set(*,+) on every edge. 每个顶点都有一个int数(可能是负数),每个边上有一个set(*,+)的运算。 Every time, we remove an edge E from the polygon, merge the two vertexes linked by the edge(V1,V2) to a new vertex with value: V1 op(E) V2. 每次,我们从多边形中移除边E,将由边(V1,V2)链接的两个顶点合并到具有值的新顶点:V1 op(E)V2。 The last case would be two vertexes with two edges, the result is the bigger one. 最后一种情况是两个带有两条边的顶点,结果是较大的一个。 Return the max result value can be gotten from a given polygon. 返回最大结果值可以从给定的多边形获得。

I think we can use just greedy approach. 我想我们可以使用贪婪的方法。 Ie for polygon with k edges find a pair (p, q) which produces the maximum number when collapsing: (p ,q) = max ({i operation j : i, j - adjacent edges) 即,对于具有k个边的多边形,找到一对(p,q),其在折叠时产生最大数量:(p,q)= max({i operation j:i,j - 相邻边)

Then just call a recursion on polygons: 1. Let function CollapseMaxPair( P(k) ) - gets polygon with k edges and returns 'collapsed' polygon with k-1 edges 2. Then our recursion: 然后只需在多边形上调用递归:1。让函数CollapseMaxPair(P(k)) - 得到带有k个边的多边形并返回带有k-1边的“折叠”多边形2.然后我们的递归:

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

What do you think? 你怎么看?

I have answered this question here: Google Interview : Find the maximum sum of a polygon and it was pointed out to me that that question is a duplicate of this one. 我在这里回答了这个问题: 谷歌访谈:找到多边形的最大总和,并向我指出该问题与此问题重复。 Since no one has answered this question fully yet, I have decided to add this answer here as well. 既然没有人完全回答这个问题,我也决定在这里添加这个答案。

As you have identified (tagged) correctly, this indeed is very similar to the matrix multiplication problem (in what order do I multiply matrixes in order to do it quickly). 正确识别(标记)后,这确实非常类似于矩阵乘法问题(为了快速完成,我将以什么顺序乘以矩阵)。

This can be solved polynomially using a dynamic algorithm. 这可以使用动态算法以多项式求解。

I'm going to instead solve a similar, more classic (and identical) problem, given a formula with numbers, addition and multiplications, what way of parenthesizing it gives the maximal value, for example 6+1 * 2 becomes (6+1)*2 which is more than 6+(1*2) . 我将改为解决一个类似的,更经典的(和相同的)问题,给定一个带有数字,加法和乘法的公式,括号的哪种方式给出最大值,例如6+1 * 2变为(6+1)*2超过6+(1*2)

Let us denote our input a1 to an real numbers and o(1),...o(n-1) either * or + . 让我们将输入a1 to an表示a1 to an实数,将o(1),... o(n-1)表示为*+ Our approach will work as follows, we will observe the subproblem F(i,j) which represents the maximal formula (after parenthasizing) for a1,...aj. 我们的方法将如下工作,我们将观察子问题F(i,j),它代表a1,... aj的最大公式(在括号后)。 We will create a table of such subproblems and observe that F(1,n) is exactly the result we were looking for. 我们将创建一个这样的子问题表,并观察F(1,n)正是我们正在寻找的结果。

Define 限定

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

This goes through all possible options. 这经历了所有可能的选择。 TProof of correctness is done by induction on the size n=ji and is pretty trivial. 通过对大小n = ji的归纳来完成TProof的正确性并且非常简单。

Lets go through runtime analysis: 让我们进行运行时分析:

If we do not save the values dynamically for smaller subproblems this runs pretty slow, however we can make this algorithm perform relatively fast in O(n^3) 如果我们不为较小的子问题动态保存值,则运行速度非常慢,但我们可以使此算法在O(n^3)执行相对较快

We create an*n table T in which the cell at index i,j contains F(i,j) filling F(i,i) and F(i,j) for j smaller than i is done in O(1) for each cell since we can calculate these values directly, then we go diagonally and fill F(i+1,i+1) (which we can do quickly since we already know all the previous values in the recursive formula), we repeat this n times for n diagonals (all the diagonals in the table really) and filling each cell takes (O(n)), since each cell has O(n) cells we fill each diagonals in O(n^2) meaning we fill all the table in O(n^3). 我们创建一个* n表T,其中索引i,j处的单元格包含F(i,j)填充F(i,i)和F(i,j),其中j小于i,在O(1)中完成每个单元格,因为我们可以直接计算这些值,然后我们对角线并填充F(i + 1,i + 1)(我们可以快速完成,因为我们已经知道递归公式中的所有先前值),我们重复这个n n对角线的时间(表格中的所有对角线)和填充每个单元格需要(O(n)),因为每个单元格都有O(n)个单元格,我们用O(n ^ 2)填充每个对角线,这意味着我们填充所有表中的O(n ^ 3)。 After filling the table we obviously know F(1,n) which is the solution to your problem. 填写完表后,我们显然知道F(1,n)是你问题的解决方案。

我们填写表格的顺序

Now back to your problem 现在回到你的问题

If you translate the polygon into n different formulas (one for starting at each vertex) and run the algorithm for formula values on it, you get exactly the value you want. 如果将多边形转换为n不同的公式(一个用于从每个顶点开始)并在其上运行公式值的算法,则可以获得所需的值。

Here's a case where your greedy algorithm fails: 这是贪婪算法失败的情况:

Imagine your polygon is a square with vertices A, B, C, D (top left, top right, bottom right, bottom left). 想象一下,你的多边形是一个有顶点A,B,C,D(左上,右上,右下,左下)的正方形。 This gives us edges (A,B), (A,D), (B,C), and (C, D). 这给了我们边(A,B),(A,D),(B,C)和(C,D)。

Let the weights be A=-1, B=-1, C=-1, and D=1,000,000. 设权重为A = -1,B = -1,C = -1,D = 1,000,000。

A (-1) ------ B (-1)  
|             |  
|             |  
|             |  
|             |  
D(1000000) ---C (-1)  

Clearly, the best strategy is to collapse (A,B), and then (B,C), so that you may end up with D by itself. 显然,最好的策略是崩溃(A,B),然后崩溃(B,C),这样你就可以自己最终得到D. Your algorithm, however, will start with either (A,D) or (D,C), which will not be optimal. 但是,您的算法将以(A,D)或(D,C)开头,这将不是最佳的。

A greedy algorithm that combines the min sums has a similar weakness, so we need to think of something else. 结合最小总和的贪婪算法也有类似的弱点,所以我们需要考虑别的东西。

I'm starting to see how we want to try to get all positive numbers together on one side and all negatives on the other. 我开始看到我们想要尝试将所有正数放在一边,所有负数放在另一边。

If we think about the initial polygon entirely as a state, then we can imagine all the possible child states to be the subsequent graphs were an edge is collapsed. 如果我们将初始多边形完全视为一个状态,那么我们可以想象所有可能的子状态是后续图形是边缘被折叠。 This creates a tree-like structure. 这创建了一个树状结构。 A BFS or DFS would eventually give us an optimal solution, but at the cost of traversing the entire tree in the worst case, which is probably not as efficient as you'd like. BFS或DFS最终将为我们提供最佳解决方案,但代价是在最坏的情况下遍历整个树,这可能不如您所希望的那样高效。

What you are looking for is a greedy best-first approach to search down this tree that is provably optimal. 您正在寻找的是一种贪婪的最佳方法,可以搜索这棵树,这种方法可以说是最佳的。 Perhaps you could create an A*-like search through it, although I'm not sure what your admissable heuristic would be. 也许你可以通过它创建一个类似A *的搜索,虽然我不确定你的可接受启发式是什么。

I don't think the greedy algorithm works. 我不认为贪心算法有效。 Let the vertices be A = 0, B = 1, C = 2, and the edges be AB = a - 5b, BC = b + c, CA = -20. 令顶点为A = 0,B = 1,C = 2,并且边缘为AB = a-5b,BC = b + c,CA = -20。 The greedy algorithm selects BC to evaluate first, value 3. Then AB, value, -15. 贪婪算法选择BC首先评估,值3.然后AB,值,-15。 However, there is a better sequence to use. 但是,有一个更好的序列可供使用。 Evaluate AB first, value -5. 首先评估AB,值-5。 Then evaluate BC, value -3. 然后评估BC,值-3。 I don't know of a better algorithm though. 我不知道有更好的算法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM