使用Python在多种条件下优化牛饲料成分

问题描述 投票:0回答:1

我有一个数据框

df1
代表
different ingredients
(Maize, Jowar, Bajara Rice_Broken Wheat)
用于牛饲料,每个都有相关的成本
nutritional parameters
(ME_Kcal_per_Kg,  C_Protein,  C_Fat and   Chloride)
重量代表分配的重量,以保持不同的比例成分。

      Item    Cost   Weight   ME_Kcal_per_Kg  C_Protein  C_Fat   Chloride  Ingredients_constraints_Min  Ingredients_constraints_Max
      Maize    60       1            3.30        9.0      4.0      0.04                            0                           60
      Jowar    42     0.7            3.00       10.0      3.0      0.10                            0                           30
     Bajara    20       1            2.64       12.7      4.9      0.00                            0                           30
Rice_Broken     9       1            2.60        7.9      1.7      0.00                            0                           40
      Wheat    24       1            3.10       14.0      2.6      0.05                            0                           20

另一个数据框

df2
定义了牛饲料的营养限制

Nutrients_Limits  ME_Kcal_per_Kg  C_Protein   C_Fat   Chloride
             Min            2.78        26.5       5       0.3
             Max            2.90        28.0       7       0.5

目标是找到 df1 中的成分组合,最大限度地降低成本,同时满足 df2 中定义的营养限制。

条件是:

1。每种成分的数量不应超过 df1 中 Ingredients_constraints_Max 列中指定的值。

2。每种成分的数量不应低于 df1 中 Ingredients_constraints_Min 列中指定的值。

3.不同成分的组合总共不得超过100种。

4。营养参数(体重、ME_Kcal_per_Kg、C_Protein、C_Fat、Chloride)应符合 df2 中规定的限值。

第一个条件的代码片段在这里,无法集成第二个条件。

import numpy as np
from scipy.optimize import linprog

# Extracting relevant data from the DataFrame
costs = df1['Cost'].values
constraints_min = df1['Ingredients_constraints_Min'].values
constraints_max = df1['Ingredients_constraints_Max'].values

# Coefficients for the linear programming problem
c = costs
A_eq = np.ones((1, len(costs)))
b_eq = np.array([100])

# Bounds for each ingredient quantity
bounds = [(constraints_min[i], constraints_max[i]) for i in range(len(costs))]

# Solving the linear programming problem
result = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

# Extracting the solution
solution_quantities = result.x

# Displaying the results
for i, item in enumerate(df1['Item']):
    print(f"{item}: {solution_quantities[i]}")

print(f"Total Cost: {result.fun}")

如何找到在满足这些营养限制的同时最大限度地降低成本的成分组合?任何帮助将不胜感激。

python pandas optimization scipy data-science
1个回答
0
投票

由于这是实际问题的子集,因此该子集可能不可行。也就是说,我相信我即将确定的代码会起作用,尽管我无法测试它。

对于营养素,您需要创建

A_ub
b_ub
来定义营养素值的上限和下限。上限很简单,您只需在
A_ub
中设置营养值,在
b_ub
中设置最大值。对于下界,由于我们有小于或等于约束,因此我们必须对所有项取负,以便它应用大于或等于约束。

你还说成分限制不超过100,这让我认为它需要小于或等于100,但我想我现在明白这意味着它应该等于100。

import pandas as pd
from scipy.optimize import linprog

df1 = pd.read_csv("df1.csv")
df2 = pd.read_csv("df2.csv")

costs = df1["Cost"].values
ingredients_min = df1["Ingredients_constraints_Min"].values
ingredients_max = df1["Ingredients_constraints_Max"].values

A_ub = []
b_ub = []
for nutrient in df2.columns[1:]:
    A_ub.append(df1[nutrient].to_list())
    A_ub.append([-n for n in df1[nutrient].to_list()])
    nutrient_min, nutrient_max = df2[nutrient].to_list()
    b_ub.append([nutrient_max])
    b_ub.append([-nutrient_min])

A_eq = [[1]*len(costs)]
b_eq = [100]

bounds = list(zip(ingredients_min, ingredients_max))

result = linprog(costs, A_eq=A_eq, b_eq=b_eq, A_ub=A_ub, b_ub=b_ub, bounds=None)

if result.success:
    solution_quantities = result.x
    for i, item in enumerate(df1["Item"]):
        print(f"{item}: {solution_quantities[i]}")
    
    print(f"Total Cost: {result.fun}")
© www.soinside.com 2019 - 2024. All rights reserved.