Процентное распределение чисел в AS3 - PullRequest
1 голос
/ 08 октября 2011

Мне нужно сгенерировать 238 чисел с диапазоном 1-4, но я хочу их взвесить, так что, скажем, 35% шансов получить 3, 28% шансов получить 2, 18% шансов получить 4 м, и19% шанс получить 1.

Я нашел это ..

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 ]

1 голос
/ 08 октября 2011

Я бы сделал что-то вроде этого:

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
}

(непроверенный код, но идея должна работать)

1 голос
/ 08 октября 2011

Посмотрите на эту статью:

http://uihacker.blogspot.com/2009/09/actionscript-3-choose-random-item-from.html

Вы также можете использовать Rnd.bit(), чтобы получить взвешенную 1 или 0 и адаптировать ее к вашей ситуации.

0 голосов
/ 19 августа 2017

Здесь для вас:

/**
 * 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: /5597153/sozdat-vzveshennoe-sluchainoe-chislo
        // 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...