Пример #1
0
        /// <summary>
        /// Retourne une solution par la méthode des plus prches voisins
        /// </summary>
        /// <param name="parser">DataParser à utiliser</param>
        /// <param name="loadConstraint">Contrainte de chargement</param>
        /// <returns>Solution générée</returns>
        public static CVRPSolution PPVSolution(DataParser parser, double loadConstraint)
        {
            CVRPSolution sol = _AddVars(parser);                                    //Génère une instance de la solution

            sol.addNewRoute(parser);                                                //Créé une nouvelle route
            sol.setVariable(0, parser, loadConstraint);                             //Fixe le dépot dans la route
            double[,] arcWeight = (double[, ])parser.arcWeight.Clone();             //Créé une copie de la matrice des distance
            //On boucle tant que tout les clients ne sont pas servis
            while (sol.freeVarCount != 0)
            {
                int    nearestId = 0;                                                      //On initialise le plus proche voisin
                double distance  = arcWeight[sol.varsIdList[sol.varsIdList.Count - 1], 0]; //On initialise sa distance au dernier point visité
                //On parcours tout les voisins potentiels
                for (int j = 1; j < parser.nodeList.Count; j++)
                {
                    //Si l'arc vers j est réalisable et meilleur que les précédents considérés
                    if (arcWeight[sol.varsIdList[sol.varsIdList.Count - 1], j] != 0 && (distance == 0 || arcWeight[sol.varsIdList[sol.varsIdList.Count - 1], j] < distance))
                    {
                        //On met à jour le plus prche voisin
                        nearestId = j;
                        distance  = arcWeight[sol.varsIdList[sol.varsIdList.Count - 1], j];
                    }
                }
                //Si on revient au dépot, on créé une nouvelle solution
                if (nearestId == 0)
                {
                    sol.endRoute();
                }
                else
                {
                    sol.setVariable(nearestId, parser, loadConstraint);                     //On fixe le plus proche voisin
                }
                //On empêche le plus proche voisin d'être de nouveau disponible
                for (int j = 0; j < parser.nodeList.Count; j++)
                {
                    arcWeight[j, nearestId] = 0;
                }
            }
            sol.endSolution();              //On termine la solution
            return(sol);
        }
Пример #2
0
        /// <summary>
        /// Fonction récursive de résolution
        /// </summary>
        /// <param name="currentNode">Noeud courant de l'arbre</param>
        /// <param name="step">Profondeur du parcours</param>
        /// <returns>Noeud courant</returns>
        private TreeNode solve(TreeNode currentNode, int step)
        {
            //Si la solution est une solution finale
            if (currentNode.sol.isFinalSolution())
            {
                //On al déclare comme finale
                ((CVRPSolution)currentNode.sol).endSolution();
                currentNode.sol.eval = getFixedCost((CVRPSolution)currentNode.sol);
                //Si cette solution est meilleure
                if (majValue > currentNode.sol.eval)
                {
                    //On met à jour la meilleure solution et on l'affiche
                    majValue = currentNode.sol.eval;
                    bestSol  = (CVRPSolution)currentNode.sol;
                    logger.log("Meilleur solution trouvée de coût:" + ((int)Math.Round(currentNode.sol.eval)).ToString(), Message.Level.Warning);
                    computedSteps++;
                    displaySolution(bestSol);
                }
                else
                {
                    currentNode.isLocked = true;                        //On bloque la solution
                    computedSteps++;
                }
                updateBenchmark(step);
                return(currentNode);
            }
            else
            {
                List <TreeNode> nextSol = new List <TreeNode>();                //On initialise la liste des enfants
                for (int i = 0; i < _pb.varCount; i++)
                {
                    //Pour chaque variable en encors libre
                    if (!currentNode.sol.isFixed(i))
                    {
                        CVRPSolution nSol1 = (CVRPSolution)currentNode.sol.copy();                              //On copie la solution
                        nSol1.setVariable(i, data, loadConstraint);                                             //On fixe une nouvelle variable
                        nSol1.eval = evaluateSolution(nSol1, step);                                             //On détermine la borne inférieure
                        //Si la solution est viable
                        //> ou < selon minimisation ou maximisation
                        if (nSol1.eval <= majValue)
                        {
                            nextSol.Add(new TreeNode(nSol1, null));                             //On l'ajoute aux enfants
                        }
                        else
                        {
                            computedSteps++;
                        }
                        //Si on peut obtenir une autre solution en créant une nouvelle route
                        if (nSol1.routes.Count == ((CVRPSolution)currentNode.sol).routes.Count)
                        {
                            CVRPSolution nSol2 = (CVRPSolution)currentNode.sol.copy();
                            nSol2.endRoute();
                            nSol2.setVariable(i, data, loadConstraint);
                            nSol2.eval = evaluateSolution(nSol2, step);
                            //> ou < selon minimisation ou maximisation
                            if (nSol2.eval <= majValue)
                            {
                                nextSol.Add(new TreeNode(nSol2, null));
                            }
                            else
                            {
                                computedSteps++;
                            }
                        }
                    }
                }
                //Si il y a des enfants
                if (nextSol.Count != 0)
                {
                    nextSol.Sort((x, y) => x.sol.eval.CompareTo(y.sol.eval));                           //On les trie selon leur borne inférieure
                    //On parcours les enfants
                    for (int i = 0; i < nextSol.Count; i++)
                    {
                        //Si la solution est toujours viable
                        if (nextSol[i].sol.eval <= majValue)
                        {
                            nextSol[i] = solve(nextSol[i], step + 1);                                   //On poursuit la résolution
                        }
                        else
                        {
                            nextSol[i].isLocked = true;
                            computedSteps++;
                        }
                    }
                    currentNode.childs = nextSol;
                }
                else
                {
                    currentNode.isLocked = true;
                    updateBenchmark(step);
                }

                computedSteps++;
                int locked = 0;
                //On regarde si tout les enfants sont bloquéss
                foreach (TreeNode node in nextSol)
                {
                    if (node.isLocked)
                    {
                        node.Dispose();
                        locked++;
                    }
                }
                //Si ils le sont tous, on bloque la solution
                if (locked == nextSol.Count)
                {
                    currentNode.isLocked = true;
                    nextSol = null;
                }
                return(currentNode);
            }
        }