web-dev-qa-db-fra.com

Comparaison de la représentation d'un graphe d'objets avec une liste d'adjacence et des représentations matricielles

Je suis actuellement en train de suivre les conseils de Steve Yegge sur la préparation d'un entretien de programmation technique: http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html

Dans sa section sur les graphiques, il déclare:

Il existe trois méthodes de base pour représenter un graphique en mémoire (objets et pointeurs, matrice et liste d'adjacence), et vous devez vous familiariser avec chaque représentation et ses avantages et inconvénients.

Les avantages et les inconvénients des représentations matricielles et des listes d'adjacence sont décrits dans CLRS, mais je n'ai pas été en mesure de trouver une ressource qui les compare à une représentation d'objet.

Juste en y réfléchissant, je peux en déduire moi-même une partie de cela, mais je voudrais m'assurer que je n'ai pas raté quelque chose d'important. Si quelqu'un pouvait décrire cela de manière exhaustive ou me diriger vers une ressource qui le fait, je l'apprécierais grandement.

78
jbeard4

objets et pointeurs

Ce ne sont que des infrastructures de base comme hammar l'a dit dans l'autre réponse, dans Java vous représenteriez cela avec des classes comme les arêtes et les sommets. Par exemple, une arête relie deux sommets et peut être dirigée ou non, et elle peut contenir un poids. Un sommet peut avoir un ID, un nom, etc. La plupart du temps, les deux ont des propriétés supplémentaires. Vous pouvez donc construire votre graphique avec eux comme

Vertex a = new Vertex(1);
Vertex b = new Vertex(2);
Edge edge = new Edge(a,b, 30); // init an Edge between ab and be with weight 30  

Cette approche est couramment utilisée pour les implémentations orientées objet, car elle est plus lisible et plus pratique pour les utilisateurs orientés objet;).

matrice

Une matrice n'est qu'un simple tableau bidimensionnel. En supposant que vous ayez des ID de sommet qui peuvent être représentés comme un tableau int comme ceci:

int[][] adjacencyMatrix = new int[SIZE][SIZE]; // SIZE is the number of vertices in our graph
adjacencyMatrix[0][1] = 30; // sets the weight of a vertex 0 that is adjacent to vertex 1

Ceci est couramment utilisé pour les graphiques denses où l'accès à l'index est nécessaire. Vous pouvez représenter une structure non dirigée et pondérée avec cela.

liste d'adjacence

Ce n'est qu'un simple mélange de données, j'implémente généralement ceci en utilisant un HashMap<Vertex, List<Vertex>>. Similaire utilisé peut être le HashMultimap en goyave.

Cette approche est cool, car vous avez O(1) (amorti) recherche de sommet et cela me renvoie une liste de tous les sommets adjacents à ce sommet particulier que j'ai demandé.

ArrayList<Vertex> list = new ArrayList<>();
list.add(new Vertex(2));
list.add(new Vertex(3));
map.put(new Vertex(1), list); // vertex 1 is adjacent to 2 and 3

Ceci est utilisé pour représenter des graphiques clairsemés, si vous postulez chez Google, vous devez savoir que le graphique Web est clairsemé. Vous pouvez les gérer de manière plus évolutive en utilisant un BigTable .

Oh et BTW, ici est un très bon résumé de ce post avec des images fantaisistes;)

89
Thomas Jungblut

Les objets et les pointeurs sont essentiellement les mêmes que la liste d'adjacence, au moins dans le but de comparer des algorithmes qui utilisent ces représentations.

Comparer

struct Node {
    Node *neighbours[];
};

avec

struct Node {
    Node *left;
    Node *right;
};

Vous pouvez facilement construire la liste des voisins à la volée dans ce dernier cas, s'il est plus facile de travailler avec des pointeurs nommés.

7
hammar

L'avantage de la représentation d'objet ( liste d'incidence ) est que deux sommets adjacents partagent la même instance de l'arête. Cela facilite la manipulation avec des données Edge non dirigées (longueur, coût, flux ou même direction). Cependant, il utilise de la mémoire supplémentaire pour les pointeurs.

4
Michal Čizmazia

Une autre bonne ressource: Khan Academy - "Représenter les graphiques"

Outre la liste de contiguïté et la matrice de contiguïté, ils listent les "listes de bord" comme 3e type de représentation graphique. Une liste Edge pourrait être interprétée comme une liste d '"objets Edge" comme ceux de la réponse de Thomas "objets et pointeurs".

Avantage: nous pouvons stocker plus d'informations sur l'Edge (mentionné par Michal)

Inconvénient: C'est une structure de données très lente avec laquelle travailler:

  • Rechercher un bord: O (log e)
  • Supprimer un bord: O (e)
  • Trouver tous les nœuds adjacents à un nœud donné: O (e)
  • Déterminez s'il existe un chemin entre deux nœuds: O (e ^ 2)

e = nombre d'arêtes

1
Chris Leung