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

Lazarus Pascal Discussion :

Remplir un TListValueEditor avec des nombres aléatoires


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    6EME 5EME 4EME
    Inscrit en
    Septembre 2021
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : 6EME 5EME 4EME
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2021
    Messages : 19
    Par défaut Remplir un TListValueEditor avec des nombres aléatoires
    Bonjour

    Je souhaite remplir un TlistValueEditor de 36 nombres aléatoires distincts (de 1 à 36)

    Randomize afin d'avoir une liste de nombres toujours différents
    Ensuite 36 fois je défini un nombre provisoire je teste si il a été déja utilisé et en fonction du résultat je l'affecte ou je passe au suivant hélas y a un truc qui ne fonctionne pas je me retrouve avec des nombres en double ou en triple
    Je suis dispo pour toutes info complémentaire
    Merci
    Eric

    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
     
      Randomize;
      for lignes := 1 to 36 do begin
         affecte:=False;
         while not affecte do begin
            provisoire:=(RandomRange(1,36));
            for ii := 1 to 36 do begin
               if (liste_aleatoire.Cells[1,ii] = IntToStr(provisoire))
               then Break ;
            end;
            If Not affecte Then begin
               liste_aleatoire.Cells[1,lignes]:= IntToStr(provisoire);
               Break;
            end;
         end;
      end;

  2. #2
    Membre très actif

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2013
    Messages : 413
    Billets dans le blog
    2
    Par défaut
    Une possibilité:

    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
     
    LS := TStringList.Create;
    try
      LS.Sorted := true;
      LS.Duplicates := dupIgnore;
      LS.Clear;
      Nb := 36;
      while (LS.Count < Nb) do
      begin
        provisoire:=(RandomRange(1,36));
        LS.Add(format('%f', [provisoire]);
      end;
    finally
      FreeAndNil(LS)
    end;

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 975
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 975
    Par défaut
    Le principe est mauvais, while pourrait boucler des centaines voire des milliers de fois avant d'avoir les 36 nombres différents.

    Remplis une liste et ensuite seulement tu la réordonnes de façon aléatoire.

    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
    var
      Table :array[1..36] of integer;
      i, Nb, Src, Dst :integer;
     
    begin
      for i := Low(Table) to High(Table) do
        Table[i] := i;
     
      // On peut jouer sur le nombre de pas
      for i := 0 to 50 do
      begin
        Src := Random(High(Table)) +1;
        Dst := Random(High(Table)) +1;
        Nb  := Table[Dst];
     
        Table[Dst] := Table[Src];
        Table[Src] := Nb;
      end;
    end;

  4. #4
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Salut le plus simple serai l'algo de Fisher Yates qui se rapproche de l'algo de Andnotor

    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
    var
      Table :array[1..36] of integer;
      i, j, mini, maxi, tmp : integer;
     
    begin
      mini := Low(Table);
      maxi := High(Table);
     
      for i := mini to maxi do
        Table[i] := i;
     
      for i := maxi downto mini do
      begin
        j:= System.Random(Abs(mini-maxi)) + Math.Min(mini,maxi);
        tmp := Table[j];
        Table[j] := Table[i];
        Table[i] := tmp;
      end;
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Membre averti
    Homme Profil pro
    6EME 5EME 4EME
    Inscrit en
    Septembre 2021
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : 6EME 5EME 4EME
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2021
    Messages : 19
    Par défaut Merci à tous
    Ma question a suscité pas mal de réponses et je vous en remercie

    J'ai finalement opté pour la solution de BeanzMaster

    Pour info j'ai tenté de compter le nombre de passage dans la boucle while et vous avez raison plus de 7000 tentatives pour finalement faire des doublons et ça je ne le comprend pas.

    Bonne journée à vous et bonnes vacances à ceux qui y sont.

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 496
    Par défaut
    Salut

    La solution de Ben aussi peut générer des doublons.

    Quelques optimisations à prévoir pour éviter des instructions à chaque boucle :
    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
    var
      Table :array[1..36] of integer;
      i, j, mini, maxi, tmp : integer;
      lmin,lNbVal : Integer;
    begin
      mini := Low(Table);
      maxi := High(Table);
     
      for i := mini to maxi do
        Table[i] := i;
     
      lmin     :=  Math.Min(mini,maxi); // pas besoin de verifier le min a chaque boucle
      LNbVal := Abs(mini-maxi); // pas besoin le nbval est constant a chaque boucle
    for i := maxi downto mini do
      begin
        j := System.Random(LNbVal)+lmin ;// 
        tmp := Table[j];
        Table[j] := Table[i];
        Table[i] := tmp;
      end;

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 975
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 975
    Par défaut
    Citation Envoyé par eric436243 Voir le message
    ... finalement faire des doublons et ça je ne le comprend pas.
    Parce que affecte n'est jamais passé à TRUE, tu ajoutes systématiquement le nombre qu'il existe ou pas puisque if not affecte then est toujours vrai.

    Le break de la ligne 9 ne fait sortir que de la boucle ii, pas du while. C'est certainement ce qui t'a trompé

    Mais de toute façon ce while n'avait aucune utilité puisque tu ne passais qu'une fois dedans (si ça avait été fait juste) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for lignes := 1 to 36 do
    begin
      provisoire := (RandomRange(1, 37));
     
      for ii := 1 to 36 do
      begin
        affecte := liste_aleatoire.Cells[1, ii] = IntToStr(provisoire);
        if affected then Break;
      end;
     
      if not affecte then
        liste_aleatoire.Cells[1, lignes] := IntToStr(provisoire);
    end;
    A noter qu'il devait aussi toujours te manquer le nombre 36, RandomRange (à l'instar de Random) n'incluant pas la limite supérieure (d'où le +1 dans mon exemple).

    Citation Envoyé par anapurna Voir le message
    La solution de Ben aussi peut générer des doublons.
    Non elle ne peut pas.

Discussions similaires

  1. Réponses: 4
    Dernier message: 12/11/2009, 10h58
  2. remplir un tableau par des nombre aléatoires
    Par logo98 dans le forum Débuter
    Réponses: 7
    Dernier message: 07/03/2009, 00h22
  3. remplir une table avec des données aléatoire
    Par jamal_id dans le forum SQL
    Réponses: 3
    Dernier message: 17/10/2007, 11h11
  4. Réponses: 12
    Dernier message: 25/05/2007, 17h28

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