1

I've a list of objects and each object contains a percentage.

I wanna grab a random object based on it's percentage.

Example:

public class Item {
    private int chance;

    /* ... */
}

public class App {
    private List<Item> items;

    /* ... */

    public getItem() {
        // Get random item based on it's percentage
    }
}

I've seen a lot of posts talking about weight, but in this case I need percentages.

Thank you! :P

  • 1
    Hi, very interesting, perhaps this might be of interest https://stackoverflow.com/questions/6409652/random-weighted-selection-in-java – IronMan May 22 '20 at 20:02
  • Thank you for the reply @IronMan but weights does not work for me. But, if i don't find one more efficient code, I'll convert the percentages to weight ranges. :P –  May 22 '20 at 20:07
  • 2
    Isn't percentage the same as a weight? How is it different? Can you provide an example? – Hari Menon May 22 '20 at 20:30
  • Percentage *is* weight. If you mean something else, please explain. – erickson May 22 '20 at 20:52

1 Answers1

0

Algorithm steps are:
1 - sum chances
2 - store multiple time an item according to chance
3 - generate a number up to sum_Chances and return the index (which is the object)

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Percent
{
    List<Item> l;
    Map<Integer,Item> m;
    public static void main(String[] args)
    {
        Percent p = new Percent();

        for(int i=0;i<=9;i++)
        {
            System.out.println(i+"_itemNo="+p.getItem().name);
        }

    }
    Percent()
    {
        l = new ArrayList();
        l.add(new Item("i1",1));
        l.add(new Item("i2",2));
        l.add(new Item("i3",3));
    }

    public Item getItem()
    {
        m = new HashMap();
        int total=0;
        int k=0;
        for(int i=0;i<l.size();i++)
        {

            total += l.get(i).chance;
            for(int j=0;j<l.get(i).chance;j++)
            {
                m.put(k,l.get(i));
                k++;
            }
        }
        int r = (int)(Math.random()*total);
        //System.out.println(r);
        return m.get(r);
    }
    class Item
    {
        Item(){};
        Item(String name, int chance)
        {
            this.name = name;
            this.chance = chance;
        }
        public int chance;
        public String name;
    }
}

Output:

0_itemNo=i3
1_itemNo=i3
2_itemNo=i3
3_itemNo=i3
4_itemNo=i1
5_itemNo=i2
6_itemNo=i1
7_itemNo=i2
8_itemNo=i2
9_itemNo=i3


It's easy to see even with 10-events that item_3 have maximum occurrences

Traian GEICU
  • 1,750
  • 3
  • 14
  • 26