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

C# Discussion :

Problème List d'objets [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 29
    Par défaut Problème List d'objets
    Bonjour à tous,

    J'ai crée un objet dans mon projet C# :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    public class Individu
    	{
    		// Attributs
    		public List<int> selec;
    		public int Resultat;
    		public int Erreur;
    		public bool SignDelta;	
     
    		// Méthode RAZIndividu : Remet à zéro Individu
    		public void RAZIndividu()
    		{
    			List<int> RAZList = new List<int> {0,0,0,0,0};
    			int RAZRes = 0;
    			int RAZErr = 0;
    			bool RAZsign = false;
     
    			selec = RAZList;
    			Resultat = RAZRes;
    			Erreur = RAZErr;
    			SignDelta = RAZsign;
    		}
    	}
    J'ai également une classe Population contenant mes fonctions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class Population
    	{
                   public List<Individu> InitPop(List<Individu> Pop, int nbIndiv)
                   public void Calc(List<Individu> Pop,int solution)
                   etc..
             }
    Mon problème est lorsque je crée des List d'objet Individu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Population pop = new Population();
     
    // Déclaration population
    List<Individu> Popu = new List<Individu>();
    List<Individu> PopTemp = new List<Individu>();
    Par exemple j’initialise Popu : Popu = pop.InitPop(Popu, i);
    Mais le problème est lorsque que je touche a un Individu de PopTemp, ca modifie également l'Individu de Popu.

    Il y a un problème qui m'echappe dans la création de mes classes...

    Merci de votre aide et bonne journée

  2. #2
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Bonjour,

    Tu ne nous as pas donné le code de InitPop() mais à tous les coups, tu ne copies pas les objets avant des les insérer dans ta deuxième liste. Du coup, c'est le même objet qui est contenu dans les deux listes et à chaque fois que tu le modifie, il est modifié aux deux endroits.
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  3. #3
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 29
    Par défaut
    Bonjour et merci de votre réponse.

    Voici le code de InitPop ainsi que CroisementPop

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    public List<Individu> InitPop(List<Individu> Pop, int nbIndiv)
    		{
    			for(int i = 0; i<nbIndiv; i++)
    			{
                                    // Creation d'un nouvel individu et RAZ
    				Individu ind = new Individu();
    				ind.RAZIndividu();
    				// k est initialisé au nombre d'element de selec
     				int k = ind.selec.Count;
     
     
    				for (int j = 0 ; j < k; j++)
    				{
    					// Remplissage de selec
                                            ind.selec[j] = rnd.Next(0,16);
    					// Tps pour generation nouveau nb aleatoire
    					System.Threading.Thread.Sleep(30);
    				}
    				// Ajout de l'individu à la population
    				Pop.Add(ind);
    			}
    			// On retourne la population	
    			return Pop;
    		}
     
    public List<Individu> CroisementPop(List<Individu> pop, List<Individu> popTemp, int nbIndividu)
    		{
    			// Initialisation de variables
                            int i, j, k, nbItem, indiceBest, alea = 0;
     
    			nbItem = pop[0].selec.Count;
                            // Un tiers de la population
    			indiceBest = nbIndividu/3;
     
    			for(i = 0; i < indiceBest-1; i++)
    			    {
                                    // Création de deux nouveaux individus
    			    	Individu ind = new Individu();
    				Individu ind2 = new Individu();
    				ind.RAZIndividu();
    				ind2.RAZIndividu();
    				// Nombre aléatoire entre 0 et 5 donc [0..4]	
    				alea = rnd.Next(1,nbItem);	
    				//Recopie des valeur de selec des deux premiers individu de Popu	
    				ind.selec= pop[i].selec;
    				ind2.selec= pop[i+1].selec;
    				// Inversion des valeurs de selec des deux individus
                                    // Premiere boucle de alea à la fin
                                    // Deuxieme du debut à alea	
    			    	for(j = alea; j < nbItem; j++)
    			    	{
    			    		ind.selec[j] = pop[i+1].selec[j];
    			    	}
    			    	popTemp[i].selec= ind.selec;
     
    			    	for(k = 0; k < alea; k++)
    			    	{
    			    		ind2.selec[k] = pop[i].selec[k];
    			    	}
    			    	popTemp[i+1].selec= ind2.selec;
    				}
     
    			return popTemp;
    		}
    Alors quand je crée mes deux Pop et que je les initialise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Population pop = new Population();
    // Déclaration population
    List<Individu> Popu = new List<Individu>();
    List<Individu> PopTemp = new List<Individu>();
    // Initialisation population
    Popu = pop.InitPop(Popu,nbindividus);
    PopTemp = pop.InitPop(PopTemp,nbindividus/3);
    La jai bien deux population avec des individus distincts.

    Mais lorsque je fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PopTemp = pop.CroisementPop(Popu, PopTemp, nbindividus);
    Popu prend les valeurs de PopTemp.

    Merci de votre aide.

  4. #4
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Bon, je pense que la question suivante s'impose :
    Qu'est-ce que tu souhaites faire exactement?

    Des bribes de code et sans commentaires, ça a le don de ne pas m'intéresser.

  5. #5
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 29
    Par défaut
    Bonjour et dsl du manque d'info:

    Je crée deux listes d'Individus, Popu et PopTemp, chaque individu a les données suivantes :
    une liste "selec" de 5 int : ex (5,2,4,9,15).
    un int résultat : qui calcule la somme des entiers de selec.
    un int erreur : qui prend la valeure absolue de resultat - solution (defini par l'utilisateur).
    un bool : qui est vrai si resultat - solution est négatif, reste à faux sinon.

    La fonction InitPop prend en entrée une population (List<Individu>) et un int correspond au nombre d'individu souhaité (defini par l'utilisateur).
    Cette fonction rempli la liste "selec" par 5 int aléatoire.
    Et renvoi la liste d'individu.

    Je fais ca pour Popu et PopTemp, à la différence que les deux populations n'ont pas le même nombre d'individu...

    Ensuite la fonction CroisementPop, qui prend en entrée Popu, PopTemp et un entier correspond au nb d'individu de Popu (d'ailleurs ce n'est pas necessaire je peux directement l'avoir avec Popu.Count, bref...)
    Cette fonction doit renvoyer PopTemp en ayant fait le traitement suivant :
    on crée deux individu "temporaire" : Ind et Ind2
    Ind.selec recoit Popu[i].selec
    Ind2.selec recoit Popu[i+1].selec
    En gros c'est une recopie de la liste de int du premier et second individu de Popu.
    Ensuite un nb aleatoire est généré entre 0 et 5 -> (0..4)

    Exemple :
    Popu[0].selec = (1,2,3,4,5)
    Popu[1].selec = (6,7,8,9,10)

    si le nb aleatoire alea vaut 3 alors les deux listes d'int deviennent :

    ind.selec = (1,2,3,9,10)
    ind2.selec = (6,7,8,4,5)

    ( alea = 3 -> (1,2,3 | 9,10) ) En gros on coupe à 3eme element et on ajoute les elements de la deuxieme.

    Ensuite ind et ind2 sont ajoutés à PopTemp.
    Ainsi de suite.
    On retourne PopTemp.

    Sauf que dans mon cas PopTemp est bien retourné mais Popu est modifié avec les valeurs de PopTemp.

    Excusez moi j'ai un peu de mal a m'expliquer et si ce n'est pas très clair je repondrai à vos questions.

    Merci.

  6. #6
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Bonjour,

    Tu ne dois pas être très à l'aise avec la notion de référence.

    Un exemple vaut mieux qu'un long discours :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    //Je crée une instance de personne.
    Personne unePersonne = new Personne();
    //Je crée une liste de personnes (gens) qui va contenir ma personne
    List<Personne> gens = new List<Personne>();
    gens.Add(unePersonne);
    //Je crée une liste de personnes (autreGens) qui va contenir ma personne
    List<Personne> autreGens = new List<Personne>();
    autreGens.Add(unePersonne);
    Tout ça pour dire que c'est la même instance (référence) à unePersonne qui sera dans les deux listes. Donc si tu modifies la personne dans la liste gens, quand tu va regarder dans la liste autreGens tu verra que cette personne aura les modifications que tu as effectuées dans la première liste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    //Je crée deux instances de personne.
    Personne unePersonne = new Personne();
    Personne uneAutrePersonne = new Personne();
    //Je crée une liste de personnes (gens) qui va contenir ma personne
    List<Personne> gens = new List<Personne>();
    gens.Add(unePersonne);
    //Je crée une liste de personnes (autreGens) qui va contenir ma personne
    List<Personne> autreGens = new List<Personne>();
    autreGens.Add(uneAutrePersonne);
    Tu peux modifier une personne sans que ça ne modifie l'autre, puisqu'il y a 2 instances différentes et donc deux références.

    A mon avis dans tes listes PopTemp et popu, il doit y avoir les mêmes instances de ta classe individu.

    J'espère avoir été clair.

    Sinon envoie nous du code pour te pointer du doigt la faute

    Bon dév.

  7. #7
    olf
    olf est déconnecté
    Membre actif
    Profil pro
    Inscrit en
    Août 2004
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 26
    Par défaut
    Bonjour à tous,

    En l'absence de réponse, je me permets de compléter les analyses de MaximePalmisano et de sisqo60 qui de mon point de vue ont fait l'essentiel du travail.

    On constate en lisant le code qu'il s'agit bien d'un problème de copie de Référence (cf. méthode CroisementPop ligne 45 par exemple) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    //Recopie des valeur de selec des deux premiers individu de Popu	
    ind.selec= pop[i].selec;
    ind2.selec= pop[i+1].selec;

    Ces 2 lignes de code ne copient pas les valeurs de selec des deux premiers individu de Popu, elles indiquent que la liste selec de l'individu ind sera la liste selec du (ième +1) individu de la liste pop et que la liste selec de l'individu ind2 sera la liste selec du (ième +2) individu de la liste pop.

    Autrement dit, modifier la liste selec de l'individu ind revient à modifier la liste selec de l'individu pop[i] puisque ces 2 Individus "partagent" la même liste selec.

    Pour constituer les listes selec des nouveaux Individus, il faut donc récupérer leurs valeurs 1 à 1.

    J'ai essayé de recoder rapidement la méthode concernée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    public List<Individu> CroisementPop(List<Individu> pop, List<Individu> popTemp, int nbIndividu)
    {
     
     
    int alea, indiceBest, nbItem;
    Individu ind, ind2;//je préfère déclarer les individus ici plutôt que dans la boucle for
     
    Random rnd = new Random();
    alea = rnd.Next(1,pop[0].selec.Count);
     
    indiceBest = nbIndividu/3 -1 ;//je préfère décrémenter de 1 ici plutôt que dans la boucle for
    nbItem = pop[0].selec.Count;//je suppose que les listes selec sont toutes de la même longueur 
     
    //Récupération des premiers éléments de pop 2 par 2 
    for(int i = 0; i < indiceBest; i++)
    {
     	//création de 2 nouveaux individus 
    	ind = new Individu();
    	ind2 = new Individu();
    	ind.RAZIndividu();
    	ind2.RAZIndividu();
     
    	//pour les aleas premiers éléments : 
    	for(int j=0; j<alea;j++)
    	{
    		//le j-ième élément de la liste selec du 1ier nouveau Individu a pour valeur celle du j-ième élément de la liste selec du 1ier Individu récupéré.
    		ind.selec[j] = pop[i].selec[j];
    		//le j-ième élément de la liste selec du second nouveau Individu a pour valeur celle du j-ième élément de la liste selec du second Individu récupéré.
    		ind2.selec[j] = pop[i+1].selec[j];
     
    	}
     
    	//Pour les éléments suivants : 
     
    	for(int j=alea; j<nbItem;j++)
    	{
    		//le j-ième élément de la liste selec du 1ier nouveau Individu a pour valeur celle du j-ième élément de la liste selec du second Individu récupéré.
    		ind.selec[j] = pop[i+1].selec[j];
    		//le j-ième élément de la liste selec du second nouveau Individu a pour valeur celle du j-ième élément de la liste selec du 1ier Individu récupéré.
    		ind2.selec[j] = pop[i].selec[j];
     
    	}
    //On rajoute les individus créés à la liste popTemp
    	popTemp.Add(ind);
    	popTemp.Add(ind2);
     
     }
     
    return popTemp;
    }
    Alternativement, il est peut-être possible d'implémenter la même méthode avec des fonctions "copy" de la classe Array ou autre (?). Néanmoins, je ne suis pas certain que cela ait un intérêt pour des listes à 5 éléments (pour de très grandes listes, ça pourrait être différent).

    Cordialement,

    Florian.

  8. #8
    Membre averti
    Inscrit en
    Mai 2010
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 29
    Par défaut
    Bonjour à tous,

    Merci pour ta réponse Florian et tes conseils de codage, effectivement,
    On constate en lisant le code qu'il s'agit bien d'un problème de copie de Référence
    Je n'ai pas pu donner de nouvelles plus rapidement mais je suis arrivé à regler ce problème en utilisant "getrange" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //Recopie des valeur de selec des deux premiers individu de Popu	
    ind.selec= pop[i].selec.GetRange(0,Nbitem);
    ind2.selec= pop[i+1].selec.GetRange(0,Nbitem);
    Florian, ta méthode fonctionne également !

    Merci de votre aide en tout cas et bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème d'affectation dans des listes d'objets
    Par DotNET74 dans le forum Framework .NET
    Réponses: 3
    Dernier message: 04/06/2012, 22h50
  2. problème de récupération d'une liste d'objet au niveau des DAO
    Par yness dans le forum Persistance des données
    Réponses: 1
    Dernier message: 25/04/2011, 19h57
  3. problème list d'objets affichage
    Par faten7 dans le forum C++
    Réponses: 4
    Dernier message: 09/08/2008, 12h41
  4. Problème Iterateur sur liste d'objets
    Par kornterstrike dans le forum SL & STL
    Réponses: 1
    Dernier message: 23/11/2007, 19h33
  5. liste d'objets
    Par Pierrot dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2002, 09h56

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