Пример #1
0
 public void AddPath(Path path)
 {
     try
     {
         Paths.Add(path.Identifier, path);
     }
     catch (ArgumentException)
     {
         Paths.Remove(path.Identifier);
         Paths.Add(path.Identifier, path);
     }
 }
Пример #2
0
 public bool RemovePath(Path path)
 {
     bool result = Paths.Remove(path.Identifier);
     
     return result;
 }
Пример #3
0
        public void ShortestPathToBlockedEdge()
        {
            Graph graph = new Graph(1);

            Node a = new Node("a");
            Node b = new Node("b");
            Node c = new Node("c");
            Node d = new Node("d");
            Node e = new Node("e");

            graph.AddNode(a);
            graph.AddNode(b);
            graph.AddNode(c);
            graph.AddNode(d);
            graph.AddNode(e);

            graph.AddUndirectedEdge(new Tuple<Node, int>(a, 1), new Tuple<Node, int>(b, 3), 1);
            graph.AddUndirectedEdge(new Tuple<Node, int>(b, 2), new Tuple<Node, int>(c, 0), 2);
            graph.AddUndirectedEdge(new Tuple<Node, int>(c, 3), new Tuple<Node, int>(d, 1), 3); //block this
            graph.AddUndirectedEdge(new Tuple<Node, int>(d, 0), new Tuple<Node, int>(e, 2), 200);
            graph.AddUndirectedEdge(new Tuple<Node, int>(e, 1), new Tuple<Node, int>(a, 3), 100);

            graph.BlockEdge(c, d);

            Path expectedPath = new Path()
            {
                Identifier = 1,
                Nodes = new List<Node>(){a, b, c}
            };

            Path actualPath = graph.PathToBlockedEdge(a, graph.BlockedEdges.FirstOrDefault());
            actualPath.Identifier = 1;

            Assert.IsTrue(expectedPath.Equals(actualPath));
        }
Пример #4
0
        public void ShortestPathThreeNodesTwoPaths()
        {
            Graph g = new Graph(1);

            Node a = new Node("a");
            Node b = new Node("b");
            Node c = new Node("c");

            Edge ab = new Edge(20);
            Edge ac = new Edge(10);
            Edge cb = new Edge(5);

            g.AddNode(a);
            g.AddNode(b);
            g.AddNode(c);

            g.AddUndirectedEdge(new Tuple<Node, int>(a, 0), new Tuple<Node, int>(b, 0), ab);
            g.AddUndirectedEdge(new Tuple<Node, int>(a, 1), new Tuple<Node, int>(c, 0), ac);
            g.AddUndirectedEdge(new Tuple<Node, int>(c, 1), new Tuple<Node, int>(b, 1), cb);

            Path actual = g.ShortestPath(a, b);

            Path expected = new Path();
            expected.Nodes.Add(a);
            expected.Nodes.Add(c);
            expected.Nodes.Add(b);

            Assert.IsTrue(expected.Equals(actual));
        }
Пример #5
0
        public void ShortestPathTwoNodes()
        {
            Graph g = new Graph(1);

            Node a = new Node("a");
            Node b = new Node("b");

            Edge ab = new Edge(10);

            g.AddNode(a);
            g.AddNode(b);

            g.AddUndirectedEdge(new Tuple<Node, int>(a, 0), new Tuple<Node, int>(b, 0), ab);

            Path actual = g.ShortestPath(a, b);

            Path expected = new Path();
            expected.Nodes.Add(a);
            expected.Nodes.Add(b);

            Assert.IsTrue(actual.Equals(expected));
        }
Пример #6
0
        public Path ShortestPath(Node from, Node to, Node ignore = null)
        {
            if (from == null)
            {
                throw new NodeException("From-node cannot be null");
            }

            if (to == null)
            {
                throw new NodeException("To-node cannot be null");
            }

            // Make sure that the nodes are in the graph
            if (!(Nodes.FindAll(x => x.Equals(from)).Count > 0 && Nodes.FindAll(x => x.Equals(to)).Count > 0))
            {
                throw new Exception("Either 'from'- or 'to'-node not in graph!");
            }

            List<Node> Q = new List<Node>();

            List<KeyValuePair<Node, double>> distance = new List<KeyValuePair<Node, double>>();
            List<KeyValuePair<Node, Node>> previous = new List<KeyValuePair<Node, Node>>();

            foreach (Node node in Nodes)
            {
                if (node == null)
                {
                    continue;
                }

                if (!node.Equals(from))
                {
                    // Set the distance of all nodes to infinity
                    distance.Add(new KeyValuePair<Node, double>(node, Double.MaxValue));

                    // Set the previous node for all nodes to null (undefined)
                    previous.Add(new KeyValuePair<Node, Node>(node, null));
                }

                // Add the node to Q
                Q.Add(node);
            }

            // The distance to the node "from" is always 0
            distance.Add(new KeyValuePair<Node, double>(from, 0));

            // While there are nodes to inspect
            while (Q.Count > 0)
            {
                // Find the node with lowest distance in Q
                Node selectedNode = Q.First();
                double oldDistance = Int32.MaxValue;

                foreach (Node node in Q)
                {
                    if (node == null)
                    {
                        continue;
                    }

                    double newDistance = distance.Find(x => x.Key.Equals(node)).Value;

                    if (newDistance < oldDistance)
                    {
                        selectedNode = node;
                        oldDistance = newDistance;
                    }
                }

                // Remove the node from u
                Q.Remove(selectedNode);

                foreach (KeyValuePair<Node, Edge> neighbour in selectedNode.Neighbours)
                {
                    if (neighbour.Key == null)
                    {
                        continue;
                    }

                    // If selected the from node, ignore the ignore node
                    if (ignore != null && selectedNode.Equals(from) && neighbour.Key.Equals(ignore))
                    {
                        continue;
                    }
                    
                    // Find the distance to the selected
                    double distanceToSelectedNode = distance.Find(x => x.Key.Equals(selectedNode)).Value;

                    // Find the distance to the selected neighbour
                    double distanceToNeighbour = selectedNode.Neighbours.Find(x => x.Key != null && x.Key.Equals(neighbour.Key)).Value.Weight;

                    // Add the two distances
                    double alt = distanceToSelectedNode + distanceToNeighbour;

                    double neighbourDistance = distance.Find(x => x.Key.Equals(neighbour.Key)).Value;

                    // Check if this new distance (alt) is shorter than what we know
                    if(alt < neighbourDistance)
                    {
                        // Update the distance
                        distance.RemoveAll(x => x.Key.Equals(neighbour.Key));
                        distance.Add(new KeyValuePair<Node, double>(neighbour.Key, alt));

                        // Set previous of neighbour to selectednode
                        previous.RemoveAll(x => x.Key.Equals(neighbour.Key));
                        previous.Add(new KeyValuePair<Node, Node>(neighbour.Key, selectedNode));
                    }
                }
            }

            // Create a new path
            Path p = new Path();

            // Start the path from the target (Path will later be inverted)
            Node lastNode = to;
            bool previousNode = true;

            // Add the last node to path
            p.Nodes.Add(lastNode);

            // Continue the loop as long as there are a previous node
            while (previousNode)
            {
                // Find the previous node
                KeyValuePair<Node, Node> newPreviousNode = previous.Find(x => x.Key != null && x.Key.Equals(lastNode));

                // Check if the last node is the start
                // There is a path, everything went well
                if (lastNode.Equals(from))
                {
                    previousNode = false;
                }
                // The last node has a previous node, everything is good
                // However, the path is still not finished, so continue the loop
                else if (newPreviousNode.Value != null)
                {
                    p.Nodes.Add(newPreviousNode.Value);
                    lastNode = newPreviousNode.Value;
                }
                // We are not at the start node, and not at a valid node,
                // hence, there must be a gab in the path. Error!
                else
                {
                    throw new PathException("Cannot generate path. Some edges might be blocked.");
                }
            }

            // Reserve the graph
            p.Nodes.Reverse();

            return p;
        }
Пример #7
0
        public ForkliftPath(Path path, Node initialNode = null)
        {
            if (path == null)
            {
                throw new Exception("Cannot convert null-path to ForkliftPath");
            }

            this.initialNode = initialNode;

            // If the initial node is null, check for the node in the forklift property
            if (this.initialNode == null)
            {
                this.initialNode = Database.Instance.Data.Forklifts.FirstOrDefault().Value.RearNode;
            }

            // Something is wrong, if the initial node is still null
            if (this.initialNode == null)
            {
                throw new NodeException("Initial node is null");
            }
            
            // Check if the initial node is also the first node in the path
            if (this.initialNode.Equals(path.Nodes.FirstOrDefault()))
            {
                throw new NodeException("First- and ignore node cannot be the same");
            }

            // Check if the initial node is a neighbour of the first node in the path
            Node node = path.Nodes.FirstOrDefault();
            if (node != null 
                && (node.Neighbours.FindAll(x => x.Key != null && x.Key.Equals(this.initialNode)).Count == 0
                && node.BlockedNeighbours.FindAll(x => x.Key != null && x.Key.Equals(this.initialNode)).Count == 0))
            {
                throw new NodeException("Could not find initial node '" + this.initialNode.Name + "' in the neighbours of node '" + node.Name + "'");
            }

            this.path = path;
            
            if (path.Nodes.Count <= 1)
            {
                return;
            }

            int initialIndex = 0;
            
            // Check if the initial node is in neighbours
            if (path.Nodes[0].Neighbours.FindAll(x => x.Key != null && x.Key.Equals(initialNode)).Count > 0)
            {
                initialIndex = path.Nodes[0].Neighbours.FindIndex(x => x.Key != null && x.Key.Equals(initialNode));
            }
            // The initial node was not in neighbours, then it must be in blocked neighbours
            else
            {
                initialIndex = path.Nodes[0].BlockedNeighbours.FindIndex(x => x.Key != null && x.Key.Equals(initialNode));
            }

            int fromIndex = initialIndex;
            int toIndex = -1;

            for (int i = 0; i < path.Nodes.Count - 1; i++)
            {
                Node fromNode = null;
                Node thisNode = path.Nodes[i];
                Node toNode = path.Nodes[i+1];

                if (i != 0)
                {
                    fromNode = path.Nodes[i - 1];
                    fromIndex = thisNode.Neighbours.FindIndex(x => x.Key != null && x.Key.Equals(fromNode));
                }

                toIndex = thisNode.Neighbours.FindIndex(x => x.Key != null && x.Key.Equals(toNode));

                forkliftPath.Add(navigationMatrix[fromIndex, toIndex]);
            }
        }