代码之家  ›  专栏  ›  技术社区  ›  Quantum64

根据百分比选择值

  •  1
  • Quantum64  · 技术社区  · 9 年前

    我需要根据该值被选中的概率百分比来选择一个值。例如:

    • 时间增量值a的10%
    • 时间增量值b的20%
    • 时间增量值c的30%
    • 时间增量值d的40%

    百分比加起来总是精确到100%

    我遇到了几种解决方案,如 this one ,但已确定它们不可能是正确的。以下是使用上述解决方案构建的示例程序:

    import java.util.Random;
    
    public class Main {
    
        private static Random r = new Random();
    
        public static void main(String[] args) {
            final int iterations = 1000000;
            System.out.println("Testing percentage based random, " + iterations + " iterations");
            int onePercent = 0;
            int sixPercent = 0;
            int sevenPercent = 0;
            int thirtySixPercent = 0;
            int fiftyPercent = 0;
            // Those values add up to 100% overall
            for (int i = 0; i < iterations; i++) {
                int random = r.nextInt(100);
                if (random < 1) {
                    onePercent++;
                    continue;
                }
                if (random < 6) {
                    sixPercent++;
                    continue;
                }
                if (random < 7) {
                    sevenPercent++;
                    continue;
                }
                if (random < 36) {
                    thirtySixPercent++;
                    continue;
                }
                if (random < 50) {
                    fiftyPercent++;
                    continue;
                }
                // That can't be right because if random > 50 then nothing at all happens
            }
            System.out.println("One percent happened about " + (onePercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Six percent happened about " + (sixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Seven percent happened about " + (sevenPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Thirty six percent happened about " + (thirtySixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Fifty percent happened about " + (fiftyPercent / Float.valueOf(iterations)) * 100 + "% of the time");
        }
    }
    

    输出:

    Testing percentage based random, 1000000 iterations
    One percent happened about 0.99649996% of the time
    Six percent happened about 4.9925% of the time
    Seven percent happened about 1.0029999% of the time
    Thirty six percent happened about 29.001299% of the time
    Fifty percent happened about 14.0191% of the time
    

    预期产出:

    Testing percentage based random, 1000000 iterations
    One percent happened about 0.99649996% of the time
    Six percent happened about 6.9925% of the time
    Seven percent happened about 7.0029999% of the time
    Thirty six percent happened about 36.001299% of the time
    Fifty percent happened about 50.0191% of the time
    

    我相信我需要使用某种算法将百分比转换为从0到99的范围,以便随机数生成器能够准确地选择一个值。不过,我想不出该怎么做。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Benoit Vanalderweireldt    9 年前

    您的结果是正确的:

    50%发生在14.0191%的时间

    50 - 36 = 14

    36%的时间发生在29.001299%的时间

    36 - 7 = 29

    7%发生在1.0029999%的时间

    7 - 6 = 1

    ....

    如果你想总结所有的“continue”语句,请删除它们。

        2
  •  -1
  •   Quantum64    9 年前

    想出来了。您需要跟踪到目前为止测试的百分比,并将其添加到当前测试中。

    import java.util.Random;
    
    public class Main {
    
        private static Random r = new Random();
    
        public static void main(String[] args) {
            final int iterations = 1000000;
            System.out.println("Testing percentage based random, " + iterations + " iterations");
            int onePercent = 0;
            int sixPercent = 0;
            int sevenPercent = 0;
            int thirtySixPercent = 0;
            int fiftyPercent = 0;
            // Those values add up to 100% overall
            for (int i = 0; i < iterations; i++) {
                int random = r.nextInt(100);
                int totalPercent = 0;
                if (random < totalPercent + 1) {
                    onePercent++;
                    continue;
                }
                totalPercent += 1;
                if (random < totalPercent + 6) {
                    sixPercent++;
                    continue;
                }
                totalPercent += 6;
                if (random < totalPercent + 7) {
                    sevenPercent++;
                    continue;
                }
                totalPercent += 7;
                if (random < totalPercent + 36) {
                    thirtySixPercent++;
                    continue;
                }
                totalPercent += 36;
                if (random < totalPercent + 50) {
                    fiftyPercent++;
                    continue;
                }
                totalPercent += 50;
                // That can't be right because if random > 50 then nothing at all happens
            }
            System.out.println("One percent happened about " + (onePercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Six percent happened about " + (sixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Seven percent happened about " + (sevenPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Thirty six percent happened about " + (thirtySixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
            System.out.println("Fifty percent happened about " + (fiftyPercent / Float.valueOf(iterations)) * 100 + "% of the time");
        }
    }