//Fonctionnel public Bellman(Graph graph, Node origine) { path = new Dictionary<Node, Dictionary<List<Node>, Int32>>(); this.g = graph; this.o = origine; execute(g, o); }
static void Main(string[] args) { /* Object[,] graphComponent = new Object[,] { {"Paris", int.MaxValue, 1, int.MaxValue, int.MaxValue, 11, int.MaxValue, int.MaxValue}, {"Bordeaux", int.MaxValue, int.MaxValue, 5, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue}, {"Bayonne", int.MaxValue, int.MaxValue, int.MaxValue, 5, int.MaxValue, int.MaxValue, int.MaxValue}, {"Pau", 3, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 3}, {"Bangkok", int.MaxValue, int.MaxValue, int.MaxValue,int.MaxValue, int.MaxValue, 8, 13}, {"Yangon", int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 3, int.MaxValue, int.MaxValue}, {"Tarbes", int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue , int.MaxValue}, }; */ Object[,] graphComponent = new Object[,] { {"Paris", 0, 1, 10, 3, int.MaxValue, int.MaxValue, int.MaxValue}, {"Bordeaux", 4, 0, 3, 1, int.MaxValue, int.MaxValue, 5}, {"Pau", 3, 7, 0, 1, int.MaxValue, 10, int.MaxValue}, {"Bangkok", 52, 4, 1, 0, 8, int.MaxValue, int.MaxValue}, {"Yangon", int.MaxValue, int.MaxValue, int.MaxValue, 8, int.MaxValue, int.MaxValue, int.MaxValue}, {"Tarbes", int.MaxValue, 5, int.MaxValue, int.MaxValue, int.MaxValue, 0, int.MaxValue}, {"Bayonne", int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 0}, }; Graph g = new Graph(graphComponent); g.display(); g.displayCurrentMatrix(); SaveManager sm = new SaveManager(); sm.saveGraph(g); StronglyConnectedComponent scc = new StronglyConnectedComponent(); scc.displaySCC(g); /* Actions a = new Actions(); a.testPerf(g); */ Bellman bm = new Bellman(g, g.getNodeAt(0)); bm.display(); Dijkstra dj = new Dijkstra(g, g.getNodeAt(0)); dj.display(); /* * Floyd flo = new Floyd(g); flo.display(); * DepthFirst dfs = new DepthFirst(g, g.getNodeAt(0)); dfs.displayDFSPath(); TreeDepthFirst tdfs = new TreeDepthFirst(g, g.getNodeAt(0)); Graph zi = tdfs.getDFSGraph(); zi.display(); */ }
public void testPerf(Graph g) { long milliseconds; Stopwatch stopDij = new Stopwatch(); stopDij.Start(); Dijkstra dj = new Dijkstra(g, g.getNodeAt(0)); stopDij.Stop(); milliseconds = stopDij.ElapsedMilliseconds; Console.WriteLine("Dijkstra : " + milliseconds + " ms"); Stopwatch stopBell = new Stopwatch(); stopBell.Start(); Bellman bm = new Bellman(g, g.getNodeAt(0)); stopBell.Stop(); milliseconds = stopBell.ElapsedMilliseconds; Console.WriteLine("Bellman : " + milliseconds + " ms"); Stopwatch stopDFS = new Stopwatch(); stopDFS.Start(); DepthFirst dfs = new DepthFirst(g , g.getNodeAt(0)); stopDFS.Stop(); milliseconds = stopDFS.ElapsedMilliseconds; Console.WriteLine("DFS : " + milliseconds + " ms"); Stopwatch stopFloyd = new Stopwatch(); stopFloyd.Start(); Floyd fl = new Floyd(g); stopFloyd.Stop(); milliseconds = stopFloyd.ElapsedMilliseconds; Console.WriteLine("Floyd : " + milliseconds + " ms"); }
public void saveGraph(Graph g) { fs = new FileStream("datas\\grapheSauve.lol", FileMode.Create); bf.Serialize(fs, g); fs.Close(); }
public Floyd(Graph graph) { //On récupère la matrice du graphe this.Matrix = graph.getMatrix().getCalcM(); //On récupère la longueur des lignes de la matrice n = Matrix.GetLength(0); //Création d'un tableau d'entier qui contiendra les résultats de l'agorithme de Floyd floydMatrix = new int[n, n]; execute(graph); }
public TreeDepthFirst(Graph graph, Node origine) { depthFirstTree = new Graph(); depthFirstTree.setMatrix(graph.getMatrix()); this.graph = graph; this.origine = origine; foreach (Node n in graph.getNodeList()) { n.unmarkNode(); } }
public void displaySCC(Graph g) { List<List<Node>> disp = compute(g); Console.WriteLine("Composantes fortement connexes : "); foreach (List<Node> list in disp) { foreach (Node n in list) { Console.WriteLine(n.getName()); } Console.WriteLine("Fin de la composante"+Environment.NewLine); } Console.WriteLine(Environment.NewLine); }
public List<List<Node>> compute(Graph g) { foreach (Node no in g.getNodeList()) { no.setIndexSCC(Int32.MaxValue); } foreach (Node n in g.getNodeList()) { if (n.getIndexSCC() == Int32.MaxValue) { strongConnect(g, n); } } return scc; }
private void strongConnect(Graph g, Node n) { n.setIndexSCC(index); n.setLowlink(index); index++; s.Add(n); foreach (Arc a in g.getArcList()) { if (a.getOrigin() == n) { if (a.getEdge().getIndexSCC() == int.MaxValue) { strongConnect(g, a.getEdge()); n.setLowlink(Math.Min(n.getLowlink(), a.getEdge().getLowlink())); } else if(s.Contains(a.getEdge())) { n.setLowlink(Math.Min(n.getLowlink(), a.getEdge().getIndexSCC())); } } } if (n.getLowlink() == n.getIndexSCC()) { scc.Add(new List<Node>()); Node w = new Node(); do { w = s.Last(); s.Remove(s.Last()); scc.Last().Add(w); } while (n != w); } }
public void execute(Graph graph, Node node) { //On marque le noeud node.markNode(); //On copie les caractéristiques du noeud dans un nouveau noeud Node n = new Node(node.getIndex(), node.getName()); //On ajoute ce dernier au graphe depthFirstTree.addNode(n); //Pour chaque arc partant du noeud : foreach (Arc a in node.getEgressArc()) { if (a.getEdge().getNodeState() == false) { Node e = new Node(a.getEdge().getIndex(), a.getEdge().getName()); depthFirstTree.addArc(new Arc(a.getCost(), n, e)); execute(graph, a.getEdge()); } } }
//Fonctionnel public int[,] execute(Graph graph) { //On copie les éléments de la matrice du graphe dans la matrice floydMatrix for (int g = 0; g < n; g++) { for (int o = 0; o < n; o++) { floydMatrix[g, o] = (int)Matrix[g, o]; } } //Algorithme de Floyd for (int a = 0; a < n; ++a) { for (int z = 0; z < n; ++z) { for (int e = 0; e < n; ++e) { if (floydMatrix[z, a] != int.MaxValue && floydMatrix[a, e] != int.MaxValue) { int d = floydMatrix[z, a] + floydMatrix[a, e]; if (floydMatrix[z, e] > d) floydMatrix[z, e] = d; } } } } //On copie les éléments de la matrice floydMatrix vers la matrice Matrix, pour l'homogénéité des types for (int g = 0; g < n; g++) { for (int o = 0; o < n; o++) { Matrix[g, o] = floydMatrix[g, o]; } } return Matrix; }
public void generateMatrix(Graph g) { int dim = g.getNodeList().Count(); Object[,] matrixC = new Object[dim, dim + 1]; //+1 <=> colonne ajoutée pour les noms //On ajoute les noms de noeuds à la matrice for (int i = 0; i < dim; i++) matrixC[i, 0] = g.getNodeAt(i).getName(); //On remplit les cases connues foreach (Node n in g.getNodeList()) { foreach (Arc a in n.getEgressArc()) { int x = a.getOrigin().getIndex(); int y = a.getEdge().getIndex(); setValueAt(matrixC, a.getCost(), x, y+1); } } //On remplie les cases inconnues for (int i = 0; i < dim; i++) { for (int j = 1; j < dim + 1; j++) { if(matrixC[i, j]==null) { if (i + 1 == j) matrixC[i, j] = 0; else matrixC[i, j] = int.MaxValue; } } } this.costMatrix = matrixC; refreshCalcM(); }
//Création de la matrice à partir d'un graphe public Matrix(Graph g) { generateMatrix(g); refreshCalcM(); }
public DepthFirst(Graph graph, Node origine) { depthFirstPath = new Dictionary<Node, Node>(); this.g = graph; this.o = origine; foreach (Node n in graph.getNodeList()) { n.unmarkNode(); } executeDFS(g, o); }
//Parcours en profondeur du graph à partir du noeud passé en paramètre public void executeDFS(Graph graph, Node origine) { origine.markNode(); foreach (Arc a in origine.getEgressArc()) { if (a.getEdge().getNodeState() == false) { depthFirstPath.Add(a.getEdge(), a.getOrigin()); executeDFS(graph, a.getEdge()); } } }
public Dictionary<Node, Dictionary<List<Node>, Int32>> execute(Graph g, Node origine) { Queue = new List<Node>(); foreach (Node n in g.getNodeList()) { Queue.Add(n); if (n.Equals(origine)) { n.setDistance(0); n.setPredecessor(n); } else { n.setDistance(2000000000); n.setPredecessor(null); } } while (Queue.Count > 0) { Node u = getSmallest(Queue); if (u.getDistance() == 2000000000) { break; } Queue.Remove(u); foreach (Arc a in g.getArcList()) { if (a.getOrigin() == u && Queue.Contains(a.getEdge())) { Node z = a.getEdge(); // Console.WriteLine(o.getName() + " -- " + z.getName()); Int32 tempDistance = u.getDistance() + a.getCost(); // Console.WriteLine("Distance origine : "+u.getDistance()+" - Cout arc : "+a.getCost()+ " tmp : "+tempDistance+" - Distance extremite : "+z.getDistance()); if (tempDistance < z.getDistance()) { z.setDistance(tempDistance); z.setPredecessor(u); Dictionary<List<Node>, Int32> dtemp = new Dictionary<List<Node>, Int32>(); listNodePath = new List<Node>(); if (path.Keys.Contains(z)) { dtemp.Remove(listNodePath); path.Remove(a.getEdge()); definePath(z); listNodePath.Add(origine); dtemp.Add(listNodePath, z.getDistance()); path.Add(z, dtemp); // Console.WriteLine("lol distance : "+z.getName()+" = "+z.getDistance()); } else { definePath(a.getEdge()); listNodePath.Add(origine); dtemp.Add(listNodePath, z.getDistance()); path.Add(z, dtemp); //Console.WriteLine("lol2 distance : " + z.getName() + " = " + z.getDistance()); } } // Console.WriteLine(); } } } return path; }
//Bellman public String Bellman(ref Graph graph, ref Node node) { return ""; }
//Recherche d'un arbre couvrant à partir d'un sommet racine par parcours en profondeur. //Ajout d'un sommet d'arrivé en option ? public String depthFirst(ref Graph graph, ref Node node) { return ""; }
//Méthode implémentant l'algorithme de Bellman-Ford public Dictionary<Node, Dictionary<List<Node>, Int32>> execute(Graph graph, Node origine) { //Pour chaque noeud contenu dans le graphe foreach (Node n in graph.getNodeList()) { //Si le noeud est égal à l'origine(passée en paramètre) if (n.Equals(origine)) { //La distance est donc de 0 n.setDistance(0); //On définit le prédécesseur de l'origine à lui même n.setPredecessor(n); } else { //Si le noeud n'est pas l'origine, on définit une valeur correspondant à "l'infini" n.setDistance(2000000000); //On vide les variables predecessor de noeuds n.setPredecessor(null); } } //Pour le nombre de noeud contenu dans le graphe for (Int32 i = 1; i < graph.getNodeList().Count; i++) { //Pour chaque arc du graphe foreach (Arc az in graph.getArcList()) { //On définit l'origine de l'arc en cours dans le noeud a Node a = az.getOrigin(); //On définit l'extrémité de l'arc en cours dans le noeud z Node z = az.getEdge(); //Si la distance pour atteindre le noeud a + le coût de l'arc en cours est inférieur à la distance pour atteindre le noeud z if (a.getDistance() + az.getCost() < z.getDistance()) { //Alors on définit une nouvelle distance pour atteindre z égale à la distance pour atteindre le noeud a + le coût de l'arc en cours z.setDistance(a.getDistance() + az.getCost()); //De plus, on définit l'origine de l'arc en cours en tant que prédécesseur de l'extrémité z z.setPredecessor(a); //Création d'une chaîne de caractères qui contiendra les noeuds de passage //chemin = ""; //Ajoute des informations dans le tableau listString //listString.Add("Origine : "+node.getName()+" - Extrémité : "+z.getName()+" - Distance : "+z.getDistance()+" - Par "+definePath(z)); Dictionary<List<Node>, Int32> dtemp = new Dictionary<List<Node>, Int32>(); listNodePath = new List<Node>(); if (path.Keys.Contains(z)) { dtemp.Remove(listNodePath); path.Remove(z); definePath(z); listNodePath.Add(origine); dtemp.Add(listNodePath, z.getDistance()); path.Add(z, dtemp); } else { definePath(z); listNodePath.Add(origine); dtemp.Add(listNodePath, z.getDistance()); path.Add(z, dtemp); } } } } //Boucle foreach permettant de vérifier que le graphe ne contient pas de cycle de poids négatif foreach (Arc az in graph.getArcList()) { Node a = az.getOrigin(); Node z = az.getEdge(); if (a.getDistance() + az.getCost() < z.getDistance()) { Console.WriteLine("Le graphe contient un cycle de poids négatif"); } } return path; }
//Algorithmes de recherche du plus court chemin //Dijkstra: Ne prend pas les valeurs négatives public String dijkstra(ref Graph graph, ref Node node) { return ""; }
//Floyd public String Floyd(ref Graph graph, ref Node node) { return ""; }
//Recherche des composantes fortement connexes public List<String> strConComponent(ref Graph graph) { List<String> temp = null; return temp; }