2011-10-08 4 views
1

Je dois générer 238 nombres, avec une fourchette de 1-4, mais je veux les pondérer, donc il y a 35% de chance d'obtenir 3, 28% de chance d'obtenir 2, 18% chance d'obtenir 4 m, et 19% de chances d'obtenir 1.Pourcentage Répartition des nombres dans AS3

J'ai trouvé ..

def select(values): 
variate = random.random() * sum(values.values()) 
cumulative = 0.0 
for item, weight in values.items(): 
    cumulative += weight 
    if variate < cumulative:    return item 
return item # Shouldn't get here, but just in case of rounding... print select({ "a": 70, "b": 20, "c": 10 }) 

Mais je ne vois pas comment convertir en AS3?

Répondre

1

je ferais quelque chose comme ceci:

var values:Array = [1,2,3,4]; 
var weights:Array = [35, 28, 18, 19]; 

var total:Number = 0; 
for(var i in weights) { 
    total += weights[i]; 
} 

var rndNum:Number = Math.floor(Math.random()*total); 

var counter:Number = 0; 
for(var j:Number = 0; j<weights.length; j++) { 
    counter += weights[j]; 
    if(rndNum <= counter) return values[j]; //This is the value 
} 

(code non testé, mais l'idée devrait fonctionner)

+0

C'est similaire à l'autre r code, mais je ne vois pas comment cela me donne 238 valeurs. – Phil

+0

Eh bien, non. Vous devriez mettre cela dans une fonction et le répéter 238 fois, en stockant les résultats. –

0

ici pour vous:

/** 
* random due to weighted values 
* 
* @param {{}} spec such as {'a':0.999, 'b':0.001} 
* @return {*} return the key in object 
*/ 
public static function weightedRand(spec:Object):* { 
    var i:String, j:int, table:Array = []; 
    for (i in spec) { 
     // from: https://stackoverflow.com/questions/8435183/generate-a-weighted-random-number 
     // The constant 10 below should be computed based on the 
     // weights in the spec for a correct and optimal table size. 
     // E.g. the spec {0:0.999, 1:0.001} will break this impl. 
     for (j=0; j<spec[i]*10; j++) { 
      table.push(i); 
     } 
    } 

    return table[Math.floor(Math.random() * table.length)]; 
} 

Ensuite, vous pouvez tester avec ce code :

public static function main():void { 

    // test calculate weighted rand 
    // random weighted 
    var result:Array = []; 
    for (var k:int = 0; k < 100; k++) { 
     var rand012:String = MyUtil.weightedRand({'y': 0.8, 'n1': 0.1, 'n2': 0.1}); 
     result.push(rand012); // random in distribution... 
    } 

    logger.traceObject('result: ', result); 

    // counts 
    var counts:Object = {}; 
    var totalCounts:int = 0; 
    for (var i:int = 0; i < result.length; i++) { 
     counts[result[i]] = 1 + (counts[result[i]] || 0); 
     totalCounts++; 
    } 

    logger.traceObject('counts: ', counts); 

    // ratios 
    var ratios:Object = {}; 
    for (var c:String in counts) { 
     ratios[c] = counts[c]/totalCounts; 
    } 

    logger.traceObject('ratios: ', ratios); 
} 
+0

logger.traceObject: fonction publique traceObject (message: Chaîne, o: objet): void { message = message? message: 'objet de traçage'; this.traceLog (message); pour (var clé: Chaîne dans o) { this.traceLog ('clé:' + clé + '; valeur =' + o [clé]); } } –

Questions connexes