Пример #1
0
        /// <summary>
        /// Create graph structure
        /// </summary>
        /// <param name="solvroCity">Data that should be used to create graph</param>
        void CreateGraph(SolvroCityData solvroCity)
        {
            Nodes    = new List <SolvroCityGraphNode>();
            Directed = solvroCity.directed;
            foreach (SolvroCityNode node in solvroCity.nodes)
            {
                Nodes.Add(new SolvroCityGraphNode(node));
            }
            foreach (SolvroCityLink link in solvroCity.links)
            {
                SolvroCityGraphNode sourceNode      = Nodes.Find((node) => node.id == link.source);
                SolvroCityGraphNode destinationNode = Nodes.Find((node) => node.id == link.target);

                sourceNode.Links.Add(new SolvroCityGraphLink(link, sourceNode, destinationNode));
                destinationNode.Links.Add(new SolvroCityGraphLink(link, sourceNode, destinationNode, true, Directed ? false : true));
            }
        }
Пример #2
0
        /// <summary>
        /// Find path between two stops using graph structure
        /// </summary>
        /// <param name="source">Node name where path should start</param>
        /// <param name="destination">Node name where path should end</param>
        /// <returns>Path response: List of nodes for found path and length of path</returns>
        public PathResponse FindPath(string source, string destination)
        {
            SolvroCityGraphNode sourceNode      = Nodes.Find((node) => node.stop_name == source);      //first node
            SolvroCityGraphNode destinationNode = Nodes.Find((node) => node.stop_name == destination); //last node

            if (sourceNode == null || destinationNode == null)                                         // check if nodes exists before attempting to find path
            {
                return(new PathResponse());
            }

            List <SolvroCityGraphNode> nodesCpy     = new List <SolvroCityGraphNode>(Nodes); // create copy of nodes on which we can operate
            List <SolvroCityGraphNode> nodesChecked = new List <SolvroCityGraphNode>();      // create empty list for visited nodes

            for (int i = 0; i < nodesCpy.Count; i++)                                         // init weigth of nodes
            {
                nodesCpy[i].weightSum = uint.MaxValue;
                nodesCpy[i].prevNode  = null;
            }
            sourceNode.weightSum = 0;
            while (nodesCpy.Count > 0) // proceed with algorithm
            {
                SolvroCityGraphNode minNode = null;
                foreach (SolvroCityGraphNode node in nodesCpy)
                {
                    if (minNode == null || minNode.weightSum > node.weightSum)
                    {
                        minNode = node;
                    }
                }
                nodesChecked.Add(minNode);
                nodesCpy.RemoveAll((node) => node.id == minNode.id);
                for (int i = 0; i < minNode.Links.Count; i++)
                {
                    if (minNode.Links[i].Available)
                    {
                        SolvroCityGraphNode neighbor = minNode.Links[i].TargetNode;
                        if (minNode.weightSum != uint.MaxValue && neighbor.weightSum > minNode.weightSum + minNode.Links[i].distance)
                        {
                            neighbor.weightSum = minNode.weightSum + minNode.Links[i].distance;
                            neighbor.prevNode  = minNode;
                        }
                    }
                }
            }
            //best path have been found, proceed to generating "nice" data
            destinationNode = nodesChecked.Find((node) => node == destinationNode);
            PathResponse pathResponse = new PathResponse()
            {
                distance = destinationNode.weightSum
            };
            List <SolvroCityNode> foundNodes = new List <SolvroCityNode>();

            while (destinationNode.prevNode != null) // follow path from target to source (backwards)
            {
                foundNodes.Add(new SolvroCityNode()
                {
                    id = destinationNode.id, stop_name = destinationNode.stop_name
                });
                destinationNode = destinationNode.prevNode;
            }
            if (destinationNode != sourceNode)
            {
                pathResponse = new PathResponse();
            }
            else
            {
                foundNodes.Add(new SolvroCityNode()
                {
                    id = destinationNode.id, stop_name = destinationNode.stop_name
                });
                foundNodes.Reverse(); //path is reversed so we need to call reverse to have it in correct order
                pathResponse.stops = foundNodes;
            }
            return(pathResponse);
        }