AKIWEB
AKIWEB

Reputation: 19632

Call Different Task Based on their Percentage

Task1, X% 
Task2, Y%
Task3, Z%
----
TaskN, N%

And X + Y + Z + . . .  + N = 100%

Question:- The above Config File have some type of weighing to Different Tasks (execute Task1 X% of the time and print anything on Line1, execute Task2 Y% of the time and print anything on Line2 and execute Task3 Z% of the time and print anything on Line3 and etc etc. Total weighing should add up to 100%.

Code that I wrote:- I wrote a program in which I am reading the files line by line and stored all the lines in the ArrayList of String, and then I generated some random number between 1 and 100. So for example there are three Tasks-

Task1 75%
Task2 15%
Task3 10%   

Get a random number between 1-100. If the number is 1-75 do Task1 means print anything on line1, 76-90 do Task2 means print anything on Line2, 91-100 do Task3 means print anything on line3. But how I can expand this for any Config File having N Tasks with any percentage number. I am stuck on this part.

                private static Random r = new Random();
                private final static int Low = 1;
                private final static int High = 100;
                String sCurrentLine;
                ArrayList<Integer> percentageCalls = new ArrayList<Integer>();

                br = new BufferedReader(new FileReader("S:\\config.txt"));

                int R = r.nextInt(High-Low) + Low;

                ArrayList<List<String>> allLines = new ArrayList<List<String>>();
                while ((sCurrentLine = br.readLine()) != null) {
                    allLines.add(Arrays.asList(sCurrentLine.split("\\s+")));
                    Collections.shuffle(allLines);
                }

                for (List<String> s1 : allLines) {
                    percentageCalls.add(Integer.parseInt(s1.get(0)));
                }
                Collections.sort(percentageCalls, Collections.reverseOrder());

Upvotes: 2

Views: 564

Answers (1)

Mike Twain
Mike Twain

Reputation: 66

I recently wrote something to do this for a project that you should be able to adapt. This class allows an arbitrary number of choices to be added to a list of "Possibilities." The chance amount can be any integer...the total doesn't need to add up to 100. So if you wanted choice A to happen 5 out of 302 times and choice B to happen the other 297 times then you could add A with a chance of 5 and B with a chance of 297. This code is a bit rough and probably needs some refinement but the idea should help you expand to N choices. You'll just need to write something that loops through the file and adds each possibility to the ResultGenerator.

Sample use:

ResultGenerator<String> rgen = new ResultGenerator<String>();

rgen.AddPossibility("Red", 25);
rgen.AddPossibility("Blue", 20);
rgen.AddPossibility("Green", 30);
rgen.AddPossibility("Black", 5);
rgen.AddPossibility("White", 15);

String result = rgen.GetRandomResult();

Class:

public class ResultGenerator<T> {

     class Possibility
     {
         Possibility(T choice, int chance)
         {
             this.Choice = choice;
             this.Chance = chance;
         }

         public T Choice;
         public int Chance;
         public int RangeMax;
         public int RangeMin;

     }

     private Random r;

     public ResultGenerator(Random r)
     {
         this.r = r;
     }

     public ResultGenerator()
     {
         this.r = new Random();
     }

     private List<Possibility> possibilities = new ArrayList<Possibility>();

     public void AddPossibility(T choice, int chance) {
         possibilities.add(new Possibility(choice, chance));
     }

     public T GetRandomResult() {

         if (possibilities.size() == 0)
             return null;

         //Calculate ranges for possibilities
         int totalChances = 0;
         for (Possibility p : possibilities) {
             p.RangeMin = totalChances;
             p.RangeMax = totalChances + p.Chance;
             totalChances += p.Chance;
         }

         int randomNumber = 1 + r.nextInt(totalChances + 1);

         for(Possibility possibility : possibilities)
         {
             if (randomNumber <= possibility.RangeMax && randomNumber > possibility.RangeMin)
             {
                 return possibility.Choice;
             }
         }

         return null;
     }

}

Upvotes: 2

Related Questions