2011-10-08 155 views
1

我需要生成238個數字,範圍爲1-4,但我想加權,所以有35%的機會獲得3,28%的機會獲得2,18%獲得4米的機會,並獲得1AS3中數字的百分比分佈

的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?

回答

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 
} 

(未經測試的代碼,但這個想法應該工作)

+0

這與其他類似r代碼,但我不知道它是如何給我的值。 – Phil

+0

嗯,不。你將不得不把它放在一個函數中,重複它238次,存儲結果。 –

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); 
} 
+0

logger.traceObject: public function traceObject(message:String,o:Object):void {message = message?消息:'追蹤對象'; this.traceLog(message); (var key:String in o){ for this('key:'+ o [key]); } } –