我需要生成238个数字,范围为1-4,但我想对它们进行加权,所以有35%的几率获得3,28%的几率获得2,18%的几率获得4m,以及获得1的几率为19%。
我发现了这个..
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 } )
但我不知道如何将其转换为AS3?
答案 0 :(得分:1)
看一下这篇文章:
http://uihacker.blogspot.com/2009/09/actionscript-3-choose-random-item-from.html
您还可以使用Rnd.bit()
获得加权1或0,并根据您的情况进行调整。
答案 1 :(得分:1)
我会做这样的事情:
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
}
(未经测试的代码,但这个想法应该有用)
答案 2 :(得分:0)
给你:
/**
* 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)];
}
然后你可以用这段代码测试:
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);
}