如何在集合中找到最大化与目标值的接近程度的数字组合

时间:2017-02-05 22:13:05

标签: r algorithm

我正在寻找一种解决方案,以便在更大的集合中找到尽可能接近目标数字的数字子集。例如,我有一组值:

   c(55.14, 26.22, 76.69, 37.77, 32.7, 48.71, 7.59, 21.37, 33.54, 3.95, 16.41, 
20.56, 24.74, 26.5, 4.72, 32.99, 130.15, 27.27, 20.56, 41.21, 13, 16.41, 88.25, 
1.95, 68.2, 34.3, 51.75, 8.93, 8.38, 30.45, 34.89, 42.91, 19.42, 13.62, 9.73, 
20.86, 21.5, 37.46, 14.4, 26.61, 55.31, 24.03)

我的目标是1262.2。

如何在完整集中找到最小化目标1262.2与子集之和之差的值的子集?

1 个答案:

答案 0 :(得分:6)

v成为问题中显示的值的向量。

x为包含0-1变量的相同长度的未知向量。

然后在x上运行这两个整数线性程序,从目标最接近1262.2的解决方案中选择解决方案。 (这里*表示内在产品。)

max(v*x) such that v*x <= 1262.2

min(v*x) such that v*x >= 1262.2

使用Rglpk作为第一个,我们得到了这个,因为我们完全达到1262.2,我们不需要打扰第二个整数线性程序:

library(Rglpk)

ans <- Rglpk_solve_LP(v, t(v), "<=", 1262.2, max = TRUE, types = "B")

,并提供:

> ans[1:3]
$optimum
[1] 1262.2

$solution
 [1] 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1

$status
[1] 0

注意第一个整数线性程序称为背包问题,我们可以使用adagio中的knapsack来解决它。

library(adadgio)

v100 <- as.integer(100 * v)
knapsack(v100, v100, 126220L)

(虽然在帮助页面上没有提到,背包需要整数参数。)