Esempio n. 1
0
        public FastestPathTable FindShortestPaths(FindShortestPathsRequest request)
        {
            _findShortestPathsRequestValidator.ValidateAndThrowErrors(request);
            ValidateNodes(request.Nodes, request.PrimaryNodeId);

            var fastestPathTable = CreateFastestPathTable(request.Nodes, request.PrimaryNodeId);
            var visitedNodeIds   = new HashSet <string>();
            var nodesById        = request.Nodes.ToDictionary(n => n.Id);
            var rowsById         = fastestPathTable.Rows.ToDictionary(r => r.NodeId);

            while (visitedNodeIds.Count < request.Nodes.Count - 1)
            {
                var lowestCostNodeId = FindLowestCostNodeId(fastestPathTable, visitedNodeIds);

                // Catches graphs that aren't connected...
                if (lowestCostNodeId == null)
                {
                    break;
                }

                UpdateNeighborCosts(rowsById, visitedNodeIds, nodesById[lowestCostNodeId]);
                visitedNodeIds.Add(lowestCostNodeId);
            }

            return(fastestPathTable);
        }
            public void ShouldThrowError_WhenGivenNullNodeCollection()
            {
                // Arrange
                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = null, PrimaryNodeId = "A"
                };

                // Act
                Func <FastestPathTable> result1 = () => dijkstraService.FindShortestPaths(request);

                // Assert
                result1.Should().Throw <UserReportableException>().WithMessage(BellErrorMessageKeys.VALIDATION_ERRORS);
            }
            public void ShouldThrowError_WhenPrimaryNodeIdDoesNotExistInNodeCollection()
            {
                // Arrange
                var nodes           = GenerateUndirectedGraphNodes();
                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "SOME_OTHER_NODE_ID"
                };

                // Act
                Func <FastestPathTable> result = () => dijkstraService.FindShortestPaths(request);

                // Assert
                result.Should().Throw <UserReportableException>().WithMessage(ErrorMessageKeys.ERROR_NODE_ID_NOT_FOUND_IN_COLLECTION);
            }
            public void ShouldGenerateValidTable_WhenGivenUnconnectedGraphNodes()
            {
                // Arrange
                var nodes = GenerateUndirectedGraphNodes();

                nodes.Add(new Node {
                    Id = "F", Neighbors = null
                });

                var expectedResult = new FastestPathTable()
                {
                    PrimaryNodeId = "A",
                    Rows          = new List <FastestPathRow>
                    {
                        new FastestPathRow {
                            NodeId = "A", LowestCost = 0, NeighborNodeId = null
                        },
                        new FastestPathRow {
                            NodeId = "B", LowestCost = 3, NeighborNodeId = "D"
                        },
                        new FastestPathRow {
                            NodeId = "C", LowestCost = 7, NeighborNodeId = "E"
                        },
                        new FastestPathRow {
                            NodeId = "D", LowestCost = 1, NeighborNodeId = "A"
                        },
                        new FastestPathRow {
                            NodeId = "E", LowestCost = 2, NeighborNodeId = "D"
                        },
                        new FastestPathRow {
                            NodeId = "F", LowestCost = int.MaxValue, NeighborNodeId = null
                        }
                    }
                };

                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "A"
                };

                // Act
                var results = dijkstraService.FindShortestPaths(request);

                // Assert
                results.Should().BeEquivalentTo(expectedResult);
            }
            public void ShouldThrowError_WhenGivenUnmatchingCostsForNeighbors()
            {
                // Arrange
                var nodes = GenerateUndirectedGraphNodes();

                nodes[1].Neighbors[0].Cost++;

                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "A"
                };

                // Act
                Func <FastestPathTable> result = () => dijkstraService.FindShortestPaths(request);

                // Assert
                result.Should().Throw <UserReportableException>().WithMessage(ErrorMessageKeys.ERROR_UNMATCHING_EDGE_COSTS);
            }
            public void ShouldThrowError_WhenGivenDuplicateNeighborNodeIds()
            {
                // Arrange
                var nodes = GenerateUndirectedGraphNodes();

                nodes[1].Neighbors[1].NodeId = nodes[1].Neighbors[3].NodeId;

                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "A"
                };

                // Act
                Func <FastestPathTable> result = () => dijkstraService.FindShortestPaths(request);

                // Assert
                result.Should().Throw <UserReportableException>().WithMessage(ErrorMessageKeys.ERROR_DUPLICATE_NEIGHBOR_NODE_ID);
            }
            public void ShouldThrowError_WhenGivenBlankNodeIds()
            {
                // Arrange
                var nodes = GenerateUndirectedGraphNodes();

                nodes[2].Id = " ";

                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "A"
                };

                // Act
                Func <FastestPathTable> result = () => dijkstraService.FindShortestPaths(request);

                // Assert
                result.Should().Throw <UserReportableException>().WithMessage(BellErrorMessageKeys.ERROR_STRING_ONLY_WHITE_SPACE);
            }
            public void ShouldGenerateValidTable_WhenGivenDirectedGraphNodes()
            {
                // Arrange
                var nodes = GenerateUndirectedGraphNodes();

                // Remove the neighbor E from node D to make it directed (D->E)...
                var nodeDNeighbors = nodes.FirstOrDefault(n => n.Id == "D").Neighbors;

                nodeDNeighbors.RemoveAll(n => n.NodeId == "E");

                var expectedResult = new FastestPathTable()
                {
                    PrimaryNodeId = "A",
                    Rows          = new List <FastestPathRow>
                    {
                        new FastestPathRow {
                            NodeId = "A", LowestCost = 0, NeighborNodeId = null
                        },
                        new FastestPathRow {
                            NodeId = "B", LowestCost = 3, NeighborNodeId = "D"
                        },
                        new FastestPathRow {
                            NodeId = "C", LowestCost = 8, NeighborNodeId = "B"
                        },
                        new FastestPathRow {
                            NodeId = "D", LowestCost = 1, NeighborNodeId = "A"
                        },
                        new FastestPathRow {
                            NodeId = "E", LowestCost = 5, NeighborNodeId = "B"
                        }
                    }
                };

                var dijkstraService = CreateService();
                var request         = new FindShortestPathsRequest {
                    Nodes = nodes, PrimaryNodeId = "A"
                };

                // Act
                var results = dijkstraService.FindShortestPaths(request);

                // Assert
                results.Should().BeEquivalentTo(expectedResult);
            }