none
Microsoft Solver Foundation Alternative ou aide RRS feed

  • Question

  • Bonjour à tous,

    Je ne sais vraiment plus ou m'adresser, je ne trouve pas l'aide que j'ai besoin pour ce projet. Peut être mon anglais trop limité pour que les anglophones veuillent bien me répondre. Mon Français aussi d'ailleurs, je suis désolé.

    Le projet:

    J'ai besoin d'automatiser des fonctionnalités de mesures d'un spectromètre. Actuellement l'utilisateur a un gros fichier Excel avec une multitude de calcul, dont plusieurs Onglets avec des solvers.
    Je dois retranscrire cela dans un logiciel C#, sans utiliser le fichier Excel. Je ne peux pas malheureusement vous donner des exemples réel de mon projet, mais j'ai créé une alternative pouvant servir de base de test.

    Ce que j'ai fait:

    J'ai réussi 4 des 6 onglets concernés, ou je trouve soit des valeurs identique au solver Excel soit des valeurs légèrement inferieur (le but recherché).
    Le 5 éme Onglet, pourtant au principe identique des 4 autres, mais avec plus de calcul, me donne une valeurs plus élevé qu'Excel (à voir si je me suis pas planté quelques part, j'ai déjà vérifié, mais avec la quantité de formule j'ai put faire une erreur)
    Le 6 éme Onglet, lui est complètement diffèrent, avec beaucoup moins de formules impliquées par les variables inconnues, mais des "SI" que je n'ais pas dans les autres. Le projet compile, pas d'erreur, mais lorsque je demande la résolution du problème, il ne me redonne pas la main, le processus ne sort pas du solve et cela pendant longtemps (+ de 3 heures avant que je l'arrete).

    Objectif:

    Résoudre ces erreurs ou trouver une alternative, MSF étant abandonné.

    -->S'il vous plaie, j'ai vraiment besoin de votre aide. J'en dort plus la nuit depuis plusieurs semaines. Je bosse le Week-End dessus.

    Voila mon code exemple:

    J'ai essayé de respecter la démarche qui existe dans le fichier Excel afin de mieux trouver les erreurs et surtout s'adapter rapidement à un changement du fichier Excel, une modification, ce qui arrive assez souvent apparemment.
    Donc chaque cellules Excel est représenté par une ou 2 méthodes dans mon c#, les Fonctions classique de calculs sont présentent et me retourne un double ou string.
    Les même fonctions passées au solver me retourne des Term.
    Les fonctions mathématique, Math.Exp, Pow, Sqrt etc. sont remplacées part les fonctions Model.exp, Power, Sqrt etc lorsque les calcul utilise les variables inconnues. Ainsi que les fonctions IF, qui sont remplacé par Model.If. 

    Formalisme: Les méthodes classique sont avec une dénomination de type "double Cell_M1()", les méthodes solver avec "Term Solv_M1()". Variable inconnu Decision Solver_L18 et Decision Solver_Q18.

    le Code exemple simplifié:

    using Microsoft.SolverFoundation.Services;
    using System;
    
    
    namespace TestM6Solver
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Solver s = new Solver();
                s.StartSolver();
            }
        }
    
        public class Solver
        {
            Decision Solver_L18;
            Decision Solver_Q18;
    //variables en provenance d'autre cellules ici mise en dur.
            bool C15 = true;
            double D12 = 221.12;
            double D13 = 221.58;
            double E12 = 242.23;
            double E13 = 241.15;
            double Rth = 1.212;
            double DP = 0.92;
            double DZ = 18;
            double Var1_1 = 0.15;
            double Var1_2 = 2.73;
            double Var2_1 = 0.13;
            double Var2_2 = 1.236220193;
            double Meas1 = 5570;
            double Meas2 = 28539.50;
            double TrMeas1 = 0.07;
            double TrMeas2 = 0.03;
            double Lect1 = 0.9848;
            double Lect2 = 0.9864;
            double Min = 1;
    
            private Term Solv_R18()
            {
                Term res = Model.Sqrt(Model.Power(Solv_J18(), 2));
                return res;
            }
            private Term Solv_J18()
            {
                Term res = Solv_O18() / Solv_P18();
                return res;
            }
            private Term Solv_P18()
            {
                Term res = 0; ;
                if (C15)
                {
                    if (Meas1 < 2 * D12)
                    {
                        res = (2 * D12) / Model.If(Solv_M18() > TrMeas2, Solv_M18(), TrMeas2);
                    }
                    else
                    {
                        res = Meas1 / Model.If(Solv_M18() > TrMeas2, Solv_M18(), TrMeas2);
                    }
                }
                return res;
            }
            private Term Solv_M18()
            {
                Term res = 0;
                if (Cell_E18() == 0)
                {
                    res = Lect1;
                }
                else
                {
                    res = Lect1 * Model.Exp(-Solv_N13() * Solv_N12() * Solver_L18);
                }
                return res;
    
            }
            private Term Solv_N13()
            {
                Term res = Solver_Q18 * Var1_1 + (1 - Solver_Q18) * Var1_2;
                return res;
            }
    
            private Term Solv_O18()
            {
                Term res = 0;
                if (!C15)
                {
                    if (Meas2 < D13 * 2)
                    {
                        res = D13 * 2 / Model.If(Solv_N18() > TrMeas1, Solv_N18(), TrMeas1);
                    }
                    else
                    {
                        res = Meas2 / Model.If(Solv_N18() > TrMeas1, Solv_N18(), TrMeas1);
                    }
                }
                return res;
            }
    
            private Term Solv_N18()
            {
                Term res;
                if (Cell_E18() == 0)
                {
                    res= Lect2;
                }
                else 
                {
                    res = Lect2 * Model.Exp(-Solv_N14() * Solv_N12() * Solver_L18);
                }
                //    Lect2, Lect2 * Model.Exp(-Solv_N14() * Solv_N12() * Solver_L18));
                return res;
    
            }
            private Term Solv_N12()
            {
                Term res = 1 / (Solver_Q18 * 1 / DP + (1 * Solver_Q18) * 1 / DZ);
                return res;
            }
            private double Cell_E18()
            {
                double res = 0;
                if (Meas2 != 0)
                {
                    if (Meas1 != 0)
                    {
                        if (Meas2 > E13 && Meas1 > E12 && Meas2 / Meas1 > Min)
                        {
                            res = Meas2 / Meas1;
                        }
                    }
                }
                return res;
            }
            private double Cell_K18()
            {
                //=Rth*(1+H18)
                double H18 = Cell_H18();
                double res = Rth * (1 + H18);
                return res;
            }
            private double Cell_H18()
            {
                double F18Po = Math.Pow(Cell_F18(), 2);
                double Cnet208Pow = Math.Pow(Meas2, 2);
                double Cnet148pow = Math.Pow(Meas1, 2);
    
                Double res = Math.Sqrt(Math.Pow(Cell_F18(), 2) / Math.Pow(Meas2, 2) + Math.Pow(Cell_G18(), 2) / Math.Pow(Meas1, 2));
                return res;
            }
            private double Cell_G18()
            {
                double res = Math.Sqrt(Meas1);
                return res;
            }
            private double Cell_F18()
            {
                //=RACINE(Cnet208)
                double res = Math.Sqrt(Meas2);
                return res;
            }
    
            private Term Solv_N14()
            {
                //=Q18*µP208+(1-Q18)*µU208
                Term res = Solver_Q18 * Var2_1 + (1 - Solver_Q18) * Var2_2;
                return res;
            }
            private double Cell_I18()
            {
                //=Rth*(1-H18)
                double res = Rth * (1 - Cell_H18());
                return res;
            }
    
            public void StartSolver()
            {
                try
                {
                    var solverM6 = SolverContext.GetContext();
                    solverM6.ClearModel();
                    var modelM6 = solverM6.CreateModel();
    
    
                    //Instanciation des variables du Solver en format Real(double) Non Negative
                    Solver_L18 = new Decision(Domain.RealNonnegative, "L18");
                    Solver_Q18 = new Decision(Domain.RealNonnegative, "Q18");
    
                    modelM6.AddDecision(Solver_L18);
                    modelM6.AddDecision(Solver_Q18);
                    double K18 = Cell_K18();
                    double I18 = Cell_I18();
                    modelM6.AddConstraint("Contraint1", Solv_J18() <= K18);
                    modelM6.AddConstraint("Contraint2", Solv_J18() >= I18);
                    modelM6.AddConstraint("Contraint3", Solver_L18 <= 4);
                    modelM6.AddConstraint("Contraint4", Solver_L18 >= 0);
    
                    //Adding Solver Methods
                    modelM6.AddGoal("SolverM6", GoalKind.Minimize, Solv_R18());
    
                    // Solve our problem
    //c'est ici qu'il bloque et me rend pas la main.
                    var solution = solverM6.Solve();
    
                    // Get our decisions
                    double L18 = Solver_L18.ToDouble();
                    double Q18 = Solver_Q18.ToDouble();
                    Console.WriteLine("L18 = " + L18.ToString());
                    Console.WriteLine("Q18 = " + Q18.ToString());
    
                    string M6_QuatiteSolution = solution.Quality.ToString();
                    Console.WriteLine("Solution = " + M6_QuatiteSolution);
                    Console.ReadLine();
                }
                catch (Exception ex)
                {
    
                }
            }
        }
    }
    j'ai tenté aussi d'ajouter des bornes dans la déclaration des "Decision", surtout pour Q18 qui n'en avait pas dans les contraintes.

    Solver_L18 = new Decision(Domain.RealRange(0,4), "L18");
    Solver_Q18 = new Decision(Domain.RealRange(0,1), "Q18");
    Mais cela ne change pas, toujours bloqué dans le  "solverM6.Solve();"


    S'il vous plais, je suis vraiment dans la Me..., je sais que MSF n'est plus maintenu par Microsoft, mais pouvez vous me proposer une alternative s'il vous plaie.
    J'avais jamais entendu parlé de solver avant ce nouveau boulot, et la je sèche vraiment.

    Merci de votre aide.

    mercredi 20 juillet 2022 07:29

Toutes les réponses