J'implémente quelques algorithmes pour m'enseigner les graphiques et comment travailler avec eux. Que recommanderiez-vous est la meilleure façon de le faire en Java? Je pensais à quelque chose comme ça:
public class Vertex {
private ArrayList<Vertex> outnodes; //Adjacency list. if I wanted to support Edge weight, this would be a hash map.
//methods to manipulate outnodes
}
public class Graph {
private ArrayList<Vertex> nodes;
//algorithms on graphs
}
Mais j'ai simplement inventé ça. Y a-t-il une meilleure façon?
En outre, je veux qu'il puisse prendre en charge les variations des graphiques Vanilla comme les digraphes, les bords pondérés, les multigraphes, etc.
Chaque nœud est nommé de manière unique et sait à qui il est connecté. La liste des connexions permet à un Node d'être connecté à un nombre arbitraire d'autres nœuds.
public class Node {
public String name;
public List<Edge> connections;
}
Chaque connexion est dirigée, a un début et une fin et est pondérée.
public class Edge {
public Node start;
public Node end;
public double weight;
}
Un graphique est juste votre collection de nœuds. Au lieu de List<Node>
considérer Map<String, Node>
pour une recherche rapide par nom.
public class Graph {
List<Node> nodes;
}
Si vous avez besoin de bords pondérés et de multigraphes, vous voudrez peut-être ajouter une autre classe Edge .
Je recommanderais également d'utiliser des génériques pour permettre de spécifier quelle sous-classe de sommet et de bord est actuellement utilisée. Par exemple:
public class Graph<V extends Vertex> {
List<V> vertices;
...
}
En ce qui concerne l'implémentation d'algorithmes de graphes, vous pouvez également définir des interfaces pour vos classes de graphes sur lesquelles les algorithmes peuvent fonctionner, afin que vous puissiez jouer avec différents implémentations de la représentation graphique réelle. Par exemple, des graphiques simples qui sont bien connectés pourraient être mieux implémentés par un matrice d'adjacence, des graphiques plus clairsemés pourraient être représentés par adjacence listes - tout dépend ...
BTW Construire efficacement de telles structures peut être assez difficile, alors peut-être pourriez-vous nous donner plus de détails sur le type de travail que vous souhaitez utiliser? Pour des tâches plus complexes, je vous suggère de jeter un œil aux différentes bibliothèques de graphiques Java, pour vous inspirer.
Jetez un œil à la bibliothèque de graphes http://jung.sourceforge.net/doc/index.html . Vous pouvez toujours vous entraîner à implémenter vos propres algorithmes (peut-être une recherche en largeur ou en profondeur pour commencer), mais vous n'avez pas à vous soucier de créer la structure du graphique.
Pourquoi ne pas garder les choses simples et utiliser une matrice d'adjacence ou une liste d'adjacence ?
Même au moment de cette question, il y a plus de 3 ans, Sage (qui est complètement gratuit) existait et était assez bon en théorie des graphes. Mais, en 2012, il s'agit du meilleur outil de théorie des graphes qui soit. Ainsi, Sage a déjà une énorme quantité de matériel de théorie des graphes intégré, y compris d'autres trucs gratuits et open source qui sont là-bas. Donc, simplement jouer avec diverses choses pour en savoir plus est facile car aucune programmation n'est requise.
Et, si vous êtes également intéressé par la partie programmation, Sage est d'abord open source afin que vous puissiez voir tout code qui existe déjà. Et, deuxièmement, vous pouvez reprogrammer n'importe quelle fonction que vous voulez si vous voulez vraiment vous entraîner, ou vous pouvez être le premier à programmer quelque chose qui n'existe pas déjà. Dans ce dernier cas, vous pouvez même soumettre cette nouvelle fonctionnalité et améliorer Sage pour tous les autres utilisateurs.
Pour le moment, cette réponse n'est peut-être pas très utile au PO (car cela fait 3 ans), mais j'espère qu'elle sera utile à quiconque verra cette question à l'avenir.
Je recommanderais graphviz fortement lorsque vous arrivez au point où vous voulez rendre vos graphiques.
Et ses compagnons: jetez un œil à classe GraphViz de Laszlo Szathmary , avec notugly.xls .
Il y a longtemps, j'ai eu le même problème et j'ai fait ma propre implémentation. Ce que je vous suggère, c'est d'implémenter une autre classe: Edge. Ensuite, un sommet aura une liste de bords.
public class Edge {
private Node a, b;
private directionEnum direction; // AB, BA or both
private int weight;
...
}
Ça a marché pour moi. Mais c'est peut-être si simple. Il y a cette bibliothèque qui peut peut-être vous aider si vous regardez son code: http://jgrapht.sourceforge.net/
class Graph<E> {
private List<Vertex<E>> vertices;
private static class Vertex<E> {
E elem;
List<Vertex<E>> neighbors;
}
}
L'implémentation de la liste d'adjacence de Graph est appropriée pour résoudre la plupart des problèmes liés aux graphiques.
L'implémentation Java de la même chose est ici sur mon blog.
Une représentation simple écrite par "Robert Sedgwick" et "Kevin Wayne" est disponible à http://algs4.cs.princeton.edu/41graph/Graph.Java.html
Explication copiée à partir de la page ci-dessus.
La classe Graph représente un graphique non dirigé de sommets nommés de 0 à [~ # ~] v [~ # ~] - 1.
Il prend en charge les deux opérations principales suivantes: ajoutez un bord au graphique, parcourez tous les sommets adjacents à un sommet. Il fournit également des méthodes pour renvoyer le nombre de sommets [~ # ~] v [~ # ~] et le nombre d'arêtes [~ # ~] e [~ # ~] . Les bords parallèles et les auto-boucles sont autorisés. Par convention, une auto-boucle v - v apparaît dans la contiguïté liste de v deux fois et contribue deux au degré de v .
Cette implémentation utilise une représentation de listes d'adjacence, qui est un tableau d'objets Bag indexé au sommet. Toutes les opérations prennent un temps constant (dans le pire des cas) sauf l'itération sur les sommets adjacents à un sommet donné, ce qui prend un temps proportionnel au nombre de ces sommets.