internal override void OnInitializing() { base.OnInitializing(); Console.ForegroundColor = ConsoleColor.Green; SendMessage(MessageCode.GreedyStart, Type); Console.ForegroundColor = ConsoleColor.Gray; Tour = new CityMapGraph(); NodesQueue = new Queue <int>(); SolutionsHistory = new Collection <ToSolution>(); CityMapClone = Solver.CityMapGraph.DeepCopy(); _canDoImprovements = default; int maxNodesToAdd = default; if (Parameters.ContainsKey(ParameterCodes.CanDoImprovements)) { _canDoImprovements = Parameters[ParameterCodes.CanDoImprovements]; } if (Parameters.ContainsKey(ParameterCodes.GreedyMaxNodesToAdd)) { maxNodesToAdd = Parameters[ParameterCodes.GreedyMaxNodesToAdd]; } InitializeNodesQueue(maxNodesToAdd); StartingPoint = CityMapClone.GetStartPoint(); if (StartingPoint is null) { throw new OperationCanceledException( $"{nameof(StartingPoint)} in {nameof(NearestNeighbor)}"); } StartingPoint.IsVisited = true; _timeSpent = DateTime.Now; }
/// <summary> /// This implementation is the classic GetClosestNeighborByScore. /// It returns the best candidate node near to point of interest passed as argument. /// </summary> /// <param name="interestPoint">Point of interest</param> /// <returns></returns> protected virtual InterestPointWorker GetBestNeighbor(InterestPointWorker interestPoint) { int bestScore = default; InterestPointWorker candidateNode = default; var adjPoiIds = CityMapClone.GetAdjacentNodes(interestPoint.Entity.Id); adjPoiIds.ToList().ForEach(adjPoiId => { var adjNode = CityMapClone[adjPoiId]; if (adjNode.IsVisited) { return; } var adjNodeScore = adjNode.Entity.Score.Value; if (adjNodeScore > bestScore) { bestScore = adjNodeScore; candidateNode = adjNode; } else if (adjNodeScore == bestScore) { CityMapGraph.SetRandomCandidateId(candidateNode, adjNode, out int pointId); candidateNode = CityMapClone[pointId]; } }); return(candidateNode); }
/// <summary> /// This implementation is the knapsack style Best Closest Neighbor variant. /// Firstly it gets neighbors of point of interest passed by argument. /// Secondly it orders that points by score / weight decreasing value. /// The weight value is obtained by getting the edge between param node and the neighbor node. /// Finally it returns the first not visited node of that point list. /// </summary> /// <param name="interestPoint">Point of interest</param> /// <returns></returns> protected override InterestPointWorker GetBestNeighbor(InterestPointWorker interestPoint) { var adjPoiIds = CityMapClone.GetAdjacentNodes(interestPoint.Entity.Id); var tempNodes = new Collection <(int NodeKey, double Ratio)>(); adjPoiIds.ToList().ForEach(adjPoiId => { var node = CityMapClone[adjPoiId]; if (node.IsVisited) { return; } RouteWorker edge = CityMapClone.GetEdge(interestPoint.Entity.Id, adjPoiId); if (edge is null) { return; } var value = node.Entity.Score.Value / edge.Weight.Invoke(); tempNodes.Add((adjPoiId, value)); }); var tempNodesSorted = from node in tempNodes orderby node.Ratio descending select node.NodeKey; InterestPointWorker candidateNode = default; int candidateNodeId = tempNodesSorted.FirstOrDefault(); if (candidateNodeId != 0) { candidateNode = CityMapClone[candidateNodeId]; } return(candidateNode); }