private bool IsTimeWindowsConstraintSatisfied(ToSolution solution) { bool satisfied = true; CityMapGraph solutionGraph = solution.Tour; using (var processingNodes = solutionGraph.TourPoints.GetEnumerator()) { while (satisfied && processingNodes.MoveNext()) { var node = processingNodes.Current; TimeSpan visitTime = default; if (node?.Entity.TimeVisit != null) { visitTime = node.Entity.TimeVisit.Value; } if (node == null) { continue; } DateTime nodeTime = node.ArrivalTime + node.WaitOpeningTime; foreach (var time in node.Entity.OpeningTimes) { if (time.ClosingTime.HasValue && nodeTime > (time.ClosingTime.Value - visitTime)) { satisfied = false; //continue; } } } } return(satisfied); }
internal void Validate(ToSolution solution) { foreach (var constraint in _constraintsToValidate) { bool isValid = constraint.Value.Invoke(solution); solution.ProblemConstraints.Add(constraint.Key, isValid); } }
/// <summary> /// Creates the problem contained in the configuration /// and initializes the working configuration. /// </summary> /// <param name="configuration"></param> private void InitSolver(Configuration configuration) { if (_solutionsQueue is null) { _solutionsQueue = new BlockingCollection <ToSolution>(); } ToSolution.ResetSequenceId(); WorkingConfiguration = configuration; IsMonitoringEnabled = configuration.AlgorithmMonitoring; Problem = ProblemFactory.CreateProblem(configuration.CurrentProblem); }
internal void Evaluate(ToSolution solution) { var objectiveFunc = Solver.Problem.ObjectiveFunc; solution.Cost = objectiveFunc.Invoke(solution); var penaltyFunc = Solver.Problem.PenaltyFunc; // Get the violated constraints to invoke the PenaltyFunc delegate. var violatedConstraints = solution.ProblemConstraints .Where(constraint => constraint.Value == false) .ToList(); violatedConstraints.ForEach( delegate { int penalty = penaltyFunc.Invoke(solution); solution.Cost += penalty; solution.Penalty = penalty < 0 ? -penalty : penalty; }); }
/// <summary> /// Calculates the solution cost passed as parameter using an equation of convex combination. /// </summary> /// <param name="solution"> /// Solution to evaluate. /// </param> /// <returns> /// An Evaluation Object. /// </returns> private int CalculateCost(ToSolution solution) { // Calcolo del termine del gradimento. int scoreTerm = solution.Tour.Nodes.Sum(node => node.Entity.Score.Value); // Il peso che determina l'importanza dei termini dell'equazione. double lambda = Solver.Instance.CurrentObjectiveFunctionWeight; // Calcolo del termine che da peso alla distanza tra il nodo corrente e quello precedente. // In particolare, vengono privilegati i nodi molto vicini con un peso molto alto // che darĂ quindi un maggior gradimento. double distanceTerm = solution.Tour.Nodes.Sum(node => { RouteWorker edge = solution.Tour.GetEdges(node.Entity.Id).FirstOrDefault(); if (edge is null) { return(0); } double distanceWeight = GetDistanceTermWeight(edge.Weight.Invoke()); return(distanceWeight * node.Entity.Score.Value); }); return((int)Math.Round(lambda * scoreTerm + (1 - lambda) * distanceTerm)); }
internal void EnqueueSolution(ToSolution solution) => _solutionsQueue.Add(solution);
private bool IsTMaxConstraintSatisfied(ToSolution solution) { return(solution.TimeSpent <= _tMax); }
private int CalculatePenalty(ToSolution solution) => PenaltyAmount;