Вопрос по matrix, algorithm – Максимизировать сумму «не перекрывающихся» чисел из матрицы

6

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

|5 4 3 2 1|
|4 3 2 1 5|
|3 2 1 5 4|
|2 1 5 4 3|
|1 5 4 3 2|

Error: User Rate Limit Exceeded

|5 5 5 5 5|

Error: User Rate Limit Exceeded

|5 4 3|
|4 3 2|
|3 2 1|

Error: User Rate Limit Exceeded

|3 3 3|

Error: User Rate Limit Exceeded

|5 3 1|

Error: User Rate Limit Exceeded

|4 4 1|

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededO(n^3)Error: User Rate Limit Exceeded Li-aung Yip
Error: User Rate Limit ExceededO(n^3)Error: User Rate Limit Exceeded Li-aung Yip

Ваш Ответ

4   ответа
0

This algorithm is wrong; there is no proof because it's wrong and therefore it's impossible to prove that it's correct.

Problem

Algorithm Let A be a square array of n by n numbers. Let Aij denote the element of A in the ith row and jth column. Let S( i1:i2, j1:j2 ) denote the optimal sum of non-overlapping numbers for a square subarray of A containing the intersection of rows i1 to i2 and columns j1 to j2.

S( 1:n , 1:n )

S( 1:n , 1:n ) = max {  [ S(   2:n , 2:n   ) + A11 ]
                        [ S(   2:n , 1:n-1 ) + A1n ]
                        [ S( 1:n-1 , 2:n   ) + An1 ]
                        [ S( 1:n-1 , 1:n-1 ) + Ann ] }
(recursively)

Note that S( i:i, j:j ) is simply Aij.

nn-1

S for |# # # #|
      |# # # #|
      |# # # #|
      |# # # #|

Is the best of the sums S for:

|#      |      |      #|      |# # #  |       |  # # #|
|  # # #|      |# # #  |      |# # #  |       |  # # #|
|  # # #|      |# # #  |      |# # #  |       |  # # #|
|  # # #|      |# # #  |      |      #|       |#      |
Implementation

def S(A,i1,i2,j1,j2):
    if (i1 == i2) and (j1==j2):
        return A[i1][j1]
    else:
        return max ( S( A, i1+1, i2, j1+1, j2) + A[i1][j1] ],
                     S( A, i1+1, i2, j1, j2-1) + A[i1][j2] ],
                     S( A, i1, i2-1, j1+1, j2) + A[i2][j1] ],
                     S( A, i1, i2-1, j1, j2-1) + A[i2][j2] ], )

O(4^n)S()O(n!)

repeated with the same parameters

Make the recursive function S() cache results so that it only needs to S(A,i1,i2,j1,j2) once for each i1,i2,j1,j2. This means that S() only needs to calculate O(n^3) results - all other requests will be fufilled from cache. (This is called memoising.) Instead of starting at the top, with the large n*n array, and working down through successively smaller subproblems, start at the bottom with the smallest possible subproblems and build up to the n*n case. This is called dynamic programming. This is also O(n^3), but it's a much faster O(n^3) because you don't have to hit a cache all the time.

Find optimal solutions to all 1x1 sub-arrays. (Trivial.) Find optimal solutions for all 2x2 sub-arrays. Find optimal solutions for all 3x3 sub-arrays. ... Find optimal solutions for all n-1 * n-1 sub-arrays. Find optimal solutions for the complete n*n sub-array. Notes on this solution: No proof yet. I'm working on it. You'll note the algorithm above only gives you S(), the optimal sum. It doesn't tell you which numbers actually make up that sum. You get to add in your own method of backtracing your path to the solution. The algorithm above doesn't guarantee the property that ties like 2,2 vs. 1,3 will be broken in favour of having all the individual numbers be as large as possible (so that 2,2 wins.) I believe you can define max() to break ties in favour of the largest numbers possible, and that will do what you want, but I can't prove it. General notes:

Optimal substructure: A problem can be broken down into slightly smaller parts, each of which can be used as part of the solution to the original problem. Overlapping subproblems means that there are few actual subproblems to solve, and the solutions to the subproblems are re-used many times.

slightlynn-1dynamic programming.

muchnn/2divide and conquerveryO(log n)

0

Find a reasonable solution. Select max values from each row and see if they are non-overlapping. If not, then perturb part of the solution so that the result becomes non-overlapping. Define fitness of a partial solution. Let us say you are picking up value for each row iteratively and you have already picked values from first k rows. The fitness of this solution equals sum of the already picked values + max values from remaining rows and unselected columns Now recursively start searching for solution. Select the values from first row, calculate their fitness and insert them into a priority queue. Remove all the solutions whose fitness is lower than the current optimal solution (initialized in step 1). Pick the solution at the head of the queue, calculate the next level of solutions and insert them back to the priority queue. Once you have selected values from all columns and rows, calculate the sum, and if it is higher than current optimal, replace it.
@ Li-aungYip Точно!
Было бы интересно рассуждать о среднем и наихудшем времени выполнения этого подхода. Это 3:00, и я очень сонный, поэтому я не буду пытаться делать это сам - но учтите, что если моё решение по динамическому программированию может быть доказано, оно всегда находит по крайней мере одно допустимое решение вO(n^3) время, несмотря ни на что.
Если я правильно понимаю, вы в основном строите древо потенциальных решений и отбрасываете тупики по ходу дела?
@ Li-aungYip Это эвристика. Таким образом, сложность наихудшего случая равна O (n!) (Представьте матрицу, в которой диагональ равна 2, другие элементы равны 1, а один недиагональный элемент в последней строке очень большой). Не уверен в средней сложности.
Игнорируй меня. Мой алгоритм неверен.
6

Это так круто. Спасибо! oeoeaio
Успешно справился. Возьми мои голоса.
-1

Спасибо, это очень полезно. За исключением того, что поиск "решений" это не совсем проблема. Я знаю, что есть n! "решения", и я знаю, что если я выберу элемент в другой строке и столбце каждый раз, когда я его размещу, я всегда буду в состоянии найти "решение", поэтому обратное отслеживание на самом деле не имеет отношения к моему случаю совсем. Сложная часть заключается в том, чтобы найти способ исключить или расставить приоритеты для определенного набора «решений». так что вам не придется перебирать все «решения»; чтобы найти ту, которая дает вам максимальную сумму, которая может или не может быть на самом деле возможно .... oeoeaio

Похожие вопросы