예제 #1
0
        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);
        }
예제 #2
0
 internal void Validate(ToSolution solution)
 {
     foreach (var constraint in _constraintsToValidate)
     {
         bool isValid = constraint.Value.Invoke(solution);
         solution.ProblemConstraints.Add(constraint.Key, isValid);
     }
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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;
            });
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
 internal void EnqueueSolution(ToSolution solution) =>
 _solutionsQueue.Add(solution);
예제 #7
0
 private bool IsTMaxConstraintSatisfied(ToSolution solution)
 {
     return(solution.TimeSpent <= _tMax);
 }
예제 #8
0
 private int CalculatePenalty(ToSolution solution) => PenaltyAmount;