简体   繁体   English

使用Walker的Alias方法进行加权随机选择

[英]Weighted random selection using Walker's Alias Method


I was looking for this algorithm 我在找这个算法
(algorithm which will randomly select from a list of elements where each element has different probability of being picked (weight) ) (将从元素列表中随机选择的算法,其中每个元素具有不同的被挑选概率(权重))
and found only python and c implementations, after I did a C# one, a bit different (but I think simpler) I thought I should share it, also I need an F# imlementation , if anyone can make it please post an answer 并且发现只有python和c实现,在我做了一个C#之后,有点不同(但我认为更简单)我认为我应该分享它,我也需要一个F#imlementation ,如果有人能做到它请发表回答

using System;
using System.Collections.Generic;
using System.Linq;

namespace ChuckNorris
{
    class Program
    {
        static void Main(string[] args)
        {
            var oo = new Dictionary<string, int>
                         {
                             {"A",7},
                             {"B",1},
                             {"C",9},
                             {"D",8},
                             {"E",11},
                         };

            var rnd = new Random();
            var pick = rnd.Next(oo.Values.Sum());

            var sum = 0;
            var res = "";

            foreach (var o in oo)
            {
                sum += o.Value;
                if(sum >= pick)
                {
                    res = o.Key;
                    break;
                }
            }

            Console.WriteLine("result is "+  res);
        }
    }
}

if anyone can remake it in F# please post your code 如果有人可以在F#中重拍它,请发布您的代码

Here is the similar code in F#: 这是F#中的类似代码:

let rng = new System.Random()
let d = [| "A", 3
           "B", 2
           "C", 3 |]
let sums = Seq.scan (+) 0 (dict d).Values |> Seq.skip 1 |> Seq.toArray 
let pick = rng.Next(sums.[sums.Length-1])
let res = fst d.[sums |> Seq.findIndex ((<) pick)]
open System let oo = dict [ "A", 7; "B", 1; "C", 9; "D", 8; "E", 11 ] let rnd = Random() let pick = oo.Values |> Seq.sum |> rnd.Next let res = oo |> Seq.scan (fun (_, s) (KeyValue(k, v)) -> k, s + v) ("", 0) |> Seq.tryPick (fun (k, s) -> if s >= pick then printfn "Result is %s" k; Some k else None)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM