Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
 }