使用随机数执行命令 A A % 的时间、命令 B B % 的时间、命令 C C % 的时间----- CommandZ



问题陈述:通过匹配其百分比随机执行各种命令。比如执行命令A 50%的时间和命令B25%的时间和命令C 15%的时间等等,总百分比应该是100%。

我的问题是 - 执行命令A A % 的时间,命令 B B% 的时间,CommandC C % 的时间----- CommandZ Z% 的时间。 总百分比应该是 100%,最后我可以看到 每个命令执行的次数以及执行次数 每个命令的百分比(表示每个命令的次数 以百分比形式执行(,在总执行完成后。

想法:-生成一个介于 1 和 100 之间的随机数,并查看是否有任何百分比落入该类别

List<Double> comamndDistribution = new ArrayList<Double>();
    /* Commands to execute. Here I have Z command 
    *  and total percentage should be 100% (A+B+C+D+...+Z=100%)
    */
        comamndDistribution.add(A%); // command A
        comamndDistribution.add(B%); // command B
        comamndDistribution.add(C%); // command C
        comamndDistribution.add(D%); // command D
        comamndDistribution.add(E%); // command E
        -----------
        -----------
        comamndDistribution.add(Z%); // command Z
private Command getNextCommandToExecute() {
    for (int i=0; i < 10000; i++) {
       // generating a random number between 1 and 100
      int random = r.nextInt(100-1) + 1;
    /* My Question is- Execute CommandA A% of time, CommandB B% 
       of time, CommandC C% of time ----- Command Z Z% of time. 
       And total percentage should be 100% and at the end I can see
       how much times each command is being executed and what is 
       the percentage of each command(means how many times each command is 
       being executed in terms of percentage) after total execution is complete.
    */
        }
}
/* Get the next command to execute by maintaining the Percentage of 
    each command randomly*/
    Command nextCommand = getNextCommandToExecute();

让我更清楚地说明 - 我的问题是 - 使用随机数执行命令 A A % 的时间、命令 B B % 的时间、命令 C C % 的时间-----命令 N N % 的时间。总百分比应为 100%。

PS:我想这个问题已经被问过几次了,但这不是我想要的方式。所以我想通过发布我到目前为止所做的代码来再次将其作为一个问题提出。

更新:- 我通过删除我用另一个逻辑编写的先前代码来更新问题,以便人们可以更好地理解它。

我的做法与亚当·利斯类似,但结果更冗长。

同样,我认为您不能依赖提供的命令总是加起来达到 100%,所以我已经应付了这个问题,但我的方式需要一个方法调用来重新规范比例(所以更容易出错(。

import java.util.*;
/** 
  A basic 'Command' class for testing
*/
class Command {
  private String id;
  public Command (String pId) {
    this.id = pId;
  }
  public void execute () {
    System.out.println ("Command: "+id);
  }
}
/** The class that does the random selection bit of magic */
public class CommandDist {
  /** an internal helper class to manage proportions and the command */
  class Cmd {
    Command command;                 // the command that will get executed
    double assignedProportion;       // weight assigned when added
    double cumulativeProportion;     // recalculated later to between 0 and 1
    public Cmd (Command c, double proportion) {
      this.command = c;
      this.assignedProportion = proportion;
      this.cumulativeProportion = 0.0;
    }
  }
  // the list I'm using 
  private List<Cmd> commandDistribution = new ArrayList<Cmd>();
  private java.util.Random myRandom = new java.util.Random();
  void addCommand (Command command, double proportion) {
    commandDistribution.add ( new Cmd (command, proportion));
  }
  // ** MUST BE CALLED **, after adding all the commands, to normalise the proportions.
  // you could do this tidier by setting a flag in add, and checking it in
  // getNextCommandToExecute
  void normaliseProportion() {
    double total = 0;
    double cumulativeProp = 0;
    for (Cmd cmd: commandDistribution) {
       total += cmd.assignedProportion;
    }
    for (Cmd cmd: commandDistribution) {
       cumulativeProp += cmd.assignedProportion/total;
       cmd.cumulativeProportion = cumulativeProp;
    }
  }

  private Command getNextCommandToExecute () {
    double d = myRandom.nextDouble();
    for (Cmd cmd: commandDistribution) {
      if (d < cmd.cumulativeProportion) {
        return cmd.command;
      }
    }
    // theoretically, should not get here.  Never rely on theoretically.
    return commandDistribution.get(0).command;
  }
  public static void main (String [] args) {
    CommandDist cd = new CommandDist();
    Command c; 
    cd.addCommand (new Command ("A"), 50.0);
    cd.addCommand (new Command ("B"), 20.0);
    cd.addCommand (new Command ("C"), 15.0);
    cd.addCommand (new Command ("D"), 10.0);
    cd.normaliseProportion();

    for (int i = 0; i < 10000; i++) {
       c = cd.getNextCommandToExecute();
       c.execute();
    }
  }
}

输出如下所示:

Command: C
Command: A
Command: C
Command: A
Command: D

并且通常像这样分布(当然,每次运行不同的计数(。

java CommandDist | sort | uniq -c
   5183 Command: A
   2151 Command: B
   1595 Command: C
   1071 Command: D

这不是你问的,但我认为这就是你的意思。

class RandomCommands {
  // A Map that associates each command with a threshold from 0 - totalWeights.
  // The order of iteration is the same as the order of insertion.
  private Map<int, Command> commands = new LinkedHashMap<int, Command>>();
  // Running total of the weights of all of the commands.  The likelihood that
  // particular command will be executed is its weight / totalWeights.
  private int totalWeights = 0;
  // Adds a command with the specified weight, which can be any positive integer.
  public void addCommand(int weight, Command command) {
    commands.put(totalWeights, command);
    totalWeights += weight;
  }
  // Chooses a random command.
  public Command getRandomCommand() {
    // Choose a random number to select a command.
    int selector = Random.nextInt(totalWeights);
    // Find the corresponding command.
    for (Element<int, Command> command : commands) {
      if (command.key >= selector) {
        return command.value;
      }
      selector -= command.key;
    }
  }
}

例:

假设我们有 3 个权重为 20、20 和 40 的命令。 由于权重的总和为 80,我们可以计算:

  • 前 2 个命令中的每一个都将在 20/80 = 1/4 = 25% 的时间内被选中。
  • 第 3 个命令将在 40/80 = 1/2 = 50% 的时间内被选中。

commands地图将包含以下条目:

<0,  Command1>
<20, Command2>
<40, Command3>

每次调用getRandomCommand()时,它都会选择一个从 0 到 79 的随机数。 它将返回以下命令之一,如下所示:

选择器命令执行频率————————   ———————   ——————————————————————————————————————— 0 - 19 命令1 (1 + 19 - 0(/80 = 20/80 = 1/4 = 25%20 - 39 命令2 (1 + 39 - 20(/80 = 20/80 = 1/4 = 25%40 - 79 命令3 (1 + 79 - 40(/80 = 40/80 = 1/2 = 50%

最新更新