我不认为这是一个纸浆问题,而是如何将数学问题正确地表述为混合整数线性程序的问题。
您似乎正试图将您的目标表达为系数的总和(“子集矩阵的总和”),在一组要优化的索引上。 (顺便说一句,我看不到子矩阵的大小约束写在哪里。)但是 MILP 要求目标是决策变量向量与成本系数向量在预定索引集上的点积.因此,在自然公式中,决策向量将使用二进制值表示您选择的完整索引集中的哪些索引在您的子矩阵中。
如果我理解您想要做什么,这似乎是一个很好的问题。我相信你正在尝试选择一个固定大小的索引子集 I \subset {0, 1, ..., N-1},这样 sum{A(i,j): i,j both in I}被最大化。例如,假设大矩阵是 10x10,而您想要一个 6x6 的子矩阵。所以我是 {0, ..., 9} 的大约六个元素。
然后我会在 {0, ..., 9} 中为 i, j 定义变量 x(i,j),对于为子矩阵选择的大矩阵的每个元素都等于 1(否则为零) , 和变量 y(i), i in {0, ..., 9},用于选择的索引。然后我会尝试将这些约束表示为线性的,并使 y 变量二进制来表示每个索引是进还是出。
这是我认为您的意思的表述:
import pulp as pp
import numpy as np
import itertools
#####################
# Problem Data: #
#####################
full_matrix_size = 10
submatrix_size = 6
A = np.random.random((full_matrix_size, full_matrix_size)).round(2)
inds = range(full_matrix_size)
product_inds = list(itertools.product(inds,inds))
#####################
# Variables: #
#####################
# x[(i,j)] = 1 if the (i,j)th element of the data matrix is in the submatrix, 0 otherwise.
x = pp.LpVariable.dicts('x', product_inds, cat='Continuous', lowBound=0, upBound=1)
# y[i] = 1 if i is in the selected index set, 0 otherwise.
y = pp.LpVariable.dicts('y', inds, cat='Binary')
prob = pp.LpProblem("submatrix_problem", pp.LpMaximize)
#####################
# Constraints: #
#####################
# The following constraints express the required submatrix shape:
for (i,j) in product_inds:
# x[(i,j)] must be 1 if y[i] and y[j] are both in the selected index set.
prob += pp.LpConstraint(e=x[(i,j)] - y[i] - y[j], sense=1, rhs=-1,
name="true_if_both_%s_%s" % (i,j))
# x[(i,j)] must be 0 if y[i] is not in the selected index set.
prob += pp.LpConstraint(e=x[(i,j)] - y[i], sense=-1, rhs=0,
name="false_if_not_row_%s_%s" % (i,j))
# x[(i,j)] must be 0 if y[j] is not in the selected index set.
prob += pp.LpConstraint(e=x[(i,j)] - y[j], sense=-1, rhs=0,
name="false_if_not_col_%s_%s" % (i,j))
# The number of selected indices must be what we require:
prob += pp.LpConstraint(e=pp.LpAffineExpression([(y[i],1) for i in inds]), sense=0,
rhs=submatrix_size, name="submatrix_size")
#####################
# Objective: #
#####################
prob += pp.LpAffineExpression([(x[pair], A[pair]) for pair in product_inds])
print(prob)
########################
# Create the problem: #
########################
prob.writeLP("max_sum_submatrix.lp")
prob.solve()
##########################
# Display the solution: #
##########################
print("The following indices were selected:")
print([v.name for v in prob.variables() if v.name[0]=='y' and v.varValue==1])
print("Objective value is " + str(pp.value(prob.objective)))
我猜那是带回家的考试题……至少这个学期已经结束了。