【问题标题】:Generate combinations of values which sum to one, sorted in descending order生成总和为 1 的值组合,按降序排序
【发布时间】:2015-07-29 02:59:19
【问题描述】:

您是否知道一种更有效的方法来生成包含所有“权重”唯一组合的矩阵(让权重为 w 和 0

这是完成这项工作的代码,但删除行似乎效率低:

# generate combinations of weights such that w1 >= w2 >= w3 ...
w = seq(0, 1, 0.1) #weights 0, 0.1, ..., 0.9, 1
w = expand.grid(w, w, w, KEEP.OUT.ATTRS = FALSE) #all combinations of 3 weights
w = w[rowSums(w) == 1, ] #make sure the weights sum to one
w = w[!(w[, 1] < w[, 2] | w[, 2] < w[, 3]),] #make sure w1 >= w2 >= w3 ...

w    
#     Var1 Var2 Var3
# 11   1.0  0.0  0.0
# 21   0.9  0.1  0.0
# 31   0.8  0.2  0.0
# 41   0.7  0.3  0.0
# 51   0.6  0.4  0.0
# 61   0.5  0.5  0.0
# 141  0.8  0.1  0.1
# 151  0.7  0.2  0.1
# 171  0.5  0.4  0.1
# 271  0.6  0.2  0.2
# 281  0.5  0.3  0.2
# 291  0.4  0.4  0.2
# 401  0.4  0.3  0.3

让我添加一些更一般的信息: 在本题中(3个权重按上述顺序),第一、二、三值的上限如下:

  • 对于组合 (1, 0, 0),第一个数字至少可以是 1
  • 对于组合 (1/2, 1/2, 0),第二个数字最大可以是 1/2
  • 对于组合 (1/3, 1/3, 1/3),第三个数字最大可以是 1/3

【问题讨论】:

  • 在示例输出中,您显示的权重总和不为 1 ...从您的代码中,我假设它们应该总和为 &lt;= 1。如果是这种情况,您应该编辑您的问题。
  • 最后的三个点也是多余的,因为它们遵循每行中的第一个元素必须是最大的要求。
  • @user2706569 编辑了问题,是一个错字。
  • @Seamus O'Baired:你的评论在逻辑上是正确的,当然!但一个好的问题不一定是最不多余的问题,对吧?这是最清楚的问题。因此,我认为,解释事情比最不冗余更重要。
  • 您期望这些变量的分布如何?

标签: r


【解决方案1】:

base 的可能性:

library(partitions)

step <- 0.1
n_weights <- 3

t(restrictedparts(n = 1/step, m = n_weights) * step)
#  [1,] 1.0 0.0 0.0
#  [2,] 0.9 0.1 0.0
#  [3,] 0.8 0.2 0.0
#  [4,] 0.7 0.3 0.0
#  [5,] 0.6 0.4 0.0
#  [6,] 0.5 0.5 0.0
#  [7,] 0.8 0.1 0.1
#  [8,] 0.7 0.2 0.1
#  [9,] 0.6 0.3 0.1
# [10,] 0.5 0.4 0.1
# [11,] 0.6 0.2 0.2
# [12,] 0.5 0.3 0.2
# [13,] 0.4 0.4 0.2
# [14,] 0.4 0.3 0.3

【讨论】:

    【解决方案2】:

    标准包的通用功能:

    # Generate weights matrix with noWeights columns and noRows rows.
    # Each row of this matrix contains sorted decremental weights summing up to 1.0.
    generateWeights = function(noWeights,
                               noRows,
                               distribution = runif,
                               rounding = function(x){ round(x, 1) })
    {
      generator = function()
      {
        x = distribution (noWeights);
        x = x/sum(x);
        sort(rounding(x), decreasing = T)
      } 
      t(replicate(noRows, generator()))
    }
    
    # example of use
    generateWeights(3, 10)
    

    【讨论】:

    • 在运行之前需要进行大量调整......
    • “rows”和“cols”在哪里定义?为什么没有使用“noWeights”和“noRows”? “gen”应该等于“generateWeights”吗?
    • 对此感到抱歉。固定。
    • 在这种情况下,“genarateWeights(3,10) 只产生 13 个三元组中的 10 个。
    • 我想我没有得到你的最后一个 cmets。
    猜你喜欢
    • 2019-03-07
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多