【问题标题】:Selecting a value proportionally based on its double key根据其双键按比例选择值
【发布时间】:2012-07-19 14:53:48
【问题描述】:

我有一个值列表,用 0 到 1 之间的双精度键表示我认为某事物对我有用的可能性。例如,获取问题的答案:

0.5   call your mom
0.25  go to the library
0.6   StackOverflow
0.9   just Google it

因此,我们认为在谷歌上搜索它的帮助可能是询问您妈妈的(大约)两倍。当我试图找出下一步要做的事情时,我希望“只是谷歌它”的返回频率大约是“打电话给你妈妈”的两倍。

我一直在寻找解决方案,但收效甚微。我发现的大多数东西都依赖于整数键(如How to randomly select a key based on its Integer value in a Map with respect to the other values in O(n) time?),而我没有,也不容易生成。

我觉得应该有一些 Java 数据类型可以为我做到这一点。有什么建议么?

【问题讨论】:

  • 当您拥有double 值时,您链接到的答案适用;它不是特定于整数的。
  • 我认为情况并非如此。考虑行int index = this.rand.nextInt(this.sum) + 1;Random 包没有在 0 和给定最大值之间生成 doubles 的等效函数。此外,在总和中加 1 显然是不正确的 - 但不清楚我会在总和中添加什么常数以确保可以选择最大权重元素。
  • rand.nextDouble()相乘,不要加任何东西。

标签: java types random-access


【解决方案1】:

你可以想到一个基于java接口NavigableMap的解决方案,如果你使用TreeMap实现你总是会得到O(logn)的复杂度。

您可以使用以下方法之一:

  • lowerEntry
  • 天花板入口
  • 楼层入口
  • 更高的条目

现在您只需要以正确的概率提取随机数。为此,我会参考这篇文章:

How to generate a random number from specified discrete distribution?

【讨论】:

    【解决方案2】:

    如果我理解正确,您正在寻找的是加权随机数。
    您应该将所有权重相加,并可能将其归一化为整数值,这样您就可以按照 cmets 的建议使用 rand.nextInt。
    例如,可以通过乘以 100 来进行归一化,因此您的归一化权重现在是:
    50, 25, 60, 90 - 总和为 225。
    您应该定义范围:
    0 - 49 表示“打电话给你妈妈”
    50 - 74 - 用于“去图书馆”

    现在您需要执行 this.rand.nextInt(sum) - 并获得一个值,
    并且该值应映射到定义的范围之一。

    【讨论】:

      【解决方案3】:

      如果您跟踪概率的总值,您可以执行以下操作:

      double interval = 100;
      double counter = 0;
      double totalProbabilities = 2.25;
      int randInt = new Random().nextInt((int)interval);
      for (Element e: list) {
        counter += (interval * e.probability() / totalProbabilities);
        if (randInt < counter) {
          return e.activity();
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-03
        • 2022-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多