protected void CheckSwapPaths(int firstIndex, int secondIndex, OperatingData operatingData) { var totalDistance = operatingData.Distance; var oldDistance1 = CalculateDistance(operatingData.PathNodes[firstIndex], operatingData.PathNodes[firstIndex + 1]); var oldDistance2 = CalculateDistance(operatingData.PathNodes[secondIndex], operatingData.PathNodes[secondIndex >= operatingData.PathNodes.Count - 1 ? 0 : secondIndex + 1]); totalDistance -= (oldDistance1 + oldDistance2); var newDistance1 = CalculateDistance(operatingData.PathNodes[firstIndex], operatingData.PathNodes[secondIndex]); var newDistance2 = CalculateDistance(operatingData.PathNodes[firstIndex + 1], operatingData.PathNodes[secondIndex >= operatingData.PathNodes.Count - 1 ? 0 : secondIndex + 1]); totalDistance += (newDistance1 + newDistance2); if (totalDistance >= operatingData.Distance || totalDistance >= BestSwapPathsDistance) { return; } BestSwapPathsDistance = totalDistance; SwapPathsFirstIndex = firstIndex; SwapPathsSecondIndex = secondIndex; PathsChangeMade = true; }
private static OperatingData Recombine(OperatingData data1, OperatingData data2) { recombineIteration++; var recombinedData = new OperatingData(); ResolveEdgesMatrix(data1); ResolveEdgesMatrix(data2); var edgesCountMatrix = new Dictionary <Node, int>(); var sharedVertices = ResolveSharedVertices(data1.PathNodes, data2.PathNodes); var sharedEdgesMatrix = ResolveSharedEdgesMatrix(sharedVertices, data1.EdgesMatrix, data2.EdgesMatrix, out edgesCountMatrix); var newPathNodes = FillNodeList(sharedVertices); if (sharedVertices.Count < 50) { var nodesToConnect = RemoveUnnecessaryNodes(newPathNodes, edgesCountMatrix); //ConnectRemainingVertices(sharedVertices, sharedEdgesMatrix); ConnectRemainingVertices(nodesToConnect, sharedEdgesMatrix); } recombinedData.EdgesMatrix = sharedEdgesMatrix; //recombinedData.PathNodes = ConvertEdgesMatrixToList(sharedEdgesMatrix); recombinedData.PathNodes = newPathNodes; recombinedData.UnusedNodes = FindUnusedNodes(recombinedData.PathNodes.ToList()); recombinedData.Distance = CalculatePathDistance(recombinedData.PathNodes.ToList()); return(recombinedData); }
protected void SwapPaths(OperatingData operatingData) { var newPath = (List <Node>)operatingData.PathNodes; newPath.Reverse(SwapPathsFirstIndex + 1, Math.Abs(SwapPathsSecondIndex - SwapPathsFirstIndex)); operatingData.Distance = BestSwapPathsDistance; }
private static List <OperatingData> GenerateInitialPopulation() { var randomSolution = new RandomSolution(); var localSearch = new LocalSearch(); var population = new List <OperatingData>(); for (var i = 0; i < DAL.PopulationSize; i++) { var solution = new OperatingData { UnusedNodes = DAL.Instance.Nodes.CloneList() }; localSearch.Optimize(randomSolution.FindRouteFromRandomStart(solution)); while (population.Any(solution2 => solution2.Distance == solution.Distance)) { solution = new OperatingData { UnusedNodes = DAL.Instance.Nodes.CloneList() }; localSearch.Optimize(randomSolution.FindRouteFromRandomStart(solution)); } population.Add(solution); } return(population); }
public OperatingAndStatisticsData CloneData() { return(new OperatingAndStatisticsData { OperatingData = OperatingData.CloneData() }); }
public Node FindRandomNeighbour(Node sourceNode, OperatingData operatingData) { var randomNode = operatingData.UnusedNodes[RandomGenerator.Next(0, operatingData.UnusedNodes.Count)]; operatingData.Distance += CalculateDistance(sourceNode, randomNode); return(randomNode); }
protected void SwapVertices(OperatingData operatingData) { var newNode = operatingData.UnusedNodes[SwapVerticesUnusedNodeIndex]; var oldNode = operatingData.PathNodes[SwapVerticesPathNodeIndex]; operatingData.PathNodes[SwapVerticesPathNodeIndex] = newNode; operatingData.UnusedNodes[SwapVerticesUnusedNodeIndex] = oldNode; operatingData.Distance = BestSwapVerticesDistance; }
protected void FindBestSwapVertices(OperatingData operatingData) { for (var i = 0; i < operatingData.PathNodes.Count; i++) { for (var j = 0; j < operatingData.UnusedNodes.Count; j++) { CheckSwapVertices(i, j, operatingData); } } }
private static void ResolveEdgesMatrix(OperatingData data) { var nodes = data.PathNodes; data.EdgesMatrix[nodes.First()][nodes.Last()] = true; data.EdgesMatrix[nodes.Last()][nodes.First()] = true; for (var i = 0; i < nodes.Count - 1; i++) { data.EdgesMatrix[nodes[i]][nodes[i + 1]] = true; data.EdgesMatrix[nodes[i + 1]][nodes[i]] = true; } }
protected void FindBestSwapPaths(OperatingData operatingData) { for (var i = 0; i < operatingData.PathNodes.Count - 2; i++) { for (var j = i + 2; j < operatingData.PathNodes.Count; j++) { if (i == 0 && j == operatingData.PathNodes.Count - 1) { continue; } CheckSwapPaths(i, j, operatingData); } } }
public OperatingData FindRoute(Node startNode, OperatingData operatingData) { var actualNode = startNode; for (var i = 0; i < ResultNodesLimit; i++) { operatingData.PathNodes.Add(actualNode); operatingData.UnusedNodes.Remove(actualNode); actualNode = FindRandomNeighbour(actualNode, operatingData); } operatingData.Distance += CalculateDistance(operatingData.PathNodes.Last(), operatingData.PathNodes.First()); return(operatingData); }
public OperatingData FindRouteFromRandomStart(OperatingData operatingData) { var actualNode = operatingData.UnusedNodes[RandomGenerator.Next(0, operatingData.UnusedNodes.Count)]; for (var i = 0; i < ResultNodesLimit; i++) { operatingData.PathNodes.Add(actualNode); operatingData.UnusedNodes.Remove(actualNode); actualNode = FindRandomNeighbour(actualNode, operatingData); } operatingData.Distance += CalculateDistance(operatingData.PathNodes.Last(), operatingData.PathNodes.First()); return(operatingData); }
private static OperatingData FindWorstSolution(List <OperatingData> population) { var worstSolution = new OperatingData { Distance = 0 }; foreach (var solution in population) { if (solution.Distance > worstSolution.Distance) { worstSolution = solution; } } return(worstSolution); }
protected void CheckSwapVertices(int pathNodeIndex, int unusedNodeIndex, OperatingData operatingData) { var totalDistance = operatingData.Distance; var previousPathNodeIndex = pathNodeIndex - 1 < 0 ? operatingData.PathNodes.Count - 1 : pathNodeIndex - 1; var nextPathNodeIndex = pathNodeIndex + 1 > operatingData.PathNodes.Count - 1 ? 0 : pathNodeIndex + 1; totalDistance -= CalculateDistance(operatingData.PathNodes[previousPathNodeIndex], operatingData.PathNodes[pathNodeIndex]) + CalculateDistance(operatingData.PathNodes[pathNodeIndex], operatingData.PathNodes[nextPathNodeIndex]); totalDistance += CalculateDistance(operatingData.PathNodes[previousPathNodeIndex], operatingData.UnusedNodes[unusedNodeIndex]) + CalculateDistance(operatingData.UnusedNodes[unusedNodeIndex], operatingData.PathNodes[nextPathNodeIndex]); if (totalDistance >= operatingData.Distance || totalDistance >= BestSwapVerticesDistance) { return; } BestSwapVerticesDistance = totalDistance; SwapVerticesPathNodeIndex = pathNodeIndex; SwapVerticesUnusedNodeIndex = unusedNodeIndex; VerticesChangeMade = true; }
public void Optimize(OperatingData operatingData) { while (VerticesChangeMade || PathsChangeMade) { if (PathsChangeMade) { PathsChangeMade = false; FindBestSwapPaths(operatingData); } if (VerticesChangeMade) { VerticesChangeMade = false; FindBestSwapVertices(operatingData); } if (!VerticesChangeMade && !PathsChangeMade) { break; } if (BestSwapPathsDistance < BestSwapVerticesDistance) { SwapPaths(operatingData); } else { SwapVertices(operatingData); } } //ResetAlgorithm(); operatingData.Distance = BestSwapPathsDistance < BestSwapVerticesDistance ? BestSwapPathsDistance : BestSwapVerticesDistance; ResetAlgorithm(); }