selection based on percentage weighting

后端 未结 13 2117
忘掉有多难
忘掉有多难 2020-12-04 13:40

I have a set of values, and an associated percentage for each:

a: 70% chance
b: 20% chance
c: 10% chance

I want to select a value (a, b, c) based

13条回答
  •  借酒劲吻你
    2020-12-04 13:55

    I've my own solution for this:

    public class Randomizator3000 
    {    
    public class Item
    {
        public T value;
        public float weight;
    
        public static float GetTotalWeight(Item[] p_itens)
        {
            float __toReturn = 0;
            foreach(var item in p_itens)
            {
                __toReturn += item.weight;
            }
    
            return __toReturn;
        }
    }
    
    private static System.Random _randHolder;
    private static System.Random _random
    {
        get 
        {
            if(_randHolder == null)
                _randHolder = new System.Random();
    
            return _randHolder;
        }
    }
    
    public static T PickOne(Item[] p_itens)
    {   
        if(p_itens == null || p_itens.Length == 0)
        {
            return default(T);
        }
    
        float __randomizedValue = (float)_random.NextDouble() * (Item.GetTotalWeight(p_itens));
        float __adding = 0;
        for(int i = 0; i < p_itens.Length; i ++)
        {
            float __cacheValue = p_itens[i].weight + __adding;
            if(__randomizedValue <= __cacheValue)
            {
                return p_itens[i].value;
            }
    
            __adding = __cacheValue;
        }
    
        return p_itens[p_itens.Length - 1].value;
    
    }
    }
    

    And using it should be something like that (thats in Unity3d)

    using UnityEngine;
    using System.Collections;
    
    public class teste : MonoBehaviour 
    {
    Randomizator3000.Item[] lista;
    
    void Start()
    {
        lista = new Randomizator3000.Item[10];
        lista[0] = new Randomizator3000.Item();
        lista[0].weight = 10;
        lista[0].value = "a";
    
        lista[1] = new Randomizator3000.Item();
        lista[1].weight = 10;
        lista[1].value = "b";
    
        lista[2] = new Randomizator3000.Item();
        lista[2].weight = 10;
        lista[2].value = "c";
    
        lista[3] = new Randomizator3000.Item();
        lista[3].weight = 10;
        lista[3].value = "d";
    
        lista[4] = new Randomizator3000.Item();
        lista[4].weight = 10;
        lista[4].value = "e";
    
        lista[5] = new Randomizator3000.Item();
        lista[5].weight = 10;
        lista[5].value = "f";
    
        lista[6] = new Randomizator3000.Item();
        lista[6].weight = 10;
        lista[6].value = "g";
    
        lista[7] = new Randomizator3000.Item();
        lista[7].weight = 10;
        lista[7].value = "h";
    
        lista[8] = new Randomizator3000.Item();
        lista[8].weight = 10;
        lista[8].value = "i";
    
        lista[9] = new Randomizator3000.Item();
        lista[9].weight = 10;
        lista[9].value = "j";
    }
    
    
    void Update () 
    {
        Debug.Log(Randomizator3000.PickOne(lista));
    }
    }
    

    In this example each value has a 10% chance do be displayed as a debug =3

提交回复
热议问题