0

我遇到了几个优化问题,涉及识别向量中的一个或多个索引以最大化或最小化成本。有没有办法在线性规划中识别这些索引?我对 、 、 或任何其他 API 中的解决方案持mathprog开放CVXR态度CVXPY

例如,对于变化点问题(找到函数发生变化的索引)需要确定一个索引,对旅行商问题(在累积距离 Y 之前访问城市 X)施加距离约束。

举个简单的例子,假设我们想要识别向量中任一侧的和最相等(它们的差最小)的位置。在此示例中,解决方案是索引 5:

x = c(1, 3, 6, 4, 7, 9, 6, 2, 3)

尝试 1

使用CVXR,我尝试声明split_index并将其用作索引(例如,x[1:split]):

library(CVXR)
split_index = Variable(1, integer = TRUE)
objective = Minimize(abs(sum(x[1:split_index]) - sum(x[(split_index+1):length(x)])))
result = solve(objective)

1:split_indexNA/NaN argument.

尝试 2

声明一个显式索引向量 ( indices) 并进行元素逻辑测试是否split_index <= indices. 然后将该二进制向量逐元素乘以x选择分割的一侧或另一侧:

indices = seq_along(x)
split_index = Variable(1, integer = TRUE)
is_first = split_index <= indices
objective = Minimize(abs(sum(x * is_first) - sum(x * !is_first)))
result = solve(objective)

x * is_firstnon-numeric argument to binary operator. 我怀疑这个错误的出现是因为is_first现在是一个IneqConstraint对象。

4

2 回答 2

3

在此处输入图像描述

红色符号是决策变量,蓝色符号是常数。

代码:

> library(Rglpk)
> library(CVXR)
> 
> x <- c(1, 3, 6, 4, 7, 9, 6, 2, 3)
> n <- length(x)
> delta <- Variable(n, boolean=T)
> y <- Variable(2)
> order <- list()
> for (i in 2:n) {
+     order[[as.character(i)]] <- delta[i-1] <= delta[i]
+ }
> 
> 
> problem <- Problem(Minimize(abs(y[1]-y[2])),
+                    c(order,
+                      y[1] == t(1-delta) %*% x,
+                      y[2] == t(delta) %*%x))
> result <- solve(problem,solver = "GLPK", verbose=T)
GLPK Simplex Optimizer, v4.47
30 rows, 12 columns, 60 non-zeros
      0: obj =  0.000000000e+000  infeas = 4.100e+001 (2)
*     7: obj =  0.000000000e+000  infeas = 0.000e+000 (0)
*     8: obj =  0.000000000e+000  infeas = 0.000e+000 (0)
OPTIMAL SOLUTION FOUND
GLPK Integer Optimizer, v4.47
30 rows, 12 columns, 60 non-zeros
9 integer variables, none of which are binary
Integer optimization begins...
+     8: mip =     not found yet >=              -inf        (1; 0)
+     9: >>>>>  1.000000000e+000 >=  0.000000000e+000 100.0% (2; 0)
+     9: mip =  1.000000000e+000 >=     tree is empty   0.0% (0; 3)
INTEGER OPTIMAL SOLUTION FOUND
> result$getValue(delta)
      [,1]
 [1,]    0
 [2,]    0
 [3,]    0
 [4,]    0
 [5,]    0
 [6,]    1
 [7,]    1
 [8,]    1
 [9,]    1
> result$getValue(y)
     [,1]
[1,]   21
[2,]   20
> 

绝对值由 CVXR 自动线性化。

于 2020-06-17T21:56:01.360 回答
1

归根结底,如果您按索引选择事物,我认为您需要使用一组相应的二进制选择变量来处理它。您在示例问题中选择“连续的事物”这一事实只是需要通过对二进制变量的约束来处理。

为了解决您提出的问题,我制作了一组二进制选择变量,将其称为s[i]wherei = {0, 1, 2, ..., len(x)}然后约束:

s[i] <= s[i-1] for i = {1, 2, ..., len(x)}

它强制执行从开始到第一次非选择以及之后的“连续性”。

我的解决方案是在 Python 中。LMK 如果你想让我发帖。我认为,上面的概念就是您要问的。

于 2020-06-17T21:07:05.253 回答