2013-07-09 15 views
10

Wyznaczenie maksymalnego sumarycznego sumy w macierzy NxN można wykonać za pomocą algorytmu 2-d kadane, jak wskazano w innych wpisach. Jednakże, jeśli macierz jest rzadka, konkretnie O(n) niezerowych wpisów, czy można pokonać czas ?sumaryczny podwzrost sumy w rzadkiej macierzy

Jeśli to pomoże, dla aktualnej aplikacji jestem zainteresowany, to wystarczy mieć rozwiązanie, które przyjmuje co najwyżej jedną niezerową wartość w każdym wierszu i każdej kolumnie macierzy. Jednak w moich przyszłych zastosowaniach to założenie może nie być odpowiednie (wystarczy tylko sparyność), a poza tym moja matematyczna intuicja podpowiada, że ​​mogą istnieć dobre rozwiązania, które po prostu wykorzystują rzadkość i nie wykorzystują dalej faktu, że macierz jest iloczyn macierzy diagonalnej i permutacyjnej.

+0

Jeśli w każdym wierszu i każdej kolumnie występuje co najwyżej niezerowa wartość, należy rzutować te wartości na oś X i oś Y, otrzymasz dwie jednowymiarowe macierze o rozmiarze n.Znajdź maksymalną przyległą podwielokość dwóch tablic. Myślę, że da ci to maksymalny podretangle. Można to zrobić w czasie O (n) i O (n) przestrzeni. –

+1

Niestety to proponowane rozwiązanie O (n) nie działa, jak pokazuje następujący przykładowy licznik: 1 0 0 \\ 0 0 2 \\ 0 -1 0 \\ – user2566092

Odpowiedz

10

Tak, można to zrobić lepiej.

Przede wszystkim pomyślmy o strukturze danych, która pozwala nam

  1. zaktualizować każdy pojedynczy wartości instrumentu bazowego 1D tablicy w O(logn) czasie
  2. Znajdź sumę maksymalnej subarray tablicy w O(1) czas

Właściwie, zrównoważone drzewo binarne, które wygląda jak poniżej, może wykonać zadanie. Struktura drzewa może być opisana jako:

  1. Każdy węzeł liści drzewa reprezentuje każdy element tablicy.
  2. Jeśli wewnętrzny węzeł obejmuje zakres [a, b], jego lewe dziecko obejmuje zakres [a, c], a jego prawy pokrowiec obejmuje zakres [c + 1, b], gdzie c = floor((a + b)/2)).
  3. Główny węzeł obejmuje zakres [1, n].

         O 
            / \ 
           /  \ 
           /   \ 
          /    \ 
          /     \ 
          O      O 
         / \     / \ 
        / \    / \ 
        /  \    /  \ 
        O   O   O   O 
    /\  /\  /\  /\ 
    o  o  o  o  o  o  o  o 
    A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 
    

Istnieją 4 pola dołączone do każdego węzła v (w tym węzłów liściowych i węzłów wewnętrznych):

  • S[v]: suma wszystkich wartości w v „s zakresie
  • M[v] : maksymalna suma podciągów w zakresie v:
  • L[v]: suma maksym m subarray, który rozpoczyna się po lewej stronie v „zakresie s
  • R[v]: suma maksymalnej subarray że kończy się na prawej stronie v” s Zakres

Na podstawie powyższych definicji, możemy znaleźć następujące zasady aktualizacji:

  • Dla każdego węzła liścia v, S[v] = A[v], M[v] = L[v] = R[v] = max{0, A[v]}
  • Dla każdego wewnętrznego węzła v i jej dzieci l i r,
    • S[v] = S[l] + S[r]
    • M[v] = max{M[l], M[r], R[l] + L[r]}
    • L[v] = max{L[l], L[r] + S[l]}
    • R[v] = max{R[r], R[l] + S[r]}

Wreszcie możemy realizować operacje wymienione na początku.

  • Aby zaktualizować A[i], możemy znaleźć odpowiedni węzeł liścia w drzewie i zaktualizować pola wzdłuż jego ścieżki do korzenia przy użyciu powyższych zasad.
  • Maksymalna suma podobrazów to po prostu M[root].

Porozmawiajmy teraz o tym, jak znaleźć maksymalny prostokąt za pomocą tej struktury danych. Jeśli ustawimy górny i dolny rząd prostokąta na i th i j th wierszy, problem zmieni się w sumę problemów pod sumą 1D, gdzie A[k] = sum{B[i..j, k]}. Kluczowym wglądem jest to, że dla ustalonego i, jeśli wymienimy j w porządku rosnącym, możemy wykorzystać powyższą strukturę danych do utrzymania podstawowej tablicy 1D i znaleźć odpowiedź bardzo szybko. Pseudokod opisuje pomysł:

result = 0 
for i in (1, 2, ..., n) 
    set all fields of the binary tree T to 0 
    for j in (i, i + 1, ..., n) 
     for any k where B[j, k] != 0 
      T.update(k, A[k] + B[j, k]) 
     result = max{M[root], result} 
return result 

Załóżmy, że matryca zawiera m niezerowe elementy złożoność czasowa tego algorytmu jest O(mn logn). W twoim przypadku m = O(n), więc złożoność czasu wynosi O(n^2 logn) i jest lepsza niż O(n^3).

+0

Dzięki, ta odpowiedź wygląda poprawnie, a poprawa pomoże dla dużych n. Przejrzałem literaturę i online i nie znalazłem nic lepszego niż O (n^3) dla tego problemu dla rzadkich macierzy. W związku z tym będziemy musieli opisać ten algorytm w naszym dokumencie aplikacyjnym dotyczącym wykrywania źródła promieniowania, ponieważ nasi odbiorcy chcą wiedzieć, jakich algorytmów używamy. Proszę dać mi znać, jeśli planujesz napisać krótką notatkę na ten temat do publikacji, a jeśli tak, to jaki tytuł autora/pracodawcy, abyśmy mogli podać należne cytat. Lub, jeśli chcesz po prostu potwierdzenie, możemy to zrobić. – user2566092

+0

Chciałbym po prostu potwierdzenie, jeśli to możliwe. Możesz znaleźć mój e-mail w moim profilu. Jednak znalazłem tę stronę, która opisała podobny pomysł: http://wcipeg.com/wiki/Segment_tree#Maximum.2Fminimum_prefix.2Fsuffix_sum – fuch

Powiązane problemy