[C#] HashTable et Random

Bonjour,

j’ouvre ce thread parce que j’ai l’impression de réaliser une horreur et que je voudrai la confirmation qu’il n’y a vraiment pas moyen de faire autrement (et que je suis pas passé à coté d’un truc gros comme un maison)

Voila le problème : J’ai une HashTable et je doit prendre aléatoirement un certain nombre d’éléments dedans, à priori je ne sait pas exactement le nombre car ca dépent des objets en eux-même mais je peux facilement l’approximer.

Evidement naïf comme je suis, j’ai codé tout connement :

int size = MaHashTable.Count; Random R; while([...]) Elem E = MaHashTable[R.Next(size)];

Quelques minutes, foirages et segfaults plus tard, je me suis finallement rappelé que l’operateur [] de la HashTable sert à mettre une clé, pas un numéro d’élément :P.

Et comme vous devez-vous en doutez, j’ai aucune idée de ce que sont ces clées (sinon je viendrai pas vous faire chier) même si à priori ce sont des string.

J’ai pensé par après à utiliser la propriété Values, le seul problème que c’est une liste (enfin une Icollection), donc pas d’opérateur[], une complexité en O(n) pour les accès aléatoires à un élément et je doit itérer à la main (et comme je doit tirer un nombre inconnu d’éléments…).

En ce moment dans ma fonction, j’ai utilisé HashTable.Values.CopyTo() pour pallier au problème … je mentais pas quand je disait que j’ai fait une horreur. (oui j’ai honte :stuck_out_tongue: )

Pour vous donnez un orde de grandeur la hashlist contient typiquement quelques millier s d’éléments et j’en ai besoin d’une dizaine.

Une autre idée que j’ai eu c’est d’approximer c’est d’approximer vers le haut le nombre d’éléments à prendre, de tirer les numéros avant, de les trier de tous les récupérer en une itération. Ou alors de maintenir le vecteur obtenu avec CopyTo dans un cache.

Vous en pensez quoi?
Vous connaissez un autre moyen de réaliser cela?
Vous connaissez un hack pas trop dégeux?

Je suis preneur de tout conseil, merci d’avance.

Mmh, la question a se poser est déja: ai-je vraiment besoin d’une Hashlist ? Sinon, faudrait savoir comment elle est remplie ? si elle change souvent, si elle est accédée souvent, si le “tirage” est fréquent ? Si tu effectue plusieurs tirages avant de remodifier la hashtable …

[quote name=‘Tzim’ date=’ 27 Apr 2005, 13:49’]Mmh, la question a se poser est déja: ai-je vraiment besoin d’une Hashlist ? Sinon, faudrait savoir comment elle est remplie ? si elle change souvent, si elle est accédée souvent, si le “tirage” est fréquent ? Si tu effectue plusieurs tirages avant de remodifier la hashtable …
[right][post=“354051”]<{POST_SNAPBACK}>[/post][/right][/quote]
C’est pas moi qui construit la HashTable (c’etait pas HashList, désolé), on me la fourni, enfin c’est une application que je modifie mais c’est pas moi qui l’ai écrite.

En fait c’est une base de donnée (playlist) de musique et je voudrai tirer des morceaux au hasard.

[quote name=‘Staz’ date=’ 27 Apr 2005, 14:25’]c’est une DB (playlist) de musique et je voudrai tirer des morceaux au hasard.
[right][post=“354074”]<{POST_SNAPBACK}>[/post][/right][/quote]

Tu peux pas tirer un nombre au hasard et accèder à l’enregistrement par son id ?

[quote name=‘alt3’ date=’ 27 Apr 2005, 15:35’]Tu peux pas tirer un nombre au hasard et accèder à l’enregistrement par son id ?
[right][post=“354118”]<{POST_SNAPBACK}>[/post][/right][/quote]
c’est pas une vrai DB relationnelle style Mysql hein, c’est une pseudo base qui est stoqué dans une hashtable.

Dans ton hashtable, tu as la propriete Keys, laquelle to peux acceder via index.
while([…]) Elem E = MaHashList[MaHashList.Keys[R.Next(MaHashList.Keys.Count)]];

Note que ce genre d’algo ne te donneras pas forcement un shuffle coerent, et avec des répétitions possibles.

Pour créer un Random coeherent, j’utiliserais plutot la technique suivante :
Associe un numero aleatoire a chacun de tes entrées, et tries les sur ce nombre aléatoire. De cette manière, tu es sur d’avoir un “vrai” random, non répétitif, chaque titre n’étant joué qu’une fois.

[quote name=‘KiniK’ date=’ 27 Apr 2005, 20:09’]Dans ton hashtable, tu as la propriete Keys, laquelle to peux acceder via index.
while([…]) Elem E = MaHashList[MaHashList.Keys[R.Next(MaHashList.Keys.Count)]];
[right][post=“354194”]<{POST_SNAPBACK}>[/post][/right][/quote]
Heu je ne sais pas où tu as vu que Keys avait un index, c’est une ICollection (comme Values) et cette interface ne défini pas d’index.

Tzim > C’est vrai que ca éviterait les répetitions mais je trouve un peu étrange de trier tout les éléments pour en jouer juste quelques uns. (et à la limite si je ne veux pas rejouer les même morceaux je pense pouvoir implémenter ça par un autre methode)

[quote name=‹ Staz › date=’ 28 Apr 2005, 03:57’]Heu je ne sais pas où tu as vu que Keys avait un index, c’est une ICollection (comme Values) et cette interface ne défini pas d’index.
[right][post=« 354381 »]<{POST_SNAPBACK}>[/post][/right][/quote]
Ooops…
Bon, heu, elle doit avoir la methode CopyTo sans doute :stuck_out_tongue:
Si tu peux te permettre de perdre quelques cycles a copier ca dans un array, ca va resoudre ton probleme.

Si ca marche toujours pas, je ferai l effort de voir ca sous vs.net et trouver kkch qui marche :stuck_out_tongue:

[quote name=‘Staz’ date=’ 28 Apr 2005, 03:57’]Tzim > C’est vrai que ca éviterait les répetitions mais je trouve un peu étrange de trier tout les éléments pour en jouer juste quelques un. (et a la limite si je ne veux pas rejouer les meme morceaux je pense pouvoir implémenter ça par un autre morceaux)
[right][post=“354381”]<{POST_SNAPBACK}>[/post][/right][/quote]
Non, a priori Tzim a raison, c’est bien comme ca qu’il faut faire, ou tout au moins un int qui te dit combien de fois un morceau a ete joue pour ne pas rejouer deux fois le meme morceau dans la meme “passe”. Cela dit je comprend pas tres bien ce que tout ce bordel fait dans une hashtable si tu veux pas faire des acces par clef. C’est quoi la clef de ta hashtable? (Et c’est quoi une HashList? Dans le framework il y a pas de HashList, le truc le plus proche est surement http://msdn.microsoft.com/library/default…yclasstopic.asp ).

[quote name=‘Tzim’ date=’ 27 Apr 2005, 21:13’]Note que ce genre d’algo ne te donneras pas forcement un shuffle coerent, et  avec des répétitions possibles.

Pour créer un Random coeherent, j’utiliserais plutot la technique suivante :
Associe un numero aleatoire a chacune de tes entrées, et tries-les sur ce nombre aléatoire. De cette manière, tu es sur d’avoir un “vrai” random, non répétitif, chaque titre n’étant joué qu’une fois.
[right][post=“354213”]<{POST_SNAPBACK}>[/post][/right][/quote]
Bah, autre solution, tu associes un numéro à chaque chanson, au début, tu tires un numéro au hasard, puis pour choisir la suivante, tu ajoutes un nombre premier (genre 17, tu évites que le nombre de chansons soit un multiple de ce nombre) pour la suivante tu rajoutes encore 17, et ainsi de suite (et tu boucles quand ca dépasse.). A la fin, tu peux enregistrer la position d’un user et son nombre premier associé pour pouvoir reprendre sa lecture. Si tout se passe bien, il n’y aura aucun doublon.

M’enfin bref. Me demandez pas de justifier ça, j’ai la flemme (et ca à pas grand chose à voir avec les hashtables)

Désolé c’est une HashTable, je ne sais pas pourquoi j’écris toujours HashList, ça doit être le petite dyslexique au fond de moi qui manifeste sa présence :stuck_out_tongue:

[quote name=‹ GloP › date=’ 28 Apr 2005, 19:55’]Non, a priori Tzim a raison, c’est bien comme ca qu’il faut faire, ou tout au moins un int qui te dit combien de fois un morceau a ete joue pour ne pas rejouer deux fois le meme morceau dans la meme « passe ». Cela dit je comprend pas tres bien ce que tout ce bordel fait dans une hashtable si tu veux pas faire des acces par clef. C’est quoi la clef de ta hashtable?
[right][post=« 354537 »]<{POST_SNAPBACK}>[/post][/right][/quote]
Les clées dont en fait les noms des fichiers. Comme je l’ai dit plus haut c’est pas moi qui ai crée ni la HashTable, ni même l’application. Donc je n’ai aucune idée du pourquoi concernant le choix de cettre structure mais je suppose que si c’est utilisé, c’est que ça doit avoir son utilité.

Pour résumer j’ai à l’instant une application qui garde toute ses chansons dans une HashTable et moi je souhaiterai créer une fonction qui en sélectionne quelques unes aléatoirement et les rajoute dans la playlist. Tout connement … une bête extension de 15 lignes quoi.

Maintenant, oui un shuffle réellement aléatoire ça peut vagement m’interesser mais c’est franchement loin d’être prioritaire pour moi, surtout s’il faut recoder la moitié de l’application. Enfin si tu as une quelconque doc là-dessus je prend toujours.

Kaneloon [post=« 354594 »]<{POST_SNAPBACK}>[/post] > C’est pas bête comme idée mais j’ai l’impression que ca fonctionne uniquement si l’ordre des éléments est déjà aléatoire au départ et je crains qu’il y ai un pseudo ordre quelconque dans la hashtable et donc que les valeurs obtenues soit proche les unes des autres.

KiniK [post=« 354535 »]<{POST_SNAPBACK}>[/post]> Heu … en quoi ca serait différent par rapport à ce que j’ai proposé plus haut?