Algo ... presque bon ....

Résolu
Foxnono06 Messages postés 18 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 18 mai 2013 - 17 mai 2013 à 23:35
Foxnono06 Messages postés 18 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 18 mai 2013 - 18 mai 2013 à 13:55
Bonjour à la communauté et merci à ceux qui me liront ...

Alors voilà, je débute en c# et nést jamais fait d'algo auparavant, mais j'ai réussi à sortir quelque chose qui marche partiellement...
En quelques lignes :
J'ai nb_pan panneaux solaires a configurer avec des configs d'onduleur contenues dans le dataview.
Au début, il y a 0 pan config dc reste = nb_pan
Mes config du dataview contiennent une valeur de pan qui peuveut être configurés.
Mes config sont triés dans l'ordre de nb de panneaux qui peuvent y être connectés.
Par ex : j'ai 200 panneaux.
Le principe est de commencer par la config qui peut prendre le plus de panneaux :
Ex : Config1 = 30 pan
Config2 = 28 pan
Config3 = 14 pan
....
Dont au debut je calcule cb de config1 je peux utiliser(ds le code NbOnd) :
NbOnd 200 / 30 6 et il me reste 20 pan
ensuite je test ac la config suivante
Si le nb de pan de la config suivante est superieur au reste, je passe a la suivante.
J'arrive dc à
Nbond 20 / 14 1
et il reste 6
mais plus de config dispo
La suite de l'algo est au NbOnd du depart j'enlève 1
NbOnd --
puis je refais les même test.
jusqu´à ce que ce nb arrive a 0
puis je recommence en commençant par la config2 .... jusqu'à la dernière config.
Voilà j'éspère avoi été clair, merci d'avance.

Voici le code :
// Dataview contenant les configurations retenues, triees 
            DataView Config_tri = Config.DefaultView;
            Config_tri.Sort = "Pow, Nbtot";
            // Nb de panneaux à configurer
            int Reste = Nb_pan;
            int Min = 0;
            bool ok true, ok2 true, test = false;
            // Calcul le nb de panneau contenu dans la config mini
            Min = Convert.ToInt32(Config.Compute("MIN(Nbtot)", "Nbtot >= 0"));
            int Num 0, config 0, test2 = 0;
            for (int i = Config_tri.Count; i > 0; i--)
            {    
                do
                {
                    Reste = Nb_pan;
                    int verif = 0;
                    int nbpanconfig = 0;
                    do
                    {
                        i--;
                        int Nbtotale = Convert.ToInt32(Config_tri[i]["Nbtot"]);
                        if (Convert.ToInt32(Config_tri[i]["Nbtot"]) <= Reste && ((Reste - Convert.ToInt32(Config_tri[i]["Nbtot"]) == 0) || (Reste - Convert.ToInt32(Config_tri[i]["Nbtot"]) > Min)))
                        {
                            int NbOnd = Reste / Convert.ToInt32(Config_tri[i]["Nbtot"]);
                            Reste = Reste % Convert.ToInt32(Config_tri[i]["Nbtot"]);
                            if (test)
                            {
                                if (Reste < Min)
                                {
                                    NbOnd--;
                                    Reste = Reste + Convert.ToInt32(Config_tri[i]["Nbtot"]);
                                }
                                NbOnd = NbOnd - test2;
                                if (NbOnd == 0)
                                    ok2 = false;
                                Reste = Reste + test2 * Convert.ToInt32(Config_tri[i]["Nbtot"]);
                            }
                            if (Reste < Min && Reste != 0)
                            {
                                if (NbOnd != 0)
                                {
                                    do
                                    {
                                        NbOnd--;
                                        Reste = Reste + Convert.ToInt32(Config_tri[i]["Nbtot"]);
                                    }
                                    while (Reste < Min);
                                }
                            }
                            if (NbOnd != 0)
                            {
                                nbpanconfig += NbOnd * Nbtotale;
                                verif = nbpanconfig + Reste;
                                DataRow conf = Config_Auto.NewRow();
                                conf["Nbond"] = NbOnd;
                                conf["Nom"] = Config_tri[i]["Nom"];
                                conf["Nb"] = Num;
                                conf["Conf"] = Config_tri[i]["Conf"];
                                conf["Nbtot"] = Config_tri[i]["Nbtot"];
                                conf["Ratio"] = 100 * Convert.ToDouble(Panneau.Rows[0]["puissance"]) * Convert.ToDouble(Config_tri[i]["Nbtot"]) / (1000 * Convert.ToDouble(Config_tri[i]["Pow"]));
                                Config_Auto.Rows.Add(conf);
                            }
                            test = false;
                        }
                        if (Reste 0 || i 0)
                            ok = false;
                    }
                    while (ok);
                    Num++;
                    test2++;
                    ok = true;
                    i = Config_tri.Count - config;
                    test = true;
                }
                while (ok2);
                ok2 = true;
                i = Config_tri.Count - config;
                config++;
                test2 = 0;
                test = false;
            }
            for (int i = 0; i < Config_Auto.Rows.Count; i++)
            {
                int Tot_pan = 0;
                foreach (DataRow row in Config_Auto.Rows)
                {
                    if (row["Nb"] == Config_Auto.Rows[i]["Nb"])
                        Tot_pan += (Convert.ToInt32(row["Nbtot"]) * Convert.ToInt32(row["Nbond"]));
                }
                if(Tot_pan == Nb_pan)
                    lb_res_test.Add(Config_Auto.Rows[i]["Nb"].ToString() + " : " + Config_Auto.Rows[i]["Nbond"].ToString() + " onduleur(s) " + Config_Auto.Rows[i]["Nom"].ToString() + "de " + Config_Auto.Rows[i]["Conf"].ToString() + ", Ratio : " + Convert.ToDouble(Config_Auto.Rows[i]["Ratio"]).ToString(".#"));
            }

4 réponses

Foxnono06 Messages postés 18 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 18 mai 2013
18 mai 2013 à 11:43
Voilà, j'ai essayé de clarifier le code, j'éspère cette fois avoir été assez clair ;)
Je me rend bien comptedu travail que cela représente à me lire, je remerci d'avance tous ceux qui le feront.
J'ai essayé de trouver mes erreurs, mais le résultat est que je ne trouve pastoutes les configs. Si quelqu'un peut m'aider à trouver pourquoi ...

Merci !

// Dataview contenant les configurations retenues, triees 
            DataView Config_tri = Config.DefaultView;
            Config_tri.Sort = "Pow, Nbtot";
            // Nb de panneaux à configurer
            int Reste = Nb_pan;
            int Min = 0;
            bool ok true, ok2 true, Decrementation_Nbond = false;
            // Calcul le nb de panneau Mini contenu dans toutes les config
            // Cela permet de vérifier avec le reste car si le reste est inférieur
            // aucune config ne pourra être utilisée
            Min = Convert.ToInt32(Config.Compute("MIN(Nbtot)", "Nbtot >= 0"));
            int Num 0, config 0, Nb_de_decrementation = 0;
            // Boucle permettant de parccourir toutes les config dans l'ordre décroissant
            for (int i = Config_tri.Count; i > 0; i--)
            {    
                // Ce do while permet de tester en commencant par la plus grosse config en cours, définit par "i"
                // jusqu'à ce que le Nbond de la boucle if(test) arrive à 0
                do
                {
                    // On commence une nouvelle combinaison de config ac Nb_pan donc reste = Nb_pan
                    Reste = Nb_pan;
                    // Ce do while permet de parcourir toutes les configs depuis la plus grosse config en cours, 
                    // définit par "i" et de tester d'intégrer toutes les config suivantes, jusqu'à ce que
                    // reste 0. Les conditions de sortie sont reste 0 ou "i" == 0 car plus de config dispo
                    do
                    {
                        // Décrémentation de i car je commence à parcourir mon Dataview à Config_tri.Cout ce qui 
                        // me donnerait une erreur, car il ya Config_tri - 1 lignes ds le DataView.
                        // Celame permet également de tester ac toutes les configs dans lórdre de mon dataView
                        i--;
                        // Ce test sert à optimiser la boucle, Il vérifie que le nb de pan contenu par la config
                        // est inférieur ou égale au reste car sinon l'utilisation dela config donnerait un 
                        // reste négatif. De plus elle vérifie également que l'utilisation de la config si le reste
                        // n'est pas égal à 0, donne un reste supérieur au Min car sinon même pb, aucune config
                        // ne couvrera le nb de pan
                        if (Convert.ToInt32(Config_tri[i]["Nbtot"]) <= Reste && ((Reste - Convert.ToInt32(Config_tri[i]["Nbtot"]) == 0) || (Reste - Convert.ToInt32(Config_tri[i]["Nbtot"]) > Min)))
                        {
                            //Donc si une config passe la boucle de test, je calcule cb de config je peux utiliser
                            // ac la variable NbOnd et le reste de panneaux non configurés ac Reste
                            int NbOnd = Reste / Convert.ToInt32(Config_tri[i]["Nbtot"]);
                            Reste = Reste % Convert.ToInt32(Config_tri[i]["Nbtot"]);
                            // Ce test permet de savoir si je suis sorti de la boucle do_while qui signifie que je dois faire le test avec
                            // avec le Nbond de la plus grosse config en cours décrémenter de 1 
                            if (Decrementation_Nbond)
                            {
                                // ici je vérifie d'abord que le Reste est < Min car sinon dans la boucle précédente
                                // ou Nbond n'a pas été décrémenté, le if (Reste < Min && Reste != 0) qui suit aura
                                // déja décrémentë le Nbond donc j'obtiendrai le même résultat qu'auparavant
                                if (Reste < Min)
                                {
                                    NbOnd--;
                                    Reste = Reste + Convert.ToInt32(Config_tri[i]["Nbtot"]);
                                }
                                // Ici je décrémente NbOnd du nb de fois que je suis sorti de ma boucle do
                                NbOnd = NbOnd - Nb_de_decrementation;
                                // Le reste est donc incrémenter du nb de pan qui correspond aux configs retirées
                                Reste = Reste + Nb_de_decrementation * Convert.ToInt32(Config_tri[i]["Nbtot"]);
                                // Si j'arrive à 0,, j'ai testé toutes les valeurs de Nbond possible pour cette 
                                //Config, je dois donc sortir de mon do et décrémenter la ligne lue du 
                                //Dataview ce qui me renvoit au for du début
                                if (NbOnd == 0)
                                    ok2 = false;
                            }
                            // Ce test permet de vérifier que le Reste est supérieur au Min car sinon aucue des 
                            // config suivante ne sera utilisable. Si ce n'est pas le cas, je décrémente NbOnd et
                            // rajoute au Reste le NbOnd de Panel correspondant
                            if (Reste < Min && Reste != 0)
                            {
                                if (NbOnd != 0)
                                {
                                    do
                                    {
                                        NbOnd--;
                                        Reste = Reste + Convert.ToInt32(Config_tri[i]["Nbtot"]);
                                    }
                                    while (Reste < Min);
                                }
                            }
                            // Enfin ici, si j'ai un NbOnd > 0, j'ajoute ma config à config_auto
                            // Une config auto est composée de toutes les configs non nulles (Nbond>0)
                            // de la même boucle do while gérer par ok
                            // Je change de config auto en incrémentant "Num"
                            if (NbOnd != 0)
                            {
                                DataRow conf = Config_Auto.NewRow();
                                conf["Nbond"] = NbOnd;
                                conf["Nom"] = Config_tri[i]["Nom"];
                                conf["Nb"] = Num;
                                conf["Conf"] = Config_tri[i]["Conf"];
                                conf["Nbtot"] = Config_tri[i]["Nbtot"];
                                conf["Ratio"] = 100 * Convert.ToDouble(Panneau.Rows[0]["puissance"]) * Convert.ToDouble(Config_tri[i]["Nbtot"]) / (1000 * Convert.ToDouble(Config_tri[i]["Pow"]));
                                Config_Auto.Rows.Add(conf);
                            }
                            //J'ai déjà décrémenté Nbond dans cette boucle, dc ma condition devient fausse
                            Decrementation_Nbond = false;
                        }
                        // Condition de sorti du premier do : Reste = 0 ou ttes les configs parcourues
                        if (Reste 0 || i 0)
                            ok = false;
                    }
                    while (ok);
                    // J'incrémente le num de configs
                    Num++;
                    // J'incrémente le Nb de Nbond à retiré
                    Nb_de_decrementation++;
                    // La condition de mon do redevient vrai
                    ok = true;
                    //Je redonne le num de la ligne de départ du parcours des configs 
                    i = Config_tri.Count - config;
                    // Ma condition de décrémentation devient vrai
                    Decrementation_Nbond = true;
                }
                while (ok2);
                //Je recommence un test en commencant parla config suivante
                ok2 = true;
                // Decrementation de i pour commencer de la config suivante
                i = Config_tri.Count - config;
                // Valeur qui permet de décrémenter i
                config++;
                //Je repars  à 0 mon nb de décrémentation de NbOnd
                Nb_de_decrementation = 0;
                //Premier passage donc pas de décrémentation
                Decrementation_Nbond = false;
3
Foxnono06 Messages postés 18 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 18 mai 2013
18 mai 2013 à 13:55
Autant pour moi le pb ne venait pas de l'algo mais de mes conditions d'affichage !
3
Whismeril Messages postés 19029 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 26 avril 2024 656
18 mai 2013 à 09:03
Bonjour
Voilà j'éspère avoi été clair, merci d'avance.

en fait pas trop, d'abord tu écris parfois en sms, c'est moi lisible et ton texte est quand même dense.

Ensuite tu ne dis pas clairement le résultat attendu. Est-ce montrer toutes les combinaisons possible à l'utilisateur ou trouver celles qui emploiera le maximum de panneaux?

Enfin ton code n'est pas commenté, donc il faut trop se creuser la tête pour un samedi matin pour arriver à te suivre.

Whismeril
0
Foxnono06 Messages postés 18 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 18 mai 2013
18 mai 2013 à 10:53
je vais arranger le code... c'est vrai qu'il est moche ....Sinon Le but est de trouver tous les arrangements de combinaisons qui forment un Nb. de panneaux identique à celui donné qui est nb_pan.
dc par exemple, si j'ai nb_pan = 200 et 3 config dispo, telles que :
Config1 = 30 pan, Config2= 20 pan et Config3 = 5 pan

je commence par la config qui contient le max de pan : Config1
Donc nb_config1 200 / 30 6
Reste 200 % 30 20
Ensuite nb_config2 20 / 20 1
Reste = 0
Une bonne config que je garde à afficher !!

Mais je ne veux pas une seul config, je veux toutes les configs ...
Donc la procédure á suivre ensuite est : enlever un au nb_config de la 1ère config, ici config1 et refaire le même test.

donc nb_config1 6 - 1 5
Reste 20 + 30 50(Puisque j'enlève une config de 30 pan)
puis nb_config2 50 / 20 2
Reste = 10
et nb_config3 10 / 5 2
Reste =0

Dc encore une bonne config !!
Dc j'ai dit que l'on répète cette étape jusqu'à ce que nb_config1 = 0

Ensuite quand nb_config1 = 0, dans le code il y à une boucle for, tu remarqueras que le do while qui fonctionne avec ok2, se quitte lorsque le nb_config arrive 'à 0.

le for se décrémente donc, ce qui nous fait commencer dans le dataview contenant les configs, à une ligne en moins, donc ici par ex config1 ne sera pas utilisé.

Et cela car nous avons déjà têster toutes les configs possibles avec celle-ci.

Bonne lecture à ceux qui me lieront, siquelqu'un pense pouvoir 'aider je reposterai le code commenté.


Salut ;)
0
Rejoignez-nous