Python 纸浆:最小化一组向量的最大值
我想解决一个线性规划问题,它的所有数据都来自一个表 该表的大小(m*n)如下所示:Python 纸浆:最小化一组向量的最大值,python,mathematical-optimization,linear-programming,pulp,Python,Mathematical Optimization,Linear Programming,Pulp,我想解决一个线性规划问题,它的所有数据都来自一个表 该表的大小(m*n)如下所示: | c0 c1 c2 c3 ... cn sum --- + ------ + ------ + ------ + ------ + ------ + ------ +++ ----- + r0 | ||| Σ r0 r1
| c0 c1 c2 c3 ... cn sum
--- + ------ + ------ + ------ + ------ + ------ + ------ +++ ----- +
r0 | ||| Σ r0
r1 | ||| Σ r1
r2 | ||| Σ r2
r3 | ||| Σ r3
r4 | |||
. | |||
. | |||
. | |||
rm | ||| Σ rm
------------------------------------------------------------------- +
max |max(c0) max(c1) max(c2) max(c3) max(cn) ||| Σ max(c0...n)
pulp.LpVariable("Max___{}".format(s),
lowBound=max([v.value() for v in column]),
upBound=max([v.value() for v in column]),
cat=pulp.LpContinuous
)
当问题得到优化时,此表中的所有箱子都将保留一个浮点值
我试图最小化每列的最大值之和(∑max(c0…n))
我创建了一个LpProblem
:
problem = pulp.LpProblem("problem",pulp.LpMinimize)
我已经创建了表示表中每个箱子的LpVariables
:
variables = pulp.LpVariable.dicts("bin",
((r,c) for r in rows for c in columns),
lowBound=0,
cat='Continuous')
我事先知道每行的和(∑rx),约束条件是一行x的值必须和∑rx。作为这些数据的一个特征,一行中只有一个子集的索引可以产生这个∑rx值。例如,只有第0行中的存储箱(0,1)和(0,3)可能具有非零值。这些贡献箱的索引因行而异;某些行可能只有一个贡献箱,而其他行可能有多个(或全部)贡献箱。我通过为每一行创建约束来说明这一点
for row in rows:
column_set # a list of bin indexes for this row that make up the sum.
variable_set = [ variables[(row,c)] for c in column_set ]
problem += pulp.lpSum(variable_set) == row_sum # the sum of the row.
我的问题在于如何定义我的目标函数。由于python的max()
不适用于LpVariable
对象,因此我试图考虑如何获取任何列的最大值,并将其分配给自己的LpVariable
对象
一种方法是循环遍历给定列中表示容器的每个LpVariable
,执行类似v=variable.value()
的操作,将所有v
添加到列表中,然后在此列表上执行max()
,并将LpVariable
设置为该值,但这仅获取LpVariable
s的初始值,当解算器在solve()
过程中更改数据时,这些最大值将不会动态更新
我还尝试过创建单独的LpVariable
s来表示每列的最大值,设置如下:
| c0 c1 c2 c3 ... cn sum
--- + ------ + ------ + ------ + ------ + ------ + ------ +++ ----- +
r0 | ||| Σ r0
r1 | ||| Σ r1
r2 | ||| Σ r2
r3 | ||| Σ r3
r4 | |||
. | |||
. | |||
. | |||
rm | ||| Σ rm
------------------------------------------------------------------- +
max |max(c0) max(c1) max(c2) max(c3) max(cn) ||| Σ max(c0...n)
pulp.LpVariable("Max___{}".format(s),
lowBound=max([v.value() for v in column]),
upBound=max([v.value() for v in column]),
cat=pulp.LpContinuous
)
但同样,这似乎只是从每个LpVariable
的初始条件中获取值,并在此基础上运行solve()
,返回一个不可行的解决方案
有什么建议吗?A高层描述:
m行,n列
- 引入
n
新的连续变量m_0,m_1,…,m_(n-1)
- 添加
m*n
表单的新约束:
m\u 0>=条目(r\u 0,c\u 0)
m\u 0>=条目(r\u 1,c\u 0)
m\u 0>=条目(r\u(m-1),c\u 0)
m\u 1>=条目(r\u 0,c\u 1)
m\u 1>=条目(r\u 1,c\u 1)
m\u 1>=条目(r\u(m-1),c\u 1)
- 目标:
最小化(m_0+m_1+…+m_(n-1))
备注:
- 仅当解算器以某种方式向下推动每个m时,此操作才有效!
- 这里:最小化总和->确定李>
- 它独立于条目的类型(二进制、整数、连续)
通过定义一组2成员元组(表中可能的非零项的行-列索引),您可以更轻松地处理此问题的稀疏性
要处理每个列中的max条目,请引入@sascha提到的新决策变量和约束
例如:
"""
Example where the table is 2x2, and any entries can be non-zero except the (2,1) entry
"""
import pulp
# Define the sparse set of row-column indexes for entries that can be non-zero
rowCols = set([(1, 1),
(1, 2),
(2, 2)])
# Define row sums
rowSums = {1: 1.1,
2: 3.4}
# Detect the rows and columns of the table
rows = set([row for (row, _) in rowCols])
cols = set([col for (_, col) in rowCols])
# Define the PuLP model
problem = pulp.LpProblem("problem", pulp.LpMinimize)
# Define the variables
variables = pulp.LpVariable.dicts("bin", rowCols, lowBound=0,
cat=pulp.LpContinuous)
colMaxes = pulp.LpVariable.dicts("maximum entry in the column", cols,
lowBound=0, cat=pulp.LpContinuous)
# Define the constraints
# row sum
for row in rows:
problem += (
pulp.lpSum([variables[row, col]
for col in cols
if (row, col) in rowCols])
==
rowSums[row]
)
# max in column
for (row, col) in rowCols:
problem += (
pulp.lpSum([variables[row1, col1]
for (row1, col1) in rowCols
if col1 == col])
<=
colMaxes[col]
)
# Define objective function
problem += pulp.lpSum([colMaxes[col] for col in cols])
# Solve the problem
problem.solve()
# Print the solution
print('row col value')
for (row, col) in rowCols:
print(row, col, variables[row, col].varValue)
“”“
示例,其中表为2x2,除(2,1)项外,任何项都可以为非零
"""
进口纸浆
#为非零的条目定义行-列索引的稀疏集
rowCols=set([(1,1),
(1, 2),
(2, 2)])
#定义行和
行和={1:1.1,
2: 3.4}
#检测表的行和列
行=设置([行中的(行,))行])
cols=set([col for(u,col)在rowCols中])
#定义纸浆模型
问题=纸浆.LpProblem(“问题”,纸浆.LpProblem)
#定义变量
variables=pill.LpVariable.dicts(“bin”,rowCols,lowBound=0,
cat=纸浆(连续)
colMaxes=pill.LpVariable.dicts(“列中的最大条目”),cols,
下限=0,类别=纸浆。LPC(连续)
#定义约束条件
#行和
对于行中的行:
问题+=(
lpSum([变量[行,列]
为col的col
如果(行,列)在rowCols中])
==
行和[行]
)
#列中最大值
对于rowCols中的(行,列):
问题+=(
lpSum([变量[row1,col1]
对于rowCols中的(第1行,第1列)
如果col1==col])