Example #1
0
        /// <summary>
        /// Retourne une solution par ordre d'apparition dans le fichier
        /// </summary>
        /// <param name="parser">DataParser à utiliser</param>
        /// <param name="loadConstraint">Contrainte de chargement</param>
        /// <returns>Solution générée</returns>
        public static CVRPSolution OrderedSolution(DataParser parser, double loadConstraint)
        {
            CVRPSolution sol = _AddVars(parser);                //Génère une instance de la solution

            sol.addNewRoute(parser);                            //Créé une nouvelle route
            //On fixe les variables
            for (int i = 0; i < parser.nodeList.Count; i++)
            {
                sol.setVariable(i, parser, loadConstraint);
            }
            sol.endSolution();                                  //On termine la solution
            return(sol);
        }
Example #2
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);
        }
Example #3
0
        /// <summary>
        /// Retourne une solution par la méthode de Clarke and Wright
        /// </summary>
        /// <param name="parser">DataParser à utiliser</param>
        /// <param name="loadConstraint">Contrainte de chargement</param>
        /// <returns>Solution générée</returns>
        public static CVRPSolution ClarkeWrightSolution(DataParser parser, double loadConstraint)
        {
            CVRPSolution sol = _AddVars(parser);                //Génère une instance de la solution
            //On initialise la liste des savings
            List <KeyValuePair <Tuple <int, int>, double> > savings = new List <KeyValuePair <Tuple <int, int>, double> >();
            int j;

            //On génère les savings
            for (int i = 1; i < parser.nodeList.Count; i++)
            {
                for (j = 1; j < parser.nodeList.Count - 1; j++)
                {
                    int realJ = j;
                    //On évite l'arc i->i
                    if (j >= i)
                    {
                        realJ++;
                    }
                    savings.Add(new KeyValuePair <Tuple <int, int>, double>(new Tuple <int, int>(i, realJ), parser.arcWeight[0, realJ] + parser.arcWeight[i, 0] - parser.arcWeight[i, realJ]));
                }
            }
            //On trie la liste
            savings.Sort(
                delegate(KeyValuePair <Tuple <int, int>, double> pair1, KeyValuePair <Tuple <int, int>, double> pair2)
            {
                return(pair1.Value.CompareTo(pair2.Value));
            });
            savings.Reverse();                                          //On la renverse (ordre décroissant)
            List <List <int> > routes     = new List <List <int> >();   //Liste des routes de la solution
            List <double>      routeDist  = new List <double>();        //Liste des distances associés à chaques routes
            List <double>      routeCosts = new List <double>();        //Liste des coûts associés à chaques routes

            //On initialise les routes initiales
            for (int i = 1; i < parser.nodeList.Count; i++)
            {
                routes.Add(new List <int>(new int[] { i }));
                routeDist.Add(parser.arcWeight[0, i] + parser.arcWeight[i, 0]);
                routeCosts.Add(parser.nodeList[i].quantity);
            }
            j = 0;
            //Tant que la solution
            while (j < savings.Count - 1 && savings[j].Value >= 0)
            {
                Tuple <int, int> couple = savings[j].Key;                   //On récupère les noeuds associés au saving
                //On vérifie que les deux noeuds peuvent être fusionnés
                object[] res = _areMergeable(couple.Item1, couple.Item2, routes, routeDist, routeCosts, savings[j].Value, loadConstraint);
                //Si ils peuvent être fusionné
                if ((bool)res[0])
                {
                    routes[(int)res[1]]     = routes[(int)res[1]].Concat(routes[(int)res[2]]).ToList(); //On créé la nouvelle route
                    routeDist[(int)res[1]]  = (double)res[4];                                           //On met à jour la distance de la route
                    routeCosts[(int)res[1]] = (double)res[3];                                           //On met à jour le coût de la route
                    routes.RemoveAt((int)res[2]);                                                       //On suppprime l'ancienne route
                    routeDist.RemoveAt((int)res[2]);
                    routeCosts.RemoveAt((int)res[2]);                                                   //On supprime le coût associé
                }
                j++;
            }
            //On créé la solution
            foreach (List <int> r in routes)
            {
                sol.addNewRoute(parser);
                foreach (int node in r)
                {
                    sol.setVariable(node, parser, loadConstraint);
                }
                sol.endSolution();
            }
            return(sol);
        }