web-dev-qa-db-fra.com

Traitement d'une matrice 2D - Besoin d'accélérer mon algorithme O (N ^ 4)

J'ai une matrice n x n Que j'ai besoin de convertir en une liste triée par la valeur. En commençant par la cellule de valeur maximale à (rangée x1, Col y1), Je dois exclure immédiatement toutes les cellules où (x >= x1, y <= y1) Ou (x <= x1, y >= y1).

Il y a des cellules n x n Et chacune d'entre elles est comparée aux cellules (n - x1) * y1 + x * (n - y1). Cela donne une complexité de temps globale de O(n^4) et rend mon algorithme très lent. Pouvez-vous améliorer l'évolutivité de cet algorithme?

Voici une visualisation:

enter image description here

Voici quelques python/pseudocode:

INVALID = -1

class Pair:
    def __init__(self, x, y, value):
        self.x = x
        self.y = y
        self.value = value

def get_ordered_pairs(matrix):
    pairs = []
    for i in range(len(matrix) * len(matrix[0])):
        pairs.append(get_max_pair(matrix))
    return pairs

def get_max_pair(matrix):
    max_pair = Pair(INVALID, INVALID, INVALID)
    for x in range(len(matrix)):
        for y in range(len(matrix[x])):
            if matrix[x][y] > max_pair.value:
                max_pair = Pair(x, y, matrix[x][y])

    # invalidate entire row
    for y in range(len(matrix[0])):
        matrix[max_pair.x][y] = INVALID

    # invalidate entire column
    for x in range(len(matrix)):
        matrix[x][max_pair.y] = INVALID        

    # invalidate top right    
    for x in range(max_pair.x + 1, len(matrix)):
        for y in range(max_pair.y):
            matrix[x][y] = INVALID          

    # invalidate bottom left
    for y in range(max_pair.y + 1, len(matrix[0])):
        for x in range(max_pair.x):
            matrix[x][y] = INVALID

    return max_pair
5
Irfan434

Comment faites-vous quelque chose de plus efficace?

  • Faire moins de travail
  • Organiser mieux

En ce qui concerne faire moins de travail: au lieu de "X" sur des boîtes et répandre toute la matrice, ne manipulez que ce qui reste après avoir trouvé chaque max.

Chacun a trouvé Max subdivise l'espace restant en deux espaces plus petits, pouvant être traités indépendamment de sa matrice contenant plus grande. (Et de plus, vous informez déjà essentiellement les coins de ces deux espaces plus petits.)

En ce qui concerne une meilleure organisation: appliquez la suggestion @jimmyjames pour numériser la matrice une seule fois la collecte de toutes les valeurs dans la commande triée; Ensuite, lors de la traversée de cette série de tri, suivez les subdivisions de l'espace, qui sont ensuite utilisées pour vous indiquer si vous souhaitez ou non autoriser/sortir l'élément suivant de la série.

Codage laissé comme des exercices pour le lecteur.

0
Erik Eidt