使用 LpVariable.dicts 设置不同的变量类型和范围
Setting different variable types and bounds using LpVariable.dicts
我有一个线性规划问题,在这个问题中,我试图找到最佳投资组合,以在预算约束下最大化净现值。大多数这些投资决策是整数 (0/1),但其中一些可以部分资助(在 0 和 1 之间连续)。我在 python 中使用 PuLP,并将决策设置为字典变量 x,而不是让每个变量的决策对应一个不同的变量。我不确定如何使用 LpVariable.dicts 将类别分配给 x,以便整数变量的类别是整数,部分可资助变量的类别是连续的。
我有一个字典 Integer/Continuous 字符串保存为变量 'types' 和一个包含字典键的变量 'items'。
# Define dictionary keys
gc1=dict(zip(data['Investment ID'], data['Cost']))
items = list(gc1.keys())
# Define variable types
types=dict(zip(data['Investment ID'], np.where(data['Partial']==1, 'Continuous', 'Integer')))
# Define lp variable
x = LpVariable.dicts('x', items, lowBound=0, upBound=1, cat=types)
优化运行成功,但是一些应该是整数 (0/1) 的决策是连续的。
据我所知,LpVariable.dicts()
方法只能接受一个类别 - 即它可用于生成所有类型相同的变量字典。
您的选择是创建 2 个列表 - 一个连续列表和一个整数变量列表,然后使用 LpVariable.dicts()
方法 - 或者如下所示,一次只实例化一个变量,这仍然非常容易使用 python 列表理解。如您所见,所有整数变量都是 1 或 0。
from pulp import *
import numpy as np
n_vars = 6
np.random.seed(0)
# Define some variable names and types
var_names = ['var_' + str(i) for i in range(n_vars)]
Partial = np.random.randint(2, size=n_vars)
types = np.where(Partial==1, 'Continuous', 'Integer')
# Create some returns
returns = np.random.rand(n_vars)
# Create some costs
costs = np.random.rand(n_vars)
# Allocate a budget
budget = 2.0
# Create list of contiuous variables
x_cont = [LpVariable(i, lowBound=0, upBound=1, cat=j) for i, j in zip(var_names, types)]
# Do an optimisation to check its worked:
prob = LpProblem("Mixed Problem", LpMaximize)
prob += lpSum([x_cont[i]*returns[i] for i in range(n_vars)])
prob += lpSum([x_cont[i]*costs[i] for i in range(n_vars)]) <= budget
prob.solve()
x_soln = np.array([x_cont[i].varValue for i in range(n_vars)])
print("costs: ", costs)
print("returns: ", returns)
print("types: ", types)
print("x_soln: ", x_soln)
输出:
costs: [0.38344152 0.79172504 0.52889492 0.56804456 0.92559664 0.07103606]
returns: [0.54488318 0.4236548 0.64589411 0.43758721 0.891773 0.96366276]
types: ['Integer' 'Continuous' 'Continuous' 'Integer' 'Continuous' 'Continuous']
x_soln: [1. 0.11497788 1. 0. 1. 1. ]
谢谢@kabdulla!我还找到了另一种方法,您首先在 LpVariable 中设置一个类别,然后为变量的每个元素定义类别:
# Define dictionary keys
gc1=dict(zip(data['Investment ID'], data['Cost']))
items = list(gc1.keys())
# Define variable types
types=dict(zip(data['Investment ID'], np.where(data['Partial']==1, 'Continuous', 'Integer')))
# Define lp variable
x = LpVariable.dicts('x', items, lowBound=0, upBound=1, cat='Integer')
for i in items:
x[i].cat=types[i]
我有一个线性规划问题,在这个问题中,我试图找到最佳投资组合,以在预算约束下最大化净现值。大多数这些投资决策是整数 (0/1),但其中一些可以部分资助(在 0 和 1 之间连续)。我在 python 中使用 PuLP,并将决策设置为字典变量 x,而不是让每个变量的决策对应一个不同的变量。我不确定如何使用 LpVariable.dicts 将类别分配给 x,以便整数变量的类别是整数,部分可资助变量的类别是连续的。
我有一个字典 Integer/Continuous 字符串保存为变量 'types' 和一个包含字典键的变量 'items'。
# Define dictionary keys
gc1=dict(zip(data['Investment ID'], data['Cost']))
items = list(gc1.keys())
# Define variable types
types=dict(zip(data['Investment ID'], np.where(data['Partial']==1, 'Continuous', 'Integer')))
# Define lp variable
x = LpVariable.dicts('x', items, lowBound=0, upBound=1, cat=types)
优化运行成功,但是一些应该是整数 (0/1) 的决策是连续的。
据我所知,LpVariable.dicts()
方法只能接受一个类别 - 即它可用于生成所有类型相同的变量字典。
您的选择是创建 2 个列表 - 一个连续列表和一个整数变量列表,然后使用 LpVariable.dicts()
方法 - 或者如下所示,一次只实例化一个变量,这仍然非常容易使用 python 列表理解。如您所见,所有整数变量都是 1 或 0。
from pulp import *
import numpy as np
n_vars = 6
np.random.seed(0)
# Define some variable names and types
var_names = ['var_' + str(i) for i in range(n_vars)]
Partial = np.random.randint(2, size=n_vars)
types = np.where(Partial==1, 'Continuous', 'Integer')
# Create some returns
returns = np.random.rand(n_vars)
# Create some costs
costs = np.random.rand(n_vars)
# Allocate a budget
budget = 2.0
# Create list of contiuous variables
x_cont = [LpVariable(i, lowBound=0, upBound=1, cat=j) for i, j in zip(var_names, types)]
# Do an optimisation to check its worked:
prob = LpProblem("Mixed Problem", LpMaximize)
prob += lpSum([x_cont[i]*returns[i] for i in range(n_vars)])
prob += lpSum([x_cont[i]*costs[i] for i in range(n_vars)]) <= budget
prob.solve()
x_soln = np.array([x_cont[i].varValue for i in range(n_vars)])
print("costs: ", costs)
print("returns: ", returns)
print("types: ", types)
print("x_soln: ", x_soln)
输出:
costs: [0.38344152 0.79172504 0.52889492 0.56804456 0.92559664 0.07103606]
returns: [0.54488318 0.4236548 0.64589411 0.43758721 0.891773 0.96366276]
types: ['Integer' 'Continuous' 'Continuous' 'Integer' 'Continuous' 'Continuous']
x_soln: [1. 0.11497788 1. 0. 1. 1. ]
谢谢@kabdulla!我还找到了另一种方法,您首先在 LpVariable 中设置一个类别,然后为变量的每个元素定义类别:
# Define dictionary keys
gc1=dict(zip(data['Investment ID'], data['Cost']))
items = list(gc1.keys())
# Define variable types
types=dict(zip(data['Investment ID'], np.where(data['Partial']==1, 'Continuous', 'Integer')))
# Define lp variable
x = LpVariable.dicts('x', items, lowBound=0, upBound=1, cat='Integer')
for i in items:
x[i].cat=types[i]