Python 根据 excel 输入定义变量名称和条件

Python define variable name and condition based on excel inputs

我正在 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 输入自动定义的?不是硬编码方式?这样的代码可以动态化吗?

是的!

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

上面的示例有 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 和 select .csv 中使用“另存为”功能...忽略比尔盖茨的警告)

你应该制作两份 csvs,一份用于食物,一份用于学生。然后它们可以这样读:

# 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,所以最后一行是准确的,但没有经过测试。

您应该能够使用读入期间创建的词典和集设置约束和 objective。

Excel中的食物快照: