Search code examples
javarandomprobabilityweighted

Weighted randomness based on current values (Not sure how else to explain it)


Need some help with some code (Java)

I have a script which runs every few mins This script creates and deletes objects

For the sake of this example I want to have an average of 10 objects at any time

But a random probability of it creating and deleting objects based on how far it is from that 10 goal with hard limits, eg +- 3

I have gotten it to create objects till it reaches 7, and then delete once it goes past 13 But I cant figure out how to do the randomness between

If there is say 8 objects then it would have a higher probability of creating rather than deleting, if there are 10 then its a 50/50 split and if there is 12 then its more likely to delete then create

and im not asking for code, im happy to figure that out myself I just need a push in the right direction

Edit for update with what I currently have, I dont have the full code as there is alot of other things going on, but this is the part i need help with

This runs every min

int limit = F_Config.get().getInt("Limit");
int avg = F_Config.get().getInt("Average");
int current = P_Player.ReturnList().size();
int min = avg - limit;
int max = avg + limit;

//below min
if(current < min) {
    Main.sendConsole("Min");
    P_Player.LoginPlayer();
}

//above Max
else if(current > max) {
    Main.sendConsole("Max");
    P_Player.LogoutPlayer();
}

//Between min and Max
else{
    //Stuff here
}

Solution

  • First you have to clarify the algorithm, after how to implement (java) is something else.
    There are 2 operations : [add] and [delete] and you have to define based on some criteria the probability.

    Say: [Objects,AddP,DeleteP]

    1. [0,1,0] -> only option is to add
    2. [1 up to n, a, 1-a] , eg: [1-9, 0.75, 0.25]
    3. [n+1, m, b, 1-b] , eg: [10-15. 0.3, 0.7]
    4. [m+1, 0, 1] , eg: [16, 0, 1] -> only option is to delete

    On [2] and [3] just generate a random number and compare with a,b probability and choose an operation. Eg: [2] random = 0.60<0.75 => add, etc

    Note: 0 < a < 1 (same with b)

    import java.util.ArrayList;
    import java.util.List;
    
    public class Prob 
    {
        List<PSet> l = new ArrayList<PSet>();
        List<MyObj> obj = new ArrayList<MyObj>();
        @SuppressWarnings("unchecked")
        public static void main(String args[])
        {
            Prob p = new Prob();
            PSet ps1 = p.new PSet(0,0,1,0);
            PSet ps2 = p.new PSet(1,3,0.8,0.2);
            PSet ps3 = p.new PSet(4,5,0.3,0.7);
            PSet ps4 = p.new PSet(6,6,0,1);
            p.l.add(ps1);
            p.l.add(ps2);
            p.l.add(ps3);
            p.l.add(ps4);
    
            //loop 20 times
            for(int i=0;i<20;i++)
            {
                int counter = p.obj.size();
                for(int j=0;j<p.l.size();j++)
                {
                    PSet ps = p.l.get(j);
                    if(counter == 0 && counter == ps.start)
                    {
                        System.out.println(i+"_only_add, counter="+counter);
                        p.obj.add(p.new MyObj(String.valueOf(i)));
    
                    }
                    else if(counter > 0 && counter == ps.start && counter == ps.end)
                    {
                        System.out.println(i+"_only_del, counter="+counter);
                        p.obj.remove(0);
                    }
    
                    else if(counter>=ps.start && counter<=ps.end)
                    {
                        double rand = Math.random();
                        if(rand<ps.pAdd)
                        {
                            System.out.println(i+"_add, counter="+counter);
                            p.obj.add(p.new MyObj(String.valueOf(i)));
                        }
                        else
                        {
                            System.out.println(i+"_del, counter="+counter);
                            p.obj.remove(0);
                        }
                    }
    
                }
            }
        }
        class MyObj
        {
            String name;
            MyObj(String name)
            {
                this.name = name;
            }
        }
        class PSet
        {
            public int getStart() {
                return start;
            }
            public int getEnd() {
                return end;
            }
            public double getpAdd() {
                return pAdd;
            }
            public double getpDel() {
                return pDel;
            }
            int start;
            int end;
            double pAdd;
            double pDel;
            PSet(int start, int end, double pAdd, double pDel)
            {
                this.start = start;
                this.end = end;
                this.pAdd = pAdd;
                this.pDel = pDel;
            }
        }
    }
    

    Output:

    0_only_add, counter=0
    1_add, counter=1
    2_add, counter=2
    3_add, counter=3
    4_del, counter=4
    5_add, counter=3
    6_del, counter=4
    7_add, counter=3
    8_del, counter=4
    9_add, counter=3
    10_del, counter=4
    11_add, counter=3
    12_del, counter=4
    13_add, counter=3
    14_add, counter=4
    15_add, counter=5
    16_only_del, counter=6
    17_del, counter=5
    18_del, counter=4
    19_del, counter=3