private void CalculateSingleSource(IGraph graph, INode source) { // there cannot be any negative cost cycles because of the implementation of GetEdgeWeight var result = new SingleSourceShortestPaths { Source = { Item = source }, Sinks = { Source = graph.Nodes }, Directed = Directed, Costs = { Delegate = GetEdgeWeight } }.Run(graph); // add a gradient to indicate the distance of the nodes to the source var maxDistance = result.Distances.Values.Where(dist => !double.IsPositiveInfinity(dist)).Max(); foreach (var node in graph.Nodes) { var v = result.Distances[node] / maxDistance; node.Tag = new Tag { GradientValue = v }; var edgeToNode = result.Predecessors[node]; if (edgeToNode != null) { edgeToNode.Tag = new Tag { GradientValue = v }; } } ((Tag)source.Tag).IsSource = true; }
public static void Main(string[] args) { try { // int size = 9; // Graph graph = new DirectedGraph(size); // // graph.AddEdge(1,4); // graph.AddEdge(4,7); // graph.AddEdge(7,1); // // graph.AddEdge(9,7); // graph.AddEdge(9,3); // graph.AddEdge(3,6); // graph.AddEdge(6,9); // // graph.AddEdge(8,6); // graph.AddEdge(8,5); // graph.AddEdge(5,2); // graph.AddEdge(2,8); // graph.PrintGraph(); // //int src = 4; //int dest = 6; //Console.WriteLine($"Attempt to find length of SP ({src},{dest})"); //Console.WriteLine(graph.ShortestPaths(src, dest)); //Try Programming Assignment #1 //Reading edges from file string kosarajuPath = "/home/paul/coding/algorithms-data-structures/graphs#extra/GraphSearch/SCC.txt"; // Graph graph = new GraphBuilder().BuildFromFileForSCC(kosarajuPath); // Compute.StronglyConnectedComponents(graph); // string dijkstraTestPath = // "/home/paul/coding/algorithms-data-structures/graphs#extra/GraphSearch/dijkstraDataTest.txt"; // string dijkstraPath = "/home/paul/coding/algorithms-data-structures/graphs#extra/GraphSearch/dijkstraData.txt"; DirectedGraph graph1 = new GraphBuilder().BuildFromFileForDijkstra(dijkstraPath); SingleSourceShortestPaths ssp = new SingleSourceShortestPaths(); ssp.Dijkstra(graph1, 1); Console.WriteLine(ssp.GetDijkstraOutput()); } catch (Exception ex) { Console.WriteLine(ex); } }
//add links to the components connecting it with the initVertex void AddComponent(int compID, SingleSourceShortestPaths shortestPaths) { this.joinedComps[compID]=true; //take a node clsosest to the initVertex int node=-1; int dist=Int32.MaxValue; foreach(Edge l in this.comps[compID]){ if(shortestPaths.GetDistTo(l.source)<dist){ dist=shortestPaths.GetDistTo(l.source); node=l.source; } if(shortestPaths.GetDistTo(l.target)<dist){ dist=shortestPaths.GetDistTo(l.target); node=l.target; } } //find a link entering the component from the outside Edge link=null; while(this.nodesToCompIds[node]==compID){ if(node==this.initVertex) //this component is already connected to the initVertex return; link=shortestPaths.Pred[node]; node=link.source; } while(true) { this.linksToCompIDs[link]=this.closureID; int sourceCompID=nodesToCompIds[link.source]; if(sourceCompID==-1){ link=shortestPaths.Pred[link.source]; nodesToCompIds[link.target]=closureID; } else if(sourceCompID==closureID){ break; } else {//we hit a component from comps this.joinedComps[sourceCompID]=true; break; } } }
void Process() { if(this.numberOfVertices==0) return; if(this.mustEdges==null || this.mustEdges.Length==0){ newML=new Edge[0]; newOL=this.optionalEdges; return; } //first check with the hope that we are fine //that means that we have only one weakly //connected component containing the initVertex if(comps.Length==1){ foreach(Edge link in comps[0]) if(this.initVertex==link.target||this.initVertex==link.source){ newML=this.mustEdges; newOL=this.optionalEdges; return; } } //connect each component with the initial vertex //nothing is joined at the beginning joinedComps=new bool[comps.Length]; #region organizing the node to component id map this.nodesToCompIds=new int[this.numberOfVertices]; for(int i=0;i<nodesToCompIds.Length;i++) nodesToCompIds[i]=-1; //does not belong to any component for(int compID=0;compID<comps.Length;compID++) foreach(Edge link in comps[compID]) nodesToCompIds[link.source]=nodesToCompIds[link.target]=compID; //if initVertex does not belong to any components mark it as belonging to the //bigger component if(this.nodesToCompIds[this.initVertex]==-1) this.nodesToCompIds[this.initVertex]=this.closureID; else this.joinedComps[this.nodesToCompIds[this.initVertex]]=true; #endregion SingleSourceShortestPaths shortestPaths= new SingleSourceShortestPaths( new BasicGraph(this.initVertex,this.mustEdges, this.optionalEdges), this.initVertex); shortestPaths.Calculate(); //use the spanning tree of the SingleSourceShortestPaths //to connect the components with initVertex if(this.nodesToCompIds[this.initVertex]==-1) this.nodesToCompIds[this.initVertex]=this.closureID; bool done=false; //add the first component - may be is the only one AddComponent(0,shortestPaths); while(!done){ done=true; //find non-joined component for(int compID=0;compID<comps.Length;compID++){ if( joinedComps[compID]==false){ done=false; AddComponent(compID,shortestPaths); continue; } } } this.newML=new Edge[linksToCompIDs.Count]; this.linksToCompIDs.Keys.CopyTo(this.newML,0); this.newOL=new Edge[this.optionalEdges.Length-newML.Length+mustEdges.Length]; int j=0; foreach(Edge l in optionalEdges) if(linksToCompIDs.Contains(l)==false) this.newOL[j++]=l; }