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

SL & STL C++ Discussion :

Tirer un élément aléatoire parmi les plus grands éléments d'un std::vector


Sujet :

SL & STL C++

  1. #1
    Membre habitué

    Inscrit en
    Avril 2011
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 55
    Points : 147
    Points
    147
    Par défaut Tirer un élément aléatoire parmi les plus grands éléments d'un std::vector
    Bonjour je suis étudient et je travaille actuellement sur un alpha-beta dans un jeux ou il est fréquent que plusieurs coup aient la même valeurs.

    Mettons que mon algorithme me sorte le tableau de tuple (coup, valeur) suivant :

    [c1:23, c2:-9, c3:23, c4:12, c5:23]

    Je souhaite choisir un coup aléatoirement parmi c1, c3 et c5. Je voudrais donc savoir si la STL permet de faire ça simplement.

    Merci d'avance.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    je dirai oui, en utilisant un std::sort et un comparator bien pensé
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Si le problème est de tirer un indice pair/impair :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    std::vector<std::tuple<Coup,Valeur>> v;
     
    int indice_pair = std::rand() % (v.size() / 2) * 2;
    int indice_impair = std::rand() % ((v.size()-1) / 2) * 2 + 1;

  4. #4
    Membre habitué

    Inscrit en
    Avril 2011
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 55
    Points : 147
    Points
    147
    Par défaut
    Citation Envoyé par leternel Voir le message
    je dirai oui, en utilisant un std::sort et un comparator bien pensé
    Merci pour ta réponse, si je comprend bien, je modifie mon comparateur de tuple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool tupleCoup::greater(std::tuple<Coup, int> a, std::tuple<Coup, int> b)
    {
    	return std::get<1>(a) > std::get<1>(b);
    }
    de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool tupleCoup::greater(std::tuple<Coup, int> a, std::tuple<Coup, int> b)
    {
    	if (std::get<1>(a) > std::get<1>(b))
    		return true;
    	else if (std::get<1>(a) == std::get<1>(b))
    		return ((rand()%100) >= 50);
    	return false;
    }
    La liste est bien triée dans l'ordre décroissant mais les élléments egaux sont mélangés.

    Merci pour ton aide

  5. #5
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Il serait intéressant de faire des tests pour voir si la répartition est bonne. Il est probable que c1, c3 et c5 n'aient pas une chance sur trois d'être tiré chacun.

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je conseille la lecture de http://en.wikipedia.org/wiki/Fisher%...ing_algorithms

    Sinon, et si tu n'as pas des contraintes de perf trop drastiques, un simple tri, un comptage du nombre de valeurs identiques, puis un choix parmi ces valeurs me semble le plus simple.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Membre habitué

    Inscrit en
    Avril 2011
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 55
    Points : 147
    Points
    147
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Il serait intéressant de faire des tests pour voir si la répartition est bonne. Il est probable que c1, c3 et c5 n'aient pas une chance sur trois d'être tiré chacun.
    En effet, la répartition dépend du tri implémenté par std::sort, (cf. ici), mais bon on peut pas vraiment savoir quel tri est (sera) implémenté, du coup ça semble difficile de prédire si la répartition sera uniforme ou non (de toute façon les stateux dirons que ça suit une loi normale ). Mais à la rigueur c'est pas grave.

    Citation Envoyé par JolyLoic Voir le message
    Je conseille la lecture de http://en.wikipedia.org/wiki/Fisher%...ing_algorithms

    Sinon, et si tu n'as pas des contraintes de perf trop drastiques, un simple tri, un comptage du nombre de valeurs identiques, puis un choix parmi ces valeurs me semble le plus simple.
    Enfaite j'ai plus des contraintes de perf (l'algo s'exécute sur un temps limité) que sur répartition. Tout ce qui compte c'est que mon IA ne bouge pas tout le temps le même pion (dans ce jeu il est très risqué et du coup l'IA campe).

  8. #8
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par ahoff Voir le message
    En effet, la répartition dépend du tri implémenté par std::sort, (cf. ici), mais bon on peut pas vraiment savoir quel tri est (sera) implémenté, du coup ça semble difficile de prédire si la répartition sera uniforme ou non (de toute façon les stateux dirons que ça suit une loi normale ). Mais à la rigueur c'est pas grave.
    Que ce soit un Quicksort ou autre, ça sera un tri en O(n log(n)), je vois mal la STL implémenter un BubleSort ou autre en O(n²), bien que ça peut être plus rapide dans certains cas précis.
    (Enfin il est possible que le type de tri change en fonction de la taille du conteneur, mais c'est à prendre en compte ici)

    Du coup, comme propose JolyLoic, si tu fais un tri "normal" (O(n log(n)), suivi d'une recherche linéaire pour trouver le nombre de coups optimaux (O(n)), suivi d'un choix aléatoire parmi ces coups optimaux (O(1)), tu restes en O(n log(n)) mais avec une meilleure répartition.

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Voire même, si tu te moques de louper certains résultats, tu fais un partial_sort pour ne récupérer que les 15 premiers résultats (c'est du n log(m), avec m = 15, quelque soit n). Ensuite, parmi les valeurs égales dans ces 15 premiers résultats, tu sélectionne un au hasard.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 06/08/2008, 14h59
  2. Réponses: 13
    Dernier message: 07/01/2007, 19h43
  3. Tri aléatoire parmis les éléments d'une liste
    Par ahouba dans le forum Access
    Réponses: 2
    Dernier message: 29/06/2006, 18h03
  4. afficher les plus grand montants
    Par bertrand_declerck dans le forum Langage SQL
    Réponses: 12
    Dernier message: 19/08/2005, 14h31
  5. Réponses: 3
    Dernier message: 16/12/2002, 16h12

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