private void ChangeLinksExistenceState(Graph graph, GraphPath secundaryPath, Graph ring) { for (int i = 0; i < secundaryPath.Path.Count - 1; i++) { GraphLink link = ring.Links.FirstOrDefault(r => r.From == secundaryPath.Path[i] && r.To == secundaryPath.Path[i + 1]); if (link != null) { ring.RemoveLink(secundaryPath.Path[i], secundaryPath.Path[i + 1]); ring.RemoveLink(secundaryPath.Path[i + 1], secundaryPath.Path[i]); } else { link = graph.Links.FirstOrDefault(r => r.From == secundaryPath.Path[i] && r.To == secundaryPath.Path[i + 1]); GraphLink linkCopy = link.CopyObject <GraphLink>(); GraphLink linkCopy2 = link.CopyObject <GraphLink>(); linkCopy2.From = link.To; linkCopy2.To = link.From; //set slots and granularity ring.Links.Add(linkCopy2); ring.Links.Add(linkCopy); } } }
public List <GraphPath> GetPaths(Graph graph, GraphNode nodeFrom, GraphNode nodeTo, int numberOfPaths, bool directional = false) { List <GraphPath> paths = new List <GraphPath>(); List <InternalNodeDijkstra> priorityList = new List <InternalNodeDijkstra>(); GraphPath path = new GraphPath(new string[] { nodeFrom.Id }); Dictionary <string, int> counter = StartCounter(graph); priorityList.Add(new InternalNodeDijkstra(nodeFrom.Id, path, 0)); InternalNodeDijkstra nodeDijkstra; do { nodeDijkstra = priorityList.First(); priorityList = priorityList.Skip(1).ToList(); if (nodeDijkstra.NodeId == nodeTo.Id) { paths.Add(nodeDijkstra.Path); if (paths.Count == numberOfPaths) { break; } continue; } if (++counter[nodeDijkstra.NodeId] > numberOfPaths) { continue; } foreach (var neighboor in GetNodeNeighboorsIds(graph, nodeDijkstra, directional)) { if (nodeDijkstra.Path.Path.Contains(neighboor)) { continue; } path = new GraphPath(nodeDijkstra.Path.Path); path.Path.Add(neighboor); GraphLink link = graph.Links.FirstOrDefault(r => r.To == neighboor); if (link == null && !directional) { link = graph.Links.FirstOrDefault(r => r.From == neighboor); } priorityList.Add(new InternalNodeDijkstra(neighboor, path, nodeDijkstra.Distance + link.Cost)); priorityList.Sort((x, y) => x.CompareTo(y)); } nodeDijkstra = null; } while (priorityList.Count != 0); return(paths); }
public List <Tuple <GraphPath, GraphPath> > GetDisjointedPaths(Graph graph, GraphNode nodeFrom, GraphNode nodeTo, int numberOfMainPaths, int numberOfSecundaryPaths) { Graph bidiretionalGraph = graph.CopyObject <Graph>(); BuildDirectionLinks(bidiretionalGraph); List <Tuple <GraphPath, GraphPath> > disjointedPaths = new List <Tuple <GraphPath, GraphPath> >(); List <GraphPath> mainPaths = PathSearcher.GetPaths(graph, nodeFrom, nodeTo, numberOfMainPaths, true); foreach (GraphPath mainPath in mainPaths) { Graph graphCopy = bidiretionalGraph.CopyObject <Graph>(); for (int i = 0; i < mainPath.Path.Count - 1; i++) { graphCopy.RemoveLink(mainPath.Path[i], mainPath.Path[i + 1]); graphCopy.ChangeLinkCost(mainPath.Path[i + 1], mainPath.Path[i], 0); } List <GraphPath> secundaryPaths = PathSearcher.GetPaths(graphCopy, nodeFrom, nodeTo, numberOfSecundaryPaths, true); if (secundaryPaths.Count() == 0) { throw new Exception($"It's not possible to find two disjointed paths between {nodeFrom}->{nodeTo}"); } foreach (GraphPath secundaryPath in secundaryPaths) { Graph ring = CreateRingSubGraph(bidiretionalGraph, mainPath); ChangeLinksExistenceState(bidiretionalGraph, secundaryPath, ring); List <GraphPath> path = PathSearcher.GetPaths(ring, nodeFrom, nodeTo, 1, true); GraphPath resultMainPath = path.FirstOrDefault(); for (int i = 0; i < resultMainPath.Path.Count - 1; i++) { ring.RemoveLink(resultMainPath.Path[i], resultMainPath.Path[i + 1]); ring.RemoveLink(resultMainPath.Path[i + 1], resultMainPath.Path[i]); } List <GraphPath> path2 = PathSearcher.GetPaths(ring, nodeFrom, nodeTo, 1, true); GraphPath resultSecundaryPath = path2.FirstOrDefault(); Tuple <GraphPath, GraphPath> disjointedPath = new Tuple <GraphPath, GraphPath>(resultMainPath, resultSecundaryPath); disjointedPaths.Add(disjointedPath); } } return(disjointedPaths); }
private Graph CreateRingSubGraph(Graph graph, GraphPath mainPath) { Graph ring = graph.CopyObject <Graph>(); ring.Links = new List <GraphLink>(); for (int i = 0; i < mainPath.Path.Count - 1; i++) { GraphLink link = graph.Links.FirstOrDefault(r => r.From == mainPath.Path[i] && r.To == mainPath.Path[i + 1]); GraphLink linkCopy = link.CopyObject <GraphLink>(); //set slots and granularity ring.Links.Add(linkCopy); } BuildDirectionLinks(ring); return(ring); }
public InternalNodeDijkstra(string nodeId, GraphPath path, long distance) { NodeId = nodeId; Path = path; Distance = distance; }