AS3中数字的百分比分布

时间:2011-10-08 19:25:04

标签: actionscript-3

我需要生成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?

3 个答案:

答案 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);
}