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); }