按照我的理解总结您的问题设置(在您不能多次除以二的约束下):
- 添加
A 和B 任意次数(包括每个0)
- 除以 2,四舍五入
- 随意添加
A和B
目标是获得最大可能的总和,条件是在算法的任何一步之后总和不超过T。
这可以在一个 5 变量整数程序中巧妙地捕捉到。这五个变量是:
-
a1:除以2之前我们加A的次数
-
b1:除以2之前我们加B的次数
-
s1:floor((A*a1+B*b1)/2),第二步后的总和
-
a2:除以2后我们添加A的次数
-
b2:除以2后我们加上B的次数
最终总和为s1+A*a2+B*b2,约束不超过T;这是我们寻求最大化的。所有五个决策变量都必须是非负整数。
这个整数程序可以很容易地通过整数规划求解器求解到最优。例如,这里是你将如何使用 R 中的 lpSolve 包解决它:
library(lpSolve)
get.vals <- function(A, B, T) {
sol <- lp(direction = "max",
objective.in = c(0, 0, 1, A, B),
const.mat = rbind(c(A, B, 0, 0, 0), c(0, 0, 1, A, B), c(-A, -B, 2, 0, 0), c(-A, -B, 2, 0, 0)),
const.dir = c("<=", "<=", "<=", ">="),
const.rhs = c(T, T, 0, -1),
all.int = TRUE)$solution
print(paste("Add", A, "a total of", sol[1], "times and add", B, "a total of", sol[2], "times for sum", A*sol[1]+B*sol[2]))
print(paste("Divide by 2, yielding value", sol[3]))
print(paste("Add", A, "a total of", sol[4], "times and add", B, "a total of", sol[5], "times for sum", sol[3]+A*sol[4]+B*sol[5]))
}
现在我们可以计算如何在不超过 T 的情况下获得尽可能高的总和:
get.vals(5, 6, 8)
# [1] "Add 5 a total of 1 times and add 6 a total of 0 times for sum 5"
# [1] "Divide by 2, yielding value 2"
# [1] "Add 5 a total of 0 times and add 6 a total of 1 times for sum 8"
get.vals(17, 46, 5000000)
# [1] "Add 17 a total of 93 times and add 46 a total of 0 times for sum 1581"
# [1] "Divide by 2, yielding value 790"
# [1] "Add 17 a total of 294063 times and add 46 a total of 3 times for sum 4999999"