[英]How to use external data in the objective function in Python PuLP?
我想选择一个正方形矩阵的正方形固定大小的子集,以使子集矩阵的总和最小化。 一些代码:
import nump as np
import pulp
def subset_matrix(data, inds):
return data[np.ix_(inds, inds)]
A = np.random.random((10, 10))
indices = list(range(len(A)))
prob = pulp.LpProblem("Minimum subset", pulp.LpMaximize)
x = pulp.LpVariable.dicts('elem', indices, lowBound=0, upBound=1, cat=pulp.LpInteger)
prob += pulp.lpSum(subset_matrix(A, [x[i] for i in indices]))
prob.solve()
这失败了,因为numpy索引不喜欢inds
是LpVariables
的列表。 有没有解决的办法? 如何使纸浆约束包含numpy数组查找?
我不认为这是PuLP问题,不像是如何将数学问题恰当地表述为混合整数线性程序那样。
看起来您正在尝试将目标表示为要优化的一组索引上的系数之和(“子集矩阵之和”)。 (顺便说一句,我看不到子矩阵的大小约束写在哪里。)但是,MILP要求目标必须是在预定索引集上决策变量向量与成本系数向量的点积。 。 因此,在自然公式中,决策向量将使用二进制值来代表您选择的完整索引集中的哪些索引位于子矩阵中。
如果我了解您要执行的操作,这似乎是一个整洁的问题。 我相信您正在尝试选择索引I \\ subset {0,1,...,N-1}的固定大小的子集,以使sum {A(i,j):i,j都在I}中被最大化。 例如,假设大矩阵是10x10,而您想要一个6x6的子矩阵。 因此,我是{0,...,9}的六个元素。
然后,我将在{0,...,9}中为i,j定义变量x(i,j),对于为子矩阵选择的大矩阵的每个元素都等于一个(否则为零), y(i),i在{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)))
我猜这是一个带回家的考试问题。。。至少这个学期现在结束了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.