C++, comment formuler cette fonction?
Répondre à la discussion
Affichage des résultats 1 à 13 sur 13

C++, comment formuler cette fonction?



  1. #1
    Jeanthon

    C++, comment formuler cette fonction?


    ------

    Bonjour,

    Langage C++

    Dans une classe, je souhaite créer une méthode contenant une fonction de la sorte :



    Je possède un tableau dans lequel sont stockés toutes les variables i,j,k,..... Ce tableaux évolue au fil du programme.
    w est une fonction dépendante de i et de si.
    Les si sont des variables binaires, +1 ou -1.

    Donc je pense pour commencer à mettre le tableaux comme argument de la fonction. Pour une liste de variable donnée je suis capable d'écrire le code avec une succession de "for", mais pour une liste quelconque je ne voit pas.

    Je ne vois pas comment écrire la succession de somme de manière automatique...

    Merci pour votre aide.

    -----

  2. #2
    doul11

    Re : C++, comment formuler cette fonction?

    Bonjour,

    J'ai fait un bout de code, surement maladroit, mais l'idée est là : en fait c'est un compteur dont le nombre de chiffres et la valeur maximale de chaque chiffre n'est pas connu a l'avance.


    Code:
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    #include "math.h"
    
    
    int somme(char *list_max,int number)
    {
    int i,n;
    char *list_inc;
    
    list_inc=malloc(sizeof(char)*number);
    
    for(i=0;i<number;i++){list_inc[i]=0;}
    	
    for(i=0;i<number;i++){printf("list_max[%i]=%i\n",i,list_max[i]);}
    
    while(1)
    	{
    	while(list_inc[0]<list_max[0])
    		{
    		printf("list_inc : ");
    		for(i=0;i<number;i++)
    			{
    			printf("[%i]=%i ",i,list_inc[i]);
    			}
    		printf("\n");
    		
    		list_inc[0]++;
    		
    		}
    		
    	n=0;
    	while(list_inc[n]==list_max[n])
    		{
    		if(list_inc[n]==list_max[n])
    			{
    			list_inc[n]=0;
    			n++;
    			if( n == number){return(0);}
    			}
    		
    		list_inc[n]++;
    		} 
    	}
    }
    
    
    int main(void)
    {
    char var[3];
    
    var[0]=3;
    var[1]=3;
    var[2]=2;
    
    somme(var,3);
    
    return(0);
    }

    sortie :

    [localhost] /home/doul/c/futura > ./n_somme
    list_max[0]=3
    list_max[1]=3
    list_max[2]=2
    list_inc : [0]=0 [1]=0 [2]=0
    list_inc : [0]=1 [1]=0 [2]=0
    list_inc : [0]=2 [1]=0 [2]=0
    list_inc : [0]=0 [1]=1 [2]=0
    list_inc : [0]=1 [1]=1 [2]=0
    list_inc : [0]=2 [1]=1 [2]=0
    list_inc : [0]=0 [1]=2 [2]=0
    list_inc : [0]=1 [1]=2 [2]=0
    list_inc : [0]=2 [1]=2 [2]=0
    list_inc : [0]=0 [1]=0 [2]=1
    list_inc : [0]=1 [1]=0 [2]=1
    list_inc : [0]=2 [1]=0 [2]=1
    list_inc : [0]=0 [1]=1 [2]=1
    list_inc : [0]=1 [1]=1 [2]=1
    list_inc : [0]=2 [1]=1 [2]=1
    list_inc : [0]=0 [1]=2 [2]=1
    list_inc : [0]=1 [1]=2 [2]=1
    list_inc : [0]=2 [1]=2 [2]=1
    [localhost] /home/doul/c/futura >
    A adapter a ton problème, a ta disposition pour toute question.
    La logique est une méthode systématique d’arriver en confiance à la mauvaise conclusion.

  3. #3
    Jeanthon

    Re : C++, comment formuler cette fonction?

    Salut merci beaucoup!

    Malheureusement mon niveau n'est pas très avancé et je ne comprend vraiment pas l'idée! J'essaierai de creuser demain.

    Peut tu détailler ce que tu fais? Je ne vois pas à quoi correspond la sortie.
    Si tu m'explique avec des mots ce que tu fais, j'essaierai d'écrire mon code en m'appuyant sur le tien.

    Merci encore.

  4. #4
    Jeanthon

    Re : C++, comment formuler cette fonction?

    Pour être sur de parler de la même chose, voici le code que j'écris lorsque je connais à l'avance les variables et leurs nombre. Ici il y trois listes :
    i,j,k,l
    a,b,c,d
    ai,aj,bj,bk,ck,cl,dk,di

    Toutes les autres variables, cad celles commençant par 's' sont automatiquement générées en fonction des i,j,k,l ; ai,aj,bj,bk,ck,cl,dk,di


    for (int si=-1;si<=1;si+=2)
    {
    for (int sj=-1;sj<=1;sj+=2)
    {
    for (int sk=-1;sk<=1;sk+=2)
    {
    for (int sl=-1;sl<=1;sl+=2)
    {
    for (int sia=-1;sia<=1;sia+=2)
    {
    for (int sid=-1;sid<=1;sid+=2)
    {
    for (int sja=-1;sja<=1;sja+=2)
    {
    for (int sjb=-1;sjb<=1;sjb+=2)
    {
    for (int skb=-1;skb<=1;skb+=2)
    {
    for (int skc=-1;skc<=1;skc+=2)
    {
    for (int slc=-1;slc<=1;slc+=2)
    {
    for (int sld=-1;sld<=1;sld+=2)
    {
    correction+=wi(i,si)*wi(j,sj)* wi(k,sk)*wi(l,sl)*wa(a,sia,sja )*wa(b,sjb,skb)*wa(c,skc,slc)* wa(d,sld,sid)*delta(ai,si,sia) *delta(aj,sj,sja)*delta(bj,si, sjb)*delta(bk,sk,skb)*delta(ck ,sk,skc)*delta(cl,sl,slc)*delt a(dl,sl,sld)*delta(di,si,sid);
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }

  5. A voir en vidéo sur Futura
  6. #5
    doul11

    Re : C++, comment formuler cette fonction?

    Ok pour la sortie si je transforme un peut c'est plus clair ? les list_inc[n] sont les variables, n=0 pour la variable i, n=1 pour j, ...

    i=0 j=0 k=0
    i=1 j=0 k=0
    i=2 j=0 k=0
    i=0 j=1 k=0
    i=1 j=1 k=0
    i=2 j=1 k=0
    i=0 j=2 k=0
    i=1 j=2 k=0
    i=2 j=2 k=0
    i=0 j=0 k=1
    i=1 j=0 k=1
    i=2 j=0 k=1
    i=0 j=1 k=1
    i=1 j=1 k=1
    i=2 j=1 k=1
    i=0 j=2 k=1
    i=1 j=2 k=1
    i=2 j=2 k=1
    Sinon pour le principe du compteur : on démarre avec tout a zéro et on incrémente le premier chiffre, quand celui-ci arrive au maximum on le remet a zéro et on incrémente le second, si le second est au maximum on le met a zéro et on incrémente le troisième et ainsi de suite jusqu’à ce que tout les chiffres soit a leur maximum alors le comptage est fini, c'est exactement ce que fait mon code, le résultat est le même qu'avec des boucles for imbriqués, mais ça fonctionne avec un nombre quelconque de variables.

    Code:
    	while(list_inc[0]<list_max[0])
    		{
    		for(i=0;i<number;i++)
    			{
    			printf("%c=%i ",i+0x69,list_inc[i]);
    			}
    		printf("\n");
    		
    		list_inc[0]++;
    		
    		}
    cette partie incrémente le premier chiffre et affiche la progression des n variables


    Code:
    	n=0;
    	while(list_inc[n]==list_max[n])
    		{
    		if(list_inc[n]==list_max[n])
    			{
    			list_inc[n]=0;
    			n++;
    			if( n == number){return(0);}
    			}
    		
    		list_inc[n]++;
    		}
    cette partie du code gère le débordement (un chiffre est a sa valeur maximale) de façon récursive pour les n variables, ça met a zéro, ça incrémente le suivant, test de débordement et fin.

    En fait là ou j'ai return(0) il faut le remplacer par la valeur de ta somme calculé a chaque étape avec la variation de la valeur des indices.


    Voilà ce que je peut dire de plus pour le moment, en espérant que ça t'aide et que j'ai bien compris ce que tu voulais faire.
    La logique est une méthode systématique d’arriver en confiance à la mauvaise conclusion.

  7. #6
    doul11

    Re : C++, comment formuler cette fonction?

    Mince croisement de message ! Mais je pense que s'est bon :

    Citation Envoyé par doul11 Voir le message
    le résultat est le même qu'avec des boucles for imbriqués, mais ça fonctionne avec un nombre quelconque de variables.
    En fait avec ce que me dis ton problème est plus simple car les variables sont binaires, une simple addition et des manipulations de bits suffisent (0 -> -1 ; 1 -> +1), combien de variables tu peut avoir au maximum ?
    La logique est une méthode systématique d’arriver en confiance à la mauvaise conclusion.

  8. #7
    Zartan

    Re : C++, comment formuler cette fonction?

    Bonsoir, j'ai fait un peu d'analyse ascendante (cela revient à fabriquer des briques)

    Donc j'ai créé des classes pour pouvoir faire le calcul ici :

    correction+=wi(i,si)*wi(j,sj)* wi(k,sk)*wi(l,sl)*wa(a,sia,sja )*wa(b,sjb,skb)*wa(c,skc,slc)* wa(d,sld,sid)*delta(ai,si,sia) *delta(aj,sj,sja)*delta(bj,si, sjb)*delta(bk,sk,skb)*delta(ck ,sk,skc)*delta(cl,sl,slc)*delt a(dl,sl,sld)*delta(di,si,sid);

    Par contre je n'ai pas encore traité le problème des boucles (ce qui est le principe de l'analyse ascendante).

    Code:
    class CombiVar ;
    
    class Var
    {
    private:
    	string nom ;
    	int valeur ;
    
    public:
    	Var(string n)
    	{
    		nom = n ;
    		valeur = 0 ;
    	}
    	void setValeur(int v)
    	{
    		valeur = v ;
    	}
    	int getValeur()
    	{
    		return valeur ;
    	}
    	string getNom()
    	{
    		return nom ;
    	}
    
    };
    
    class PremiereVar : public Var
    {
    public:
    	PremiereVar(const string& n) : Var(n) 
    	{
    	}
    };
    
    class DeuxiemeVar : public Var
    {
    public:
    	CombiVar* combi1 ;
    	CombiVar* combi2 ;
    	DeuxiemeVar(string n) : Var(n) 
    	{
    		combi1 = 0;
    		combi2 = 0 ;
    	}
    	void setCombiVars(CombiVar* c1, CombiVar* c2) 
    	{
    		combi1 = c1 ;
    		combi2 = c2 ;
    	}
    
    };
    
    class CombiVar : public Var
    {
    public:
    	PremiereVar* premiere ;
    	DeuxiemeVar* deuxieme ;
    	CombiVar(PremiereVar* pv, DeuxiemeVar *dv) : Var(pv->getNom() + dv->getNom()) 
    	{
    		premiere = pv ;
    		deuxieme = dv ;
    	}
    };
    
    class SVar : public Var
    {
    public:
    	SVar(string n) : Var(n) 
    	{
    	}
    };
    
    class Compute
    {
    public:
    	static const int sizePremiere = 4 ;
    	static const int sizeDeuxieme = 4 ;
    	static const int sizeCombi = 8 ;
    private:
    	PremiereVar* tabPremiere[sizePremiere] ;
    	DeuxiemeVar* tabDeuxieme[sizeDeuxieme] ;
    	CombiVar* tabCombi[sizeCombi] ;
    	SVar* tabS[sizePremiere + sizeCombi] ; 
    
    	int correction;
    
    public:
    
    	Compute()
    	{
    	}
    
    	void init()
    	{
    
    		int n ;
    		
    		tabPremiere[0] = new PremiereVar("i") ;
    		tabPremiere[1] = new PremiereVar("j") ;
    		tabPremiere[2] = new PremiereVar("k") ;
    		tabPremiere[3] = new PremiereVar("l") ;
    
    		tabDeuxieme[0] = new DeuxiemeVar("a") ;
    		tabDeuxieme[1] = new DeuxiemeVar("b") ;
    		tabDeuxieme[2] = new DeuxiemeVar("c") ;
    		tabDeuxieme[3] = new DeuxiemeVar("d") ;
    
    		tabCombi[0] = new CombiVar(tabPremiere[0], tabDeuxieme[0]) ; // ai
    		tabCombi[1] = new CombiVar(tabPremiere[1], tabDeuxieme[0]) ; // aj
    		tabDeuxieme[0]->setCombiVars(tabCombi[0], tabCombi[1]) ;
    
    		tabCombi[2] = new CombiVar(tabPremiere[1], tabDeuxieme[1]) ; // bj
    		tabCombi[3] = new CombiVar(tabPremiere[2], tabDeuxieme[1]) ; // bk
    		tabDeuxieme[1]->setCombiVars(tabCombi[2], tabCombi[3]) ;
    
    		tabCombi[4] = new CombiVar(tabPremiere[2], tabDeuxieme[2]) ; // ck
    		tabCombi[5] = new CombiVar(tabPremiere[3], tabDeuxieme[2]) ; // cl
    		tabDeuxieme[2]->setCombiVars(tabCombi[4], tabCombi[5]) ;
    
    		tabCombi[6] = new CombiVar(tabPremiere[2], tabDeuxieme[3]) ; // dk
    		tabCombi[7] = new CombiVar(tabPremiere[0], tabDeuxieme[3]) ; // di
    		tabDeuxieme[3]->setCombiVars(tabCombi[6], tabCombi[7]) ;
    
    		for (n=0; n<sizePremiere; n++)
    		{
    			tabS[n] = new SVar("s" + tabPremiere[n]->getNom()) ;
    		}
    		for (n=sizePremiere; n<(sizePremiere + sizeCombi); n++)
    		{
    			tabS[n] = new SVar("s" + tabCombi[n]->getNom()) ;
    		}
    
    		correction = 0 ;
    	}
    
    	int evalueWI(int ind)
    	{
    		cout << "wi(" << tabPremiere[ind]->getNom() << ", " << tabS[ind]->getNom() << ")" << endl ;
    		return 1;
    	}
    	int evalueWA(int ind)
    	{
    		cout << "wa(" << tabDeuxieme[ind]->getNom() << ", " <<  tabDeuxieme[ind]->combi1->getNom() << ", " << tabDeuxieme[ind]->combi2->getNom() << ")" << endl ;
    		return 1;
    	}
    	int evalueDelta(int ind)
    	{
    		cout << "delta(" << tabCombi[ind]->getNom() << ", s" << tabCombi[ind]->premiere->getNom() << ", s" << tabCombi[ind]->getNom() << ")" << endl ;
    		return 1;
    	}
    };
    
    
    
    int main(array<System::String ^> ^args)
    {
    	char fin ;
    	int n ;
    
    	Compute compute ;
    
    	compute.init() ;
    
    	for (n = 0; n<Compute::sizePremiere; n++)
    	{
    		compute.evalueWI(n) ;
    	}
    	for (n = 0; n<Compute::sizeDeuxieme; n++)
    	{
    		compute.evalueWA(n) ;
    	}
    	for (n = 0; n<Compute::sizeCombi; n++)
    	{
    		compute.evalueDelta(n) ;
    	}
    	cin >> fin ;
        return 0;
    }
    Ce code me retourne les opérations nécessaires:
    Code:
    wi(i, si)
    wi(j, sj)
    wi(k, sk)
    wi(l, sl)
    wa(a, ia, ja)
    wa(b, jb, kb)
    wa(c, kc, lc)
    wa(d, kd, id)
    delta(ia, si, sia)
    delta(ja, sj, sja)
    delta(jb, sj, sjb)
    delta(kb, sk, skb)
    delta(kc, sk, skc)
    delta(lc, sl, slc)
    delta(kd, sk, skd)
    delta(id, si, sid)
    Dernière modification par Zartan ; 25/08/2012 à 22h49.

  9. #8
    Zartan

    Re : C++, comment formuler cette fonction?

    Citation Envoyé par doul11 Voir le message
    En fait avec ce que me dis ton problème est plus simple car les variables sont binaires, une simple addition et des manipulations de bits suffisent (0 -> -1 ; 1 -> +1), combien de variables tu peut avoir au maximum ?
    Bonjour, oui je pense qu'on peut enlever les boucles for imbriquées et les remplacer par une seule boucle si on remarque qu'elles correspondent à une incrémentation binaire.

    Au delà de 64 variables il faudrait coder ça sur plusieurs nombres mais c'est possible.

  10. #9
    doul11

    Re : C++, comment formuler cette fonction?

    Bonjour,

    Une autre question pour être sur de comprendre :

    Citation Envoyé par Jeanthon Voir le message
    Pour être sur de parler de la même chose, voici le code que j'écris lorsque je connais à l'avance les variables et leurs nombre. Ici il y trois listes :
    i,j,k,l
    a,b,c,d
    ai,aj,bj,bk,ck,cl,dk,di
    Les deux premières liste ont toujours de le même nombre de variables ?

    Dans la troisième il y doit y avoir une erreur de frappe c'est dl au lieu de dk

    Pour résoudre ce gendre de problème il ne faut plus penser en terme de variables indépendantes mais en index d'une liste de variables le longueur inconnue et répéter les actions pour n éléments des listes.


    Avec Zartan on devrais arriver a faire quelque chose
    La logique est une méthode systématique d’arriver en confiance à la mauvaise conclusion.

  11. #10
    Jeanthon

    Re : C++, comment formuler cette fonction?

    Merci infiniment à vous deux

    J'ai fini par comprendre l'idée. Le compteur est une très bonne idée, ça donne un code pas trop long. Zartan désolé je n'ai pas compris ton code, même si le résultat est bon. Ce doit être trop avancé pour moi.

    J'ai donc repris l'idée du compteur, et chaque fois qu'un nouvel état est généré, on calcul la partie de la fonction associée à cet état. Tellement simple une fois le truc trouvé!

    Après les temps de calcul deviennent évidemment démentiels des que le nombre de variable grandit trop....

    Code PHP:
    #include "math.h"
    #include "vector"
    #include "iostream"


    using namespace std;


    void computeFunction(vector<int> &variableList)
    {
        
    double result=0;
        
    double oneStateResult=1;

        
    int n=variableList.size();
        
    int n_max=n-1;

        
    vector<intstate(n,0); // Here I store my state, initialized at all 0
        
    int N=pow(2,n); // Total number of states

        
    int cursor=n_max-1;  // Trick I use to count all possible states. Maybe not the smartest one!!

        // print the first state and compute the part of the function related to this state
        
    for (int a=0;a<n;++a)
        {
            
    cout<<state[a]<<" ";
            
    //oneStateResult*=w(variableList[a],state[a]);
        
    }
        
    result+=oneStateResult;
        
    cout<<endl;

        
    // here I get all the possible states
        
    for (int q=1;q<=N/2;++q)
        {
            
    state[n_max]=1;

            
    // print the current state and compute the part of the function related to this state
            
    for (int a=0;a<n;++a)
            {
                
    cout<<state[a]<<" ";
                
    //oneStateResult*=w(variableList[a],state[a]);
            
    }
            
    result+=oneStateResult;
            
    cout<<endl;

            
    // Move the cross to the last 0
            
    for (int q=n_max;q>=0;--q)
            {
                if (
    state[q]==0)
                {
                    
    cursor=q; break;
                }
            }

            if (
    q==N/2) break;

            
    // Flip the cursor and set all variables wich are right to the cursor to 0;
            
    state[cursor]=1;
            for (
    int h=cursor+1;h<n;++hstate[h]=0;

            
    // print the current state and compute the part of the function related to this state
            
    for (int a=0;a<n;++a)
            {
                
    cout<<state[a]<<" ";
                
    //oneStateResult*=w(variableList[a],state[a]);
            
    }
            
    result+=oneStateResult;
            
    cout<<endl;
        }
    }


    int main ()
    {
        
    vector<intvariableList (4);
        
    computeFunction(variableList);

    Merci encore à tout les deux
    Dernière modification par Jeanthon ; 28/08/2012 à 04h35.

  12. #11
    Zartan

    Re : C++, comment formuler cette fonction?

    Citation Envoyé par Jeanthon Voir le message
    J'ai fini par comprendre l'idée. Le compteur est une très bonne idée, ça donne un code pas trop long. Zartan désolé je n'ai pas compris ton code, même si le résultat est bon. Ce doit être trop avancé pour moi.


    Bonjour, c'est moi qui n'ai pas compris la formule, alors j'ai reproduit l'exemple en séparant les wi(), les wa() et les delta(), d'où les 3 fonctions.

    Les classes de variables sont juste un artifice pour que je puisse afficher le nom de la variable et stocker sa valeur en même temps. C'est intéressant d'utiliser des classes pour pouvoir ajouter des membres quand on les met au point. Quitte à revenir aux int une fois que l'algorithme est trouvé.

    L'analyse ascendante permet de trouver la solution quand on ne comprend pas le problème

  13. #12
    Jeanthon

    Re : C++, comment formuler cette fonction?

    Citation Envoyé par doul11 Voir le message
    Bonjour,

    Les deux premières liste ont toujours de le même nombre de variables ?

    Dans la troisième il y doit y avoir une erreur de frappe c'est dl au lieu de dk
    Oui et oui

  14. #13
    Jeanthon

    Re : C++, comment formuler cette fonction?

    Citation Envoyé par Zartan Voir le message


    Les classes de variables sont juste un artifice pour que je puisse afficher le nom de la variable et stocker sa valeur en même temps. C'est intéressant d'utiliser des classes pour pouvoir ajouter des membres quand on les met au point. Quitte à revenir aux int une fois que l'algorithme est trouvé.
    A oui je vois, j'essaierai de m'en rappeler!

Discussions similaires

  1. Comment tracer cette fonction sur matlab ?
    Par babaz dans le forum Programmation et langages, Algorithmique
    Réponses: 1
    Dernier message: 15/03/2011, 13h09
  2. Formuler mes voeux
    Par inviteacb8757c dans le forum Orientation après le BAC
    Réponses: 8
    Dernier message: 21/01/2011, 16h18
  3. Comment formuler une demande d'injections de G-H à un endocrinologue ?
    Par invite1b00a1f5 dans le forum Santé et médecine générale
    Réponses: 60
    Dernier message: 21/09/2010, 17h42
  4. comment nommer cette fonction
    Par ABN84 dans le forum Mathématiques du supérieur
    Réponses: 10
    Dernier message: 13/12/2009, 20h00
  5. Comment dériver cette fonction ?
    Par inviteedb554ed dans le forum Mathématiques du collège et du lycée
    Réponses: 8
    Dernier message: 18/11/2008, 21h10