【问题标题】:Python define variable name and condition based on excel inputsPython根据excel输入定义变量名和条件
【发布时间】:2020-11-03 10:51:04
【问题描述】:

我正在处理 python 中的 LP 问题。

分配选择:

Type          Qty_Available   Cost  For_Protein    For_Carb
Protein_Can         50         10      TRUE          FALSE
Soup                15          8      FALSE         TRUE
EnergyDrink         10         15      TRUE          TRUE
            

数据框

StudentID   Age ProteinDef  CarbDef
A01         16      TRUE     TRUE
A02         17      FALSE    TRUE
A03         16      FALSE    FALSE
A04         18      TRUE     TRUE
A05         16      FALSE   TRUE
B01         18      FALSE   FALSE
B02         18      TRUE    TRUE
B03         20      FALSE   TRUE
B04         19      FALSE   FALSE
B05         19      TRUE    FALSE

我的代码运行良好。我面临的问题是分配选择每个月都会根据可用性而变化,并在 Excel 中提供。但是,我的代码是硬编码的(如下所示)

Protein_Can = pulp.LpVariable.dicts("Protein_Can", df.StudentID, pulp.LpBinary)
Soup= pulp.LpVariable.dictsSoupdf.StudentID, pulp.LpBinary)
EnergyDrink= pulp.LpVariable.dicts("EnergyDrink", df.StudentID, pulp.LpBinary)


cost[id] = Protein_Can[id] * Protein_Can_Cost + Soup[id] * Soup_Cost + EnergyDrink[id] * EnergyDrink_Cost 

for id in df.StudentID:
    if df.loc[id]['ProteinDef'] == TRUE:
        prob +=  Soup[id] <= 0
    if df.loc[id]['CarbDef'] == TRUE:
        prob +=  Protein_Can[id] <= 0

是否有可能确保根据 excel 输入自动定义变量的方法?不是硬编码方式?这样的代码可以动态化吗?

【问题讨论】:

    标签: python linear-programming pyomo pulp


    【解决方案1】:

    是的!

    你需要更好地利用集合。如果您有关于线性规划的文本或查看一些教程,您应该能够找到许多示例。您不应该直接将数据硬编码到您的公式中。可以从文件中读取数据或在数学模型之前单独开发数据,但不能在约束等的制定中。

    您上面的示例有 2 个主要集合,每个集合都有两个子集。 (以下为伪代码)

    主要集

    食物(或“分配选择”):

    Foods = {protein_can, soup, etc...}
    

    您可以将这些字符串名称用作集合成员,或者仅使用索引并跟踪与问题分开的索引列表中的名称

    学生:

    Students = {A01, A02, ... }
    

    子集

    上面的每个集合都有 2 个子集,与 proteincarbs 的关联。以食品为例:

    Foods_P = {Protein_can, energy_drink}  
    Foods_C = ...
    

    当你读入数据时,这些应该很容易设置,使用它们将使你的程序更简洁、更快。

    使用集合...

    之后,您只需要 2 个变量来处理食物:

    avail[food]
    cost[food]
    

    其中food 是集合Foods 的成员

    您的模型似乎是一个分配模型,您将一定数量的特定食物分配给特定学生,因此您应该有一些双索引决策变量:

    x[f, s]  # an integer/real number representing the assignment of x quantity of food f to student s
    

    约束和成本的类似结构应该到位...

    从 Excel 中读取。

    这里有几个选项...

    1. 使用 pandas 读取信息,这可能是矫枉过正,没有必要
    2. 使用直接的 Excel 界面,例如 openpyxl,这又是矫枉过正。
    3. 设置 Excel 文件后,将每个选项卡保存为单独的 .csv 文件(数据标准),然后让 python 读取 csv,这很简单。 (在 Excel 中使用“另存为”功能并选择 .csv ...忽略比尔盖茨的警告)

    您应该生成两个 csv,一个用于食物,一个用于学生。然后可以这样读取它们:

    # script to import csv files
    
    file_name = 'food.csv'
    
    qty_dict = {}
    cost_dict = {}
    foods = set()
    food_p = set()
    food_c = set()
    
    with open(file_name, 'r') as fin:
        fin.readline()  # read the header and discard it
        # process the rest
        for line in fin:
            data = line.strip().split(',')
            key = data[0]           # the type name
            qty = int(data[1])      # int conversion of qty
            cost = int(data[2])     # int conversion of cost
            qty_dict[key] = qty
            cost_dict[key] = cost
    
            # test the booleans, construct the sets
            if data[3].lower() == 'true':
                food_p.add(key)
            if data[4].lower() == 'true':
                food_c.add(key)
    
    print (cost_dict)
    print (food_p)
    
    
    # do same for students...
    
    # make pulp model
    
    # you probably have a decision variable X[f,s] which is probably something like:
    
    X = pulp.LpVariable.dicts("assign", [(f, s) for f in foods for s in students], cat='Binary')
    

    我没有安装pulp,所以最后一行是准确的,但未经测试。

    您应该能够使用在读入期间创建的字典和集合来设置约束和目标。

    Excel 中的食物快照:

    【讨论】:

    • 啊。好的。我以为您正在尝试弄清楚如何设置模型部分。所以第二个问题是关于如何从类似 Excel 的文件中提取。我会补充我的答案...
    • 太棒了....刚刚在阅读部分进行了快速编辑。我忽略了在那里放置一个循环来读取整个文件。固定。
    猜你喜欢
    • 2018-12-26
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2012-11-18
    相关资源
    最近更新 更多