R中的舍入公平优化
Rounding fairness optimization in R
我有一个简单的问题,想知道是否有聪明的解决方案而不是粗略的计算。
给定以下总和为 350 的向量 A <- c(30,20,150,50,30,70)
,我需要向元素分配(添加)5 个额外的单位,从而产生总和 355。
我只能进行整数调整。我希望分配这 5 个单位,以最小化调整后元素的最大百分比变化。也就是说,从这个意义上说,我希望每个元素的调整都是 "fairest"。例如,添加向量
c(0,0,3,0,0,2)
产生一个 "new" A (A.New) of: 30 20 153 50 30 72
每个元素的百分比变化(从 A 到 A.New)是:
0.000000 0.000000 2.000000 0.000000 0.000000 2.857143
最大变化 2.857143
再次评估调整
c(0,0,4,0,0,1)
产生的 A.New 为 30 20 154 50 30 71
和百分比变化
0.000000 0.000000 2.666667 0.000000 0.000000 1.428571
最大百分比变化为 2.666667
因此 c(0,0,4,0,0,1)
将是首选(但还不是最佳选择。)
c(0,0,3,1,0,1)
的调整会产生元素的最小最大百分比变化,即 2.000000。这似乎是最佳解决方案。
关于重复元素值(关系)的情况,或者实际上所有元素值相同的情况表明我可能需要随机化调整的分布,或者包括一个次要标准来指导如何最好地分布,这只是野兽的本性,给定了限制。但我必须将这些作为特殊情况处理。例如,一种想法是在求解之前随机抖动 A 中的重复值,然后在最后消除抖动。但是,这不是主要问题。
我一直在考虑使用 lpSolve
作为潜在的解决方案,但是 objective 函数作为 "the min of a max of values" 是有问题的。
我可以为此创建一个自定义且可能很复杂的算法,但也许我忽略了更简单的方法来解决这个问题?
(请注意,在现实中,被调整的矢量可能有数百个元素。)
这是一种使用百分比增长矩阵的方法。我已经将它放入一个函数中,该函数接受一个向量 'x' 和您希望添加的整数个数 'N'(有关解释,请参阅评论)。
Allocate_Int <- function (x,N) { # x is vector, N = Number of Integers
p <- 100/x # Percentage increase by 1
m <- p %o% c(1:N) # create a matrix of increased percentage
m1 <- m <= m[order(m)][N] # find the N-th lowest numbers in T/F matrix
return(rowSums(m1)) # and return the nr of TRUE values per item.
}
它适用于您问题中的示例:
A <- c(30,20,150,50,30,70)
Allocate_Int(A,5)
[1] 0 0 3 1 0 1
如果有关系,则返回向量有很多值:
Allocate_Int(c(1,1),3)
[1] 2 2
如果要查找领带,请使用:
vec1 <- c(10,20,20,50,100)
N <- 10
Allocate_Int(vec1,N)-Allocate_Int(vec1,N-1)
[1] 0 0 0 1 1
我有一个简单的问题,想知道是否有聪明的解决方案而不是粗略的计算。
给定以下总和为 350 的向量 A <- c(30,20,150,50,30,70)
,我需要向元素分配(添加)5 个额外的单位,从而产生总和 355。
我只能进行整数调整。我希望分配这 5 个单位,以最小化调整后元素的最大百分比变化。也就是说,从这个意义上说,我希望每个元素的调整都是 "fairest"。例如,添加向量
c(0,0,3,0,0,2)
产生一个 "new" A (A.New) of: 30 20 153 50 30 72
每个元素的百分比变化(从 A 到 A.New)是: 0.000000 0.000000 2.000000 0.000000 0.000000 2.857143 最大变化 2.857143
再次评估调整
c(0,0,4,0,0,1)
产生的 A.New 为 30 20 154 50 30 71
和百分比变化
0.000000 0.000000 2.666667 0.000000 0.000000 1.428571
最大百分比变化为 2.666667
因此 c(0,0,4,0,0,1)
将是首选(但还不是最佳选择。)
c(0,0,3,1,0,1)
的调整会产生元素的最小最大百分比变化,即 2.000000。这似乎是最佳解决方案。
关于重复元素值(关系)的情况,或者实际上所有元素值相同的情况表明我可能需要随机化调整的分布,或者包括一个次要标准来指导如何最好地分布,这只是野兽的本性,给定了限制。但我必须将这些作为特殊情况处理。例如,一种想法是在求解之前随机抖动 A 中的重复值,然后在最后消除抖动。但是,这不是主要问题。
我一直在考虑使用 lpSolve
作为潜在的解决方案,但是 objective 函数作为 "the min of a max of values" 是有问题的。
我可以为此创建一个自定义且可能很复杂的算法,但也许我忽略了更简单的方法来解决这个问题?
(请注意,在现实中,被调整的矢量可能有数百个元素。)
这是一种使用百分比增长矩阵的方法。我已经将它放入一个函数中,该函数接受一个向量 'x' 和您希望添加的整数个数 'N'(有关解释,请参阅评论)。
Allocate_Int <- function (x,N) { # x is vector, N = Number of Integers
p <- 100/x # Percentage increase by 1
m <- p %o% c(1:N) # create a matrix of increased percentage
m1 <- m <= m[order(m)][N] # find the N-th lowest numbers in T/F matrix
return(rowSums(m1)) # and return the nr of TRUE values per item.
}
它适用于您问题中的示例:
A <- c(30,20,150,50,30,70)
Allocate_Int(A,5)
[1] 0 0 3 1 0 1
如果有关系,则返回向量有很多值:
Allocate_Int(c(1,1),3)
[1] 2 2
如果要查找领带,请使用:
vec1 <- c(10,20,20,50,100)
N <- 10
Allocate_Int(vec1,N)-Allocate_Int(vec1,N-1)
[1] 0 0 0 1 1