IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Free Pascal Discussion :

Test multi conditions


Sujet :

Free Pascal

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2020
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2020
    Messages : 33
    Points : 15
    Points
    15
    Par défaut Test multi conditions
    Bonjour ;

    Je me heurte à une difficulté au niveau de l'exécution de mon application (FPC).
    Dans mon application je cherche a optimiser un résultat et pour ce faire je recherche les paramètres les plus appropriés pour un test (if then else ) comportant entre autre le membre(ou cas) ci-dessous

    or ( (NBDAYSPOS >= 32) AND ( (((CURRPTR^.C/PDL)-1)*100)> 6.85 ) AND ( (((CURRPTR^.C/PDL)-1)*100)< 11.12 ) and ((CURRPTR^.I - CURRPTR^.C) > 7) and ( (((CURRPTR^.C/CURRPTR^.M)-1)*100)> 1.88) and (DERIVATIVE2(CURRPTR,ROUND(21)) > -0.16) and (DERIVATIVE(CURRPTR,ROUND(7)) > -0.001) and (DERIVATIVE_2B(CURRPTR,ROUND(46)) > -0.03) and (DERIVATIVE_SM3(CURRPTR,ROUND(param1)) > param2)

    Pour ce faire je cherche à évaluer les résultats en faisant varier 2 paramètres (param1, param2) du cas présent de la fonction DERIVATIVE_SM3, à l'intérieur de 2 boucles imbriquées (le problème est le même quel que soit la fonction).

    Lorsque je lance l'exécution j'obtiens un seul résultat celui associe à la 1ere valeur de chaque boucle (par ex: je fais varier param1 de 1 à 71 et param2 de -0.1 a 0 ) j'obtiens un résultat pour les seuls valeurs 1 et -0.1. Or lorsque je modifie manuellement la valeur de param1 et param2 je trouve un meilleur résultat que celui associe a 1 et -0.1.

    DERIVATIVE2
    DERIVATIVE
    DERIVATIVE_2B
    DERIVATIVE2_SM3
    sont des fonctions renvoyant un réel.

    Je dois ajouter que mon test comporte 162 membres (ou cas) tel que

    or ( (NO_OF_STEP = 0) and (DERIVATIVE_S4S(CURRPTR,ROUND(15)) > 0.064) )
    -
    -
    -
    or ( (NO_OF_STEP = 10) and ( ( PRC_B2 - EMA_TEMA6) > 28.10 ) and ( ( PRC_B2 - EMA_TEMA6) < 110.05 ) and (NBNEGDAYS < 153) AND (DERIVATIVE_3S(CURRPTR,ROUND(13)) < -0.0029) AND (DERIVATIVE_2B(CURRPTR,ROUND(17)) < -0.057) )

    qui ne pose pas de problèmes a l'optimisation lorsque je cherche à réévaluer les paramètres des fonctions ainsi que la borne associe à chaque fonction.


    J'espère avoir été suffisamment clair,

    Merci pour votre aide

  2. #2
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Bonjour Jacco,
    AMHA, ton équation semble bien trop complexe pour être compréhensible et optimisable.

    Il me semble que la solution serait de passer, au moins provisoirement, par des variables intermédiaires booléennes.
    En créant un petit tableau de Bool, tu pourrais identifier les parties d'équation qui varient vraiment et ainsi, réduire la quantité de calcul par boucle.

    Une autre piste serait de regarder si ton équation n'est pas simplifiable (tableau de Karnaugh) ce qui améliorerait la compréhension comme la quantité de code.

    Cordialement,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2020
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2020
    Messages : 33
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par Galet Voir le message
    Bonjour Jacco,
    AMHA, ton équation semble bien trop complexe pour être compréhensible et optimisable.

    Il me semble que la solution serait de passer, au moins provisoirement, par des variables intermédiaires booléennes.
    En créant un petit tableau de Bool, tu pourrais identifier les parties d'équation qui varient vraiment et ainsi, réduire la quantité de calcul par boucle.

    Une autre piste serait de regarder si ton équation n'est pas simplifiable (tableau de Karnaugh) ce qui améliorerait la compréhension comme la quantité de code.

    Cordialement,
    Bonjour,

    Tout d'abord merci Galet pour ta réponse (et le temps consacré).
    Il est exact que certaines variables sont plus significatives que d'autres.
    Si je comprends bien ton conseil il faudrait que j'évalue chaque variable ex ante (avant le test) pour lui associer un bouléen et que je remplace chaque variable dans l'équation par son booléen.
    Ceci constituerait un alourdissement du code mais cela semble une piste intéressante.
    Par contre pour le tableau de Karnaugh , je n'ai jamais utilisé cette technique, il faut que je me renseigne.

    Bien cordialement,

  4. #4
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Optimiser
    Bojour,

    Si ça tourne "à la main" c'est que ce n'est pas le test qui est mauvais mais son exploitation (par exemple la bonne conservation du meilleur résultat et des paramètres associés).
    Par ailleurs, il faut sortir des 2 boucles tout ce qui ne dépend pas des variables de boucles et de mettre en boucle la plus intérieure celle qui a le moins de tests.
    Pour reprendre la proposition de Galet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if Test1 then // Test qui ne dépend ni de param1 ni de param2 (peut être n'existe t'il pas)
       for param1 := 1 to 71 do begin // peut être prévoir des passages plus fins ?
          if Test2 then  // Test qui ne dépend que de param1
             for iparam2 :=  0 to 100 do begin // ou 1000 ou 10000 ou une approche par fenêtrage itératif si la convergence est assez uniforme
                param2 := -0.1 + iparam2*0.01;  
                if Test3 then  // Test qui ne dépend que de param2
    En outre il est possible de simplifier et accélérer les expressions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    or ((NBDAYSPOS >= 32) 
        and (CURRPTR^.C > 1.0685*PDL) and (CURRPTR^.C < 1.1112*PDL)  // une multiplication est près de 3 fois plus rapide qu'une division
        and (CURRPTR^.I - CURRPTR^.C > 7)
        and (CURRPTR^.C > 1.0188*CURRPTR^.M) 
        and (DERIVATIVE2   (CURRPTR, ROUND(21)) > -0.16) 
        and (DERIVATIVE    (CURRPTR, ROUND( 7)) > -0.001) 
        and (DERIVATIVE_2B (CURRPTR, ROUND(46)) > -0.03)
        and (DERIVATIVE_SM3(CURRPTR, ROUND(param1)) > param2)
    Eviter de calculer plusieurs fois la même chose. Par exemple, comme c'est une optimisation, certaines valeurs représentent l'optimal de l'instant. Lorsqu'une meilleure valeur est trouvée, il peut être intéressant de créer des variables qui stockent des formules en dépendant. Par exemple, si CURRPTR^.M était un optimal local (simple hypothèse d'illustration), il pourrait être utile d'avoir une variable M1 := 1.0188*CURRPTR^.M pour diminuer le nombre des calculs lors des tests.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  5. #5
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Arrondir des arrondis...
    Bonjour,

    A quoi sert la fonction Round sur des entiers ? Faire des calculs inutiles ? Le compilateur transforme la valeur entière en valeur flottante pour être conforme à l'argument attendu par la fonction Round qui la retransforme en entier (peut être que le compilateur est assez malin pour s'en apercevoir mais je ne parierais pas là-dessus).

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  6. #6
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Bonjour,
    Merci Guesset d'avoir relayé...

    L'idée n'est pas tant de remplacer chaque morceau d'équation par un booléen (ce qui n'a pas de sens puisqu'on y perd en lisibilité en plus de la complexité de l'équation), mais d'essayer de simplifier l'équation en y ajoutant des calculs intermédiaires (si possible en dehors des boucles pour limiter les recalculs).
    Le but était, avec des calculs intermédiaires, de mieux faire ressortir les parties de ton équation qui varient et celles qui conditionnent vraiment ta recherche d'optimisation.

    Le tableau (ou table) de Karnaugh est une méthode qui permet de simplifier les équations logiques (Bon endroit pour aborder ce sujet dans la rubrique "Algo"), utilisée initialement pour les automatismes physiques (relais, séquenceur pneumatique) pour réduire le matériel. Il reste une bonne solution pour optimiser et réduire le volume de calcul...
    Belle journée,
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  7. #7
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 330
    Points : 4 151
    Points
    4 151
    Par défaut Optimisation
    Bonjour,

    Les optimisations logiques sont toujours possibles mais vu la variété des expressions partielles montrées jusqu'alors, je ne suis pas très optimiste . Il faudrait avoir un code plus complet pour pouvoir s'en assurer.

    Il y a un autre axe également à prendre en compte, avec les évaluations optimisées, c'est la probabilité des cas :
    • pour un or (||), il faut classer dans l'ordre des tests les plus probablement vrais au plus probablement faux
    • pour un and (&&), il faut classer dans l'ordre des tests les plus probablement faux au plus probablement vrai


    Par ailleurs quand se répètent des tests de type NO_OF_STEP = xxx, il semble qu'un éclatement par un switch (NO_OF_STEP) éviterait pas mal de tests : pour 10 valeurs le nombre moyen est 5 tests mais un branchement indexé par switch (case). A défaut, une imbrication dichotomique serait déjà plus efficace (pour 0 à 10):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if NO_OF_STEP < 5 then
       if NO_OF_STEP < 2 then
          if NO_OF_STEP < 1 then    ...   // 0
                            else    ...   // 1
       else
          if NO_OF_STEP < 4 then
             if NO_OF_STEP < 3 then ...   // 2
                               else ...   // 3
          else  ...                       // 4
    etc.
    Le nombre moyen de tests est d'environ 3.5, log2(11).

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

Discussions similaires

  1. Compilateur test des conditions dans un if
    Par BenoitM dans le forum Framework .NET
    Réponses: 4
    Dernier message: 03/10/2007, 10h07
  2. [Htaccess] - Tests et conditions
    Par Samyhijodelaluna dans le forum Apache
    Réponses: 11
    Dernier message: 17/07/2007, 15h34
  3. structure d un test de condition avec ?
    Par *alexandre* dans le forum Langage
    Réponses: 4
    Dernier message: 11/12/2006, 10h56
  4. Unordered list , test et condition d'arret
    Par NeHuS dans le forum ASP
    Réponses: 2
    Dernier message: 23/05/2006, 15h13
  5. Multi condition
    Par rvg dans le forum Access
    Réponses: 4
    Dernier message: 07/09/2005, 23h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo