Il y a un problème que je constate sur ce serveur depuis pas mal de temps : des évènements basés sur de faibles pourcentages se produisent parfois un nombre choquant de fois bien que les valeurs de pourcentages implantées soient correctes.
Exemple : Les résistances aux stuns, poisons etc qui se produisent jusqu'à 5-6 fois à la suite alors que les pourcentages n'excèdent pas 15% par exemple. Ou bien encore 3-4 résist taunt d'affilée ou le pourcentage incompressible de résistance aux sorts qui entraîne, le temps d'un down d'un boss, 10% de sorts résistés sur un échantillon de près de 100 sorts.
Cela implique des enchaînements d'évènements assez choquants et qui semblent aller à l'encontre de la logique. Après réflexion je commence à me dire que ce problème vient d'un souci au niveau du script de la RNG, qu'en gros, la RNG met trop de lancers à s'équilibrer sur ce serveur et qu'elle permet aux pourcentages de varier totalement aléatoirement sans restriction.
Ne pensant pas que cette mécanique soit vraiment blizzlike (à savoir d'obtenir des pourcentages d'apparition d'un évènement qui vont parfois jusqu'à être quasiment 10 fois supérieurs à la valeur implantée et sur un échantillon de quelque centaines de lancers), si le problème observé vient bien de la RNG, il me semblerait logique de faire des modifications sur celle-ci :
- Inclure une limite d'apparition d'évènements. Exemple : pour un évènement qui a X % de chances de se produire, limiter la variation ponctuelle du pourcentage à 2-3 * X %. Cela permettrait de limiter les aberrations observées parfois. La valeur de 2-3X est une valeur discutable et je ne la donne qu'en exemple, je pense qu'elle peut être optimisée (mais je ne sais honnêtement pas comment).
- Ou bien / et si nécessaire, réduire le nombre de lancers à partir duquel on aurait un pourcentage mesuré quasi égal à celui qui est implanté. (Cela permettrait au passage aux joueurs de faire des tests plus facilement sur tout ce qui est proc)
N'ayant quasiment pas de connaissances en programmation, je propose cela en tant qu'amateur et si ce n'est pas réalisable pour X raisons, j'espère au moins donner quelques pistes de réflexions. Il me semble que cela pourrait être bénéfique à la qualité des mécaniques du serveur.
Toi tu cherches les problèmes.
43 try ? oO
J'anticipe la suite: "Prouve qu'il y a un soucis, fais un report et on là on se penchera dessus".
Kalameet a écrit:"Prouve qu'il y a un soucis, fais un report et on là on se penchera dessus".
C'est a peu près ça. Il n'y aura aucune valeur modifié sauf si on prouve que la mécanique est incorrecte.
Privilégiez google pour vos questions, généralement la réponse survient au bout de 5 minutes.
Dans l'hypothèse où j'apporterais une preuve d'un écart ponctuel vraiment significatif entre le pourcentage implanté et le pourcentage mesuré, pourrait-ce être considéré comme un souci ?
#TauxDeLootDeLaTempêteDuChaos
43 try ? oO
C'est ce qu'on entend généralement par "prouver" wé. :|
d'un écart ponctuel ? Sur des pourcentages un écart "ponctuel" ne veut rien dire... Si ce n'est le facteur chance...
De plus je suppose que ce qui fait couiner est le racial orc, durant toute son existence (je crois qu'il n'existe plu aujourd'hui?) il a fait pleurer les rogues, druides, war... Y'a rien d’aberrant malheureusement a enchaîner les resist's sur des orcs.
Donc a moins que vous n'arriviez avec des chiffres fiables et bien sûr prouvé, rien ne sera fait.
Privilégiez google pour vos questions, généralement la réponse survient au bout de 5 minutes.
Apedemak a écrit:d'un écart ponctuel ? Sur des pourcentages un écart "ponctuel" ne veut rien dire... Si ce n'est le facteur chance...
Tu peux tout à fait calculer la proba d'avoir telle ou telle série et quelle chance a cette proba d'infirmer la règle. C'est pas parce que ce sont des probabilités que d'un coup tout devient logique sous prétexte "qu'il y a une infime chance que cela se produise si on a de la luck".
Pas spécialement le racial orc. C'est juste un exemple parmi tant d'autres. Quand on voit que certains démos arrivent à choper du 10% résist sur un boss entier alors qu'ils sont capés toucher je vois pas à quel moment on peut ne pas se dire qu'il y a un souci sans se voiler la face.
Mais ouais okay j'ai bien compris ^^. On nous demande le taff de recherche de bugg, d'identification et de test des raids / sorts sans jamais faire d'exception. Le souci ici c'est qu'on n'a pas les outils en tant que joueur pour étudier la RNG. On a juste moyen d'observer certains phénomènes et honnêtement je ne suis pas le seul à remarquer des choses étranges.
Edit : Et honnêtement, personnellement, j'en peux plus de prémâcher le travail pour qu'on ne nous écoute pas forcément, qu'il arrive qu'on se fasse envoyer paitre et qu'il arrive aussi que les infos qu'on se tue à avoir ne soient jamais utilisées.
"Sur une série de x épreuves j'ai obtenu la série x qui a x chance de se produire. La probabilité que le postulat de base soit faux est donc de x (NB: c'est ce dernier x-là qui compte). Et ensuite: Cela s'applique aux actions x/y/z/... dans les situations x/y/z/..."
Voilà. S'pas facile à faire mais les impressions c'est bullshit dans un report.
Kalameet a écrit:"Sur une série de x épreuves j'ai obtenu la série x qui a x chance de se produire. La probabilité que le postulat de base soit faux est donc de x (NB: c'est ce dernier x-là qui compte). Et ensuite: Cela s'applique aux actions x/y/z/... dans les situations x/y/z/..."
Voilà. S'pas facile à faire. Les impressions c'est bullshit dans un report.
Si toi, tu as les outils, je t'invite à faire un guide ou à le faire :). Ce n'est pas mon cas ^^.
Vaches a écrit:Ce n'est pas mon cas ^^.
La probabilité que tu doivent continuer à endurer est donc de 100%.
Le fait est que des personnes ont pris la peine de report leurs problèmes et qu'ils attendent avec patience leurs résolutions. Nous avons peu de moyen de développement, si vous voulez plus de recherche et de debug, je vous invite à postuler en tant que dev, toute aide est la bien venue, en attendant nous utilisons nos ressources pour se pencher sur les problèmes réels et non a rechercher la valeur d'une supposition émise par joueurs, car oui des suppositions de bugs sur tel ou tel chose, on en a 15 par jours en requêtes... 13 sont fausses 1 est a test, la dernière appartient au mystique généralement. Arrêtez donc de croire que parce qu'on fait pas tout de suite là maintenant, voir même en preshot, les tests nécessaire a votre question qu'on en a rien a faire, nous n'avons simplement pas les ressources nécessaire pour tester chaque hypothèse. Même si vous n'avez pas de suite les valeurs, rien ne vous empêche de récolter diverses informations relatif au problème sans pour autant vous penchez plus que ça sur le cas... Dans le cas de la resistance des boss vous pouvez récoltez les combats logs en listant les stats du personnage en question afin de voir si quelque chose ressort de ces données. Pour faire comprendre définitivement les choses, seul Lorh à tous les outils nécessaire si on suit votre raisonnement (sources, support, connaissances, expériences). Le problème c'est qu'aussi nain soit il, on ne peut pas le dédoubler pour augmenter le rendement et la disponibilité. Ensuite Kalameet, tu es hors propos, je n'ai jamais dis qu'on ne pouvait pas extraire de constante ou de schéma, seulement qu'un "écart ponctuel" ne signifiait rien, avant d'avoir a étaler ta science a tout bout de champ, il suffit de lire ce que j'écris soit: d'un écart ponctuel ? Sur des pourcentages un écart "ponctuel" ne veut rien dire...
Inutile de chercher un complot illuminati derrière mon post, j’essaie de vous facilitez la vie en disant les choses le plus concrètement/simple/direct possible, à croire que ça ne suffit pas.
Privilégiez google pour vos questions, généralement la réponse survient au bout de 5 minutes.
Apedemak a écrit:je n'ai jamais dis qu'on ne pouvait pas extraire de constante ou de schéma, seulement qu'un "écart ponctuel" ne signifiait rien
Ben détrompe-toi. Une unique série de par exemple 10 épreuves qui ont chacune 1 chance sur un million d'arriver c'est très (très) hautement significatif, pourtant ce n'est jamais qu'un "écart ponctuel" ^^
On ne report pas un "écart ponctuel" on report quand c'est régulier/fréquent étant donné que comme son nom l'indique, un écart ponctuel est par définition, ponctuel, auquel cas écart ponctuel + report = ne signifie rien.
Par contre s'il ressort des observations/tests mené par la dite personne, une régularité ou tout du moins que cela arrive trop souvent de façon hors normes dans les faits, alors un report est mérité.
Je pense que c'est plus simple de comprendre ainsi ? Ou tu as vraiment envie de tourner encore & encore sans rien faire avancer ?
Privilégiez google pour vos questions, généralement la réponse survient au bout de 5 minutes.
Apedemak a écrit:Ou tu as vraiment envie de tourner encore & encore sans rien faire avancer ?
Hein? C'est fini là, l'auteur s'est lui-même annoncé incapable de réaliser le travail statistique idoine à l'écriture du report. Je peux pas stopper un thread qui est déjà au point mort ^^ Par contre je peux continuer à te répondre par politesse mais après on va dire que je flood donc... :/
Par contre s'il ressort des observations/tests mené par la dite personne, une régularité ou tout du moins que cela arrive trop souvent de façon hors normes dans les faits, alors un report est mérité.
C'est donc largement suffisant pour ouvrir un thread partie suggestion alors. Preso il m'est arrivé en un an sur ce serv plus de choses ayant des chances inférieures a 10^-6 d'arriver, qu'en je sais plus combien d'années sur le serv dont il ne faut pas faire de pub. 17 coups consécutifs sans crit alors que j'ai 52% crit fche perso +les 3% du ret, la semaine derniere sur bruta, pour ne citer que sa. (dsl pour l'uptime perce faille les gars au passage :s) 4 resist fear consécutif en dh sur un demo cap toucher (merci pour les insultes post match mdr, sa fait plaiz) ya 3 semaines de sa en arènes. Et la je ne prends que des exemple qui me sont arrivés et qui m'ont surtout marqués, je parle pas des centaines d'autres joueurs qui le constatent tous les jours. Si tu veux t'amuser a calculer le % de chances que sa arrive au niveau des crits / non crit ou resist total/ pas resist https://fr.wikipedia.org/wiki/Loi_binomialeDire qu'on a rien pour se baser pour trouver l'origine du problème ok, dire que sa n'a pas lieu pour un post partie bug, c'est se moquer ouvertement des joueurs du sont ici.
|
|
Enohry
<Héritier des Shen Dralar>
|
Attends toujours la raison de son ban forum
Modifier la RNG ? On se moque des joueurs ? Pas de soucis, voici notre RNG : - Code: Tout sélectionner
// MersenneTwister.h // Mersenne Twister random number generator -- a C++ class MTRand // Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus // Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
// The Mersenne Twister is an algorithm for generating random numbers. It // was designed with consideration of the flaws in various other generators. // The period, 2^19937-1, and the order of equidistribution, 623 dimensions, // are far greater. The generator is also fast; it avoids multiplication and // division, and it benefits from caches and pipelines. For more information // see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference // M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally // Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on // Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, // Copyright (C) 2000 - 2003, Richard J. Wagner // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The names of its contributors may not be used to endorse or promote // products derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice: // // When you use this, send an email to: matumoto@math.keio.ac.jp // with an appropriate reference to your work. // // It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu // when you write.
#ifndef MERSENNETWISTER_H #define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has // its own MTRand object)
#include"Platform/Define.h"
#include <limits.h> #include <time.h> #include <math.h>
class MTRand { // Data public: typedef ::uint32 uint32; enum { N = 624 }; // length of state vector enum { SAVE = N + 1 }; // length of array for save()
protected: enum { M = 397 }; // period parameter uint32 state[N]; // internal state uint32 *pNext; // next value to get from state int left; // number of values left before reload needed
//Methods public: MTRand( const uint32& oneSeed ); // initialize with a simple uint32 MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array MTRand(); // auto-initialize with /dev/urandom or time() and clock() MTRand(const MTRand&); // prevent copy constructor MTRand& operator=(const MTRand&); // no-op operator= // Do NOT use for CRYPTOGRAPHY without securely hashing several returned // values together, otherwise the generator state can be learned after // reading 624 consecutive values. // Access to 32-bit random numbers double rand(); // real number in [0,1] double rand( const double& n ); // real number in [0,n] double randExc(); // real number in [0,1) double randExc( const double& n ); // real number in [0,n) double randDblExc(); // real number in (0,1) double randDblExc( const double& n ); // real number in (0,n) uint32 randInt(); // integer in [0,2^32-1] uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 double operator()() { return rand(); } // same as rand() // Access to 53-bit random numbers (capacity of IEEE double precision) double rand53(); // real number in [0,1) // Access to nonuniform random number distributions double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); // Re-seeding functions with same behavior as initializers void seed( const uint32 oneSeed ); void seed( uint32 *const bigSeed, const uint32 seedLength = N ); void seed(); // Saving and loading generator state void save( uint32* saveArray ) const; // to array of size SAVE void load( uint32 *const loadArray ); // from such array /* Mangos not use streams for random values output friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); */ protected: void initialize( const uint32 oneSeed ); void reload(); uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } uint32 mixBits( const uint32& u, const uint32& v ) const { return hiBit(u) | loBits(v); } uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const { return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); } static uint32 hash( time_t t, clock_t c ); };
inline MTRand::MTRand(const MTRand&) { seed(); }
inline MTRand& MTRand::operator=(const MTRand&) { return *this; }
inline MTRand::MTRand( const uint32& oneSeed ) { seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) { seed(bigSeed,seedLength); }
inline MTRand::MTRand() { seed(); }
inline double MTRand::rand() { return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n ) { return rand() * n; }
inline double MTRand::randExc() { return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n ) { return randExc() * n; }
inline double MTRand::randDblExc() { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n ) { return randDblExc() * n; }
inline double MTRand::rand53() { uint32 a = randInt() >> 5, b = randInt() >> 6; return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada }
inline double MTRand::randNorm( const double& mean, const double& variance ) { // Return a real number from a normal (Gaussian) distribution with given // mean and variance by Box-Muller method double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); return mean + r * cos(phi); }
inline MTRand::uint32 MTRand::randInt() { // Pull a 32-bit integer from the generator state // Every other access function simply transforms the numbers extracted here if( left == 0 ) reload(); --left; register uint32 s1; s1 = *pNext++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680UL; s1 ^= (s1 << 15) & 0xefc60000UL; return ( s1 ^ (s1 >> 18) ); }
inline MTRand::uint32 MTRand::randInt( const uint32& n ) { // Find which bits are used in n // Optimized by Magnus Jonsson (magnus@smartelectronix.com) uint32 used = n; used |= used >> 1; used |= used >> 2; used |= used >> 4; used |= used >> 8; used |= used >> 16; // Draw numbers until one is found in [0,n] uint32 i; do i = randInt() & used; // toss unused bits to shorten search while( i > n ); return i; }
inline void MTRand::seed( const uint32 oneSeed ) { // Seed the generator with a simple uint32 initialize(oneSeed); reload(); }
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) { // Seed the generator with an array of uint32's // There are 2^19937-1 possible initial states. This function allows // all of those to be accessed by providing at least 19937 bits (with a // default seed length of N = 624 uint32's). Any bits above the lower 32 // in each element are discarded. // Just call seed() if you want to get array from /dev/urandom initialize(19650218UL); register int i = 1; register uint32 j = 0; register int k = ( N > int(seedLength) ? N : int(seedLength) ); for( ; k; --k ) { state[i] = state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; state[i] &= 0xffffffffUL; ++i; ++j; if( i >= N ) { state[0] = state[N-1]; i = 1; } if( j >= seedLength ) j = 0; } for( k = N - 1; k; --k ) { state[i] = state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); state[i] -= i; state[i] &= 0xffffffffUL; ++i; if( i >= N ) { state[0] = state[N-1]; i = 1; } } state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array reload(); }
inline void MTRand::seed() { // Seed the generator with hash of time() and clock() values seed( hash( time(NULL), clock() ) ); }
inline void MTRand::initialize( const uint32 seed ) { // Initialize generator state with seed // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. // In previous versions, most significant bits (MSBs) of the seed affect // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. register uint32 *s = state; register uint32 *r = state; register int i = 1; *s++ = seed & 0xffffffffUL; for( ; i < N; ++i ) { *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; r++; } }
inline void MTRand::reload() { // Generate N new values in state // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) register uint32 *p = state; register int i; for( i = N - M; i--; ++p ) *p = twist( p[M], p[0], p[1] ); for( i = M; --i; ++p ) *p = twist( p[M-N], p[0], p[1] ); *p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state; }
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) { // Get a uint32 from t and c // Better than uint32(x) in case x is floating point in [0,1] // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0; unsigned char *p = (unsigned char *) &t; for( size_t i = 0; i < sizeof(t); ++i ) { h1 *= UCHAR_MAX + 2U; h1 += p[i]; } uint32 h2 = 0; p = (unsigned char *) &c; for( size_t j = 0; j < sizeof(c); ++j ) { h2 *= UCHAR_MAX + 2U; h2 += p[j]; } return ( h1 + differ++ ) ^ h2; }
inline void MTRand::save( uint32* saveArray ) const { register uint32 *sa = saveArray; register const uint32 *s = state; register int i = N; for( ; i--; *sa++ = *s++ ) {} *sa = left; }
inline void MTRand::load( uint32 *const loadArray ) { register uint32 *s = state; register uint32 *la = loadArray; register int i = N; for( ; i--; *s++ = *la++ ) {} left = *la; pNext = &state[N-left]; }
/* Mangos not use streams for random values output inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) { register const MTRand::uint32 *s = mtrand.state; register int i = mtrand.N; for( ; i--; os << *s++ << "\t" ) {} return os << mtrand.left; }
inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) { register MTRand::uint32 *s = mtrand.state; register int i = mtrand.N; for( ; i--; is >> *s++ ) {} is >> mtrand.left; mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; return is; } */
#endif // MERSENNETWISTER_H
Dites moi où est l'erreur provocant la redondance/le cycle/l'anormale fréquence dont vous vous plaignez, je la remonterais aux auteurs. N'hésitez pas à écrire un papier sur le sujet d'ailleurs cela peut m'intéresser.
|
|
Lorh
Administrateur Développeur
|
non 0 soucis sur la RNG TGC c'est juste très en avance en matière de stats
|
|
Azzy
<Les Smarties du Chaøs>
|
Des preuves, des preuves, ils veulent des preuves, nous voulons des preuves, pas des "ressenti" :)
43 try ? oO
Hello, résumons ce que nous avons de concret. D'un côté chose prouvée ce soir, lors d'un raid KZ auquel j'ai pu participer, j'ai pu voir certaines stats qui forcément choquent un peu par rapport au recount d'un démo du raid :   On voit quoi sur ces screens ? Déjà deux choses qui me choquent : - le pourcentage de crit diffère d'environ 7% (le démo m'a affirmé avoir 21% et des poussières de %age de crit sans compter les talents +8% du démo destru) sur les deux screens qui comportent 286 et 389 sorts. - le pourcentage de sorts résistés est d'environ 3% sur les deux screens alors que le démo est capé toucher, ce encore sur plusieurs centaines de lancers de sorts (soit trois fois plus que ce qu'on devrait avoir). Par ailleurs, on voit aussi une autre chose assez intéressante : le pourcentage de critique diminue entre le premier et le deuxième screen alors que le nombre de sorts lancés augmente. Je rappelle que je n'ai pas de connaissances en matière de script ou de probabilités mais il me semble assez étrange que quand on rajoute un nombre assez important de lancers, la statistique s'écarte du résultat visé. Edit : Pour ce point, j'admets que dans l'idée c'est statistiquement possible mais là on a quand même rajouté un peu plus d'une ceintaine de lancers, ça paraît un peu étrange. De l'autre, on a des dires de joueurs, qui certes ne prouvent rien tant qu'ils ne sont pas rapportés en tant que faits infaillibles, mais qui affirment qu'on voit que la RNG permet relativement souvent à des évènements qui sont presque statistiquement impossibles de se produire. (Je travaille là dessus, dès que j'aurai une source concernant cela, je vous ferai signe). Je tiens à préciser au vu des retours que je peux avoir eut sur ce post, que le souci n'est pas spécialement qu'il y a un bugg dans la RNG (d'où mon initiative de poster ça en tant que suggestion et pas en tant que report bugg). En soit la RNG du serveur est fonctionnelle. Le seul souci c'est que son fonctionnement entraîne à priori très souvent des évènements qui devraient être aussi rares que des éclipses. Selon moi, cela se produit pour une seule raison : la RNG du serveur met énormément de lancers à s'équilibrer (cf. le post viewtopic.php?f=34&t=35854&p=88461&hilit=r%C3%A9silience#p88461 où 4000 lancers laissent quand même un écart d'un peu plus d'1% entre la valeur mesurée et la valeur théorique par exemple) Par conséquent, la RNG n'est pas sans aucun doute pas mauvaise ni bugguée, mais il semblerait qu'elle pourrait être améliorée. Je tiens finalement à préciser que je n'ai en aucun cas créé ce sujet pour critiquer en quoi que ce soit mais plutôt dans l'optique d'avoir une discussion constructive sur un problème dont personne ne parle bien que beaucoup de gens s'en plaignent. J'admets qu'il y a beaucoup de mauvaises théories sur le problème des évènements étranges qu'on observe sur TGC et pas ailleurs mais honnêtement je n'aurais pas créé ce topic si je n'avais pas un minimum de confiance dans mon analyse.
Vaches a écrit:Par conséquent, la RNG n'est pas sans aucun doute pas mauvaise ni bugguée, mais il semblerait qu'elle pourrait être améliorée.
si c'est volontaire, 10/10, très shakespearien
que dieu me pardonne, maman, car j'ai Posté
On est repartis avec le meme discours qu'avec le camouflage, c'est sans espoir. Ps : merci avoir réussir a me donner un fou rire :p double phi = 2.0 * 3.14159265358979323846264338328
on doit virer toutes les adresses mails, statisticiens et recommandations qui n'ont rien a voir avec le serveur ?
|
|
Enohry
<Héritier des Shen Dralar>
|
Attends toujours la raison de son ban forum
Lorh a écrit:Modifier la RNG ? On se moque des joueurs ? Pas de soucis, voici notre RNG : - Code: Tout sélectionner
// MersenneTwister.h // Mersenne Twister random number generator -- a C++ class MTRand // Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus // Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
// The Mersenne Twister is an algorithm for generating random numbers. It // was designed with consideration of the flaws in various other generators. // The period, 2^19937-1, and the order of equidistribution, 623 dimensions, // are far greater. The generator is also fast; it avoids multiplication and // division, and it benefits from caches and pipelines. For more information // see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference // M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally // Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on // Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, // Copyright (C) 2000 - 2003, Richard J. Wagner // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The names of its contributors may not be used to endorse or promote // products derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice: // // When you use this, send an email to: matumoto@math.keio.ac.jp // with an appropriate reference to your work. // // It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu // when you write.
#ifndef MERSENNETWISTER_H #define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has // its own MTRand object)
#include"Platform/Define.h"
#include <limits.h> #include <time.h> #include <math.h>
class MTRand { // Data public: typedef ::uint32 uint32; enum { N = 624 }; // length of state vector enum { SAVE = N + 1 }; // length of array for save()
protected: enum { M = 397 }; // period parameter uint32 state[N]; // internal state uint32 *pNext; // next value to get from state int left; // number of values left before reload needed
//Methods public: MTRand( const uint32& oneSeed ); // initialize with a simple uint32 MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array MTRand(); // auto-initialize with /dev/urandom or time() and clock() MTRand(const MTRand&); // prevent copy constructor MTRand& operator=(const MTRand&); // no-op operator= // Do NOT use for CRYPTOGRAPHY without securely hashing several returned // values together, otherwise the generator state can be learned after // reading 624 consecutive values. // Access to 32-bit random numbers double rand(); // real number in [0,1] double rand( const double& n ); // real number in [0,n] double randExc(); // real number in [0,1) double randExc( const double& n ); // real number in [0,n) double randDblExc(); // real number in (0,1) double randDblExc( const double& n ); // real number in (0,n) uint32 randInt(); // integer in [0,2^32-1] uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 double operator()() { return rand(); } // same as rand() // Access to 53-bit random numbers (capacity of IEEE double precision) double rand53(); // real number in [0,1) // Access to nonuniform random number distributions double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); // Re-seeding functions with same behavior as initializers void seed( const uint32 oneSeed ); void seed( uint32 *const bigSeed, const uint32 seedLength = N ); void seed(); // Saving and loading generator state void save( uint32* saveArray ) const; // to array of size SAVE void load( uint32 *const loadArray ); // from such array /* Mangos not use streams for random values output friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); */ protected: void initialize( const uint32 oneSeed ); void reload(); uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } uint32 mixBits( const uint32& u, const uint32& v ) const { return hiBit(u) | loBits(v); } uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const { return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); } static uint32 hash( time_t t, clock_t c ); };
inline MTRand::MTRand(const MTRand&) { seed(); }
inline MTRand& MTRand::operator=(const MTRand&) { return *this; }
inline MTRand::MTRand( const uint32& oneSeed ) { seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) { seed(bigSeed,seedLength); }
inline MTRand::MTRand() { seed(); }
inline double MTRand::rand() { return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n ) { return rand() * n; }
inline double MTRand::randExc() { return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n ) { return randExc() * n; }
inline double MTRand::randDblExc() { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n ) { return randDblExc() * n; }
inline double MTRand::rand53() { uint32 a = randInt() >> 5, b = randInt() >> 6; return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada }
inline double MTRand::randNorm( const double& mean, const double& variance ) { // Return a real number from a normal (Gaussian) distribution with given // mean and variance by Box-Muller method double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); return mean + r * cos(phi); }
inline MTRand::uint32 MTRand::randInt() { // Pull a 32-bit integer from the generator state // Every other access function simply transforms the numbers extracted here if( left == 0 ) reload(); --left; register uint32 s1; s1 = *pNext++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680UL; s1 ^= (s1 << 15) & 0xefc60000UL; return ( s1 ^ (s1 >> 18) ); }
inline MTRand::uint32 MTRand::randInt( const uint32& n ) { // Find which bits are used in n // Optimized by Magnus Jonsson (magnus@smartelectronix.com) uint32 used = n; used |= used >> 1; used |= used >> 2; used |= used >> 4; used |= used >> 8; used |= used >> 16; // Draw numbers until one is found in [0,n] uint32 i; do i = randInt() & used; // toss unused bits to shorten search while( i > n ); return i; }
inline void MTRand::seed( const uint32 oneSeed ) { // Seed the generator with a simple uint32 initialize(oneSeed); reload(); }
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) { // Seed the generator with an array of uint32's // There are 2^19937-1 possible initial states. This function allows // all of those to be accessed by providing at least 19937 bits (with a // default seed length of N = 624 uint32's). Any bits above the lower 32 // in each element are discarded. // Just call seed() if you want to get array from /dev/urandom initialize(19650218UL); register int i = 1; register uint32 j = 0; register int k = ( N > int(seedLength) ? N : int(seedLength) ); for( ; k; --k ) { state[i] = state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; state[i] &= 0xffffffffUL; ++i; ++j; if( i >= N ) { state[0] = state[N-1]; i = 1; } if( j >= seedLength ) j = 0; } for( k = N - 1; k; --k ) { state[i] = state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); state[i] -= i; state[i] &= 0xffffffffUL; ++i; if( i >= N ) { state[0] = state[N-1]; i = 1; } } state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array reload(); }
inline void MTRand::seed() { // Seed the generator with hash of time() and clock() values seed( hash( time(NULL), clock() ) ); }
inline void MTRand::initialize( const uint32 seed ) { // Initialize generator state with seed // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. // In previous versions, most significant bits (MSBs) of the seed affect // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. register uint32 *s = state; register uint32 *r = state; register int i = 1; *s++ = seed & 0xffffffffUL; for( ; i < N; ++i ) { *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; r++; } }
inline void MTRand::reload() { // Generate N new values in state // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) register uint32 *p = state; register int i; for( i = N - M; i--; ++p ) *p = twist( p[M], p[0], p[1] ); for( i = M; --i; ++p ) *p = twist( p[M-N], p[0], p[1] ); *p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state; }
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) { // Get a uint32 from t and c // Better than uint32(x) in case x is floating point in [0,1] // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0; unsigned char *p = (unsigned char *) &t; for( size_t i = 0; i < sizeof(t); ++i ) { h1 *= UCHAR_MAX + 2U; h1 += p[i]; } uint32 h2 = 0; p = (unsigned char *) &c; for( size_t j = 0; j < sizeof(c); ++j ) { h2 *= UCHAR_MAX + 2U; h2 += p[j]; } return ( h1 + differ++ ) ^ h2; }
inline void MTRand::save( uint32* saveArray ) const { register uint32 *sa = saveArray; register const uint32 *s = state; register int i = N; for( ; i--; *sa++ = *s++ ) {} *sa = left; }
inline void MTRand::load( uint32 *const loadArray ) { register uint32 *s = state; register uint32 *la = loadArray; register int i = N; for( ; i--; *s++ = *la++ ) {} left = *la; pNext = &state[N-left]; }
/* Mangos not use streams for random values output inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) { register const MTRand::uint32 *s = mtrand.state; register int i = mtrand.N; for( ; i--; os << *s++ << "\t" ) {} return os << mtrand.left; }
inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) { register MTRand::uint32 *s = mtrand.state; register int i = mtrand.N; for( ; i--; is >> *s++ ) {} is >> mtrand.left; mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; return is; } */
#endif // MERSENNETWISTER_H
Dites moi où est l'erreur provocant la redondance/le cycle/l'anormale fréquence dont vous vous plaignez, je la remonterais aux auteurs. N'hésitez pas à écrire un papier sur le sujet d'ailleurs cela peut m'intéresser.
N=625 pour les vecteurs d'état, pas 624. Tu me mettras en premier auteur stp ? Pense à me filer le DOI dès que tu l'as. Pour le logiciel, tu peux le mettre en open source j'en fais cadeau à l'humanité.
|
|
43371
<Pas-de-Personnage>
|
This server is dark, and full of terrors.
Rowley a écrit:N=625 pour les vecteurs d'état, pas 624. Tu me mettras en premier auteur stp ? Pense à me filer le DOI dès que tu l'as. Pour le logiciel, tu peux le mettre en open source j'en fais cadeau à l'humanité.
Le but c'est de réduire les cycles/redondance des résultats, pas d'en ajouter.
|
|
Lorh
Administrateur Développeur
|
Lorh a écrit:Rowley a écrit:N=625 pour les vecteurs d'état, pas 624. Tu me mettras en premier auteur stp ? Pense à me filer le DOI dès que tu l'as. Pour le logiciel, tu peux le mettre en open source j'en fais cadeau à l'humanité.
Le but c'est de réduire les cycles/redondance des résultats, pas d'en ajouter.
Ben mets 623 alors. Ou 1, à y être... (J'aurais bien dit 0 mais je sens que ça peut pas marcher 0, c'est un piège)
|
|
43371
<Pas-de-Personnage>
|
This server is dark, and full of terrors.
T'as pas compris faut mettre 626 pour les diminuer..... bravo morray ( je bite rien au script c'est terrible xD)
Potestas
Sinon on met 1 000 ? C'est pas mal 1 000, c'est rond. Puis c'est à la fois beaucoup et pas tellement tu vois... Ou 1 000 000. Ca claque. 1 000 000 000 c'est too much, puis ça fait trop genre "hey regardez moi, je suis le milliard".
|
|
43371
<Pas-de-Personnage>
|
This server is dark, and full of terrors.
Dans ce cas mets 3 000 000 000, le script qui valait 3 milliards *_*
Potestas
Sinon on met 55725 , c'est l'id de mon perso, c'est assez swag.
"Tu parles juste au seul mec qui a organisé des events PvP sur ce serveur. Mais bon, NP, ça doit être un pur PvE boy. " - Rowley le 20/10/14
Des idées ou remarques qui pourraient nous faire avancer ?
|