from scipy.optimize import linprog
import numpy as np
raw_materials = [
{"name": "46%小颗粒尿素", "nitrogen": 0.46, "phosphorus": 0.0, "potassium": 0.0, "price": 2200},
{"name": "46%大颗粒尿素", "nitrogen": 0.46, "phosphorus": 0.0, "potassium": 0.0, "price": 2300},
{"name": "20.5%粉体硫酸铵", "nitrogen": 0.205, "phosphorus": 0.0, "potassium": 0.0, "price": 1200},
{"name": "20.5%晶体硫酸铵", "nitrogen": 0.205, "phosphorus": 0.0, "potassium": 0.0, "price": 1200},
{"name": "17.1%碳酸氢铵", "nitrogen": 0.171, "phosphorus": 0.0, "potassium": 0.0, "price": 1300},
{"name": "55%10-45-0磷酸一铵", "nitrogen": 0.1, "phosphorus": 0.45, "potassium": 0.0, "price": 3200},
{"name": "55%11-40-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.44, "potassium": 0.0, "price": 2936},
{"name": "58%11-47-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.47, "potassium": 0.0, "price": 3119},
{"name": "60%11-49-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.49, "potassium": 0.0, "price": 3257},
{"name": "64%11-53-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.53, "potassium": 0.0, "price": 3600},
{"name": "66%11-55-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.55, "potassium": 0.0, "price": 4700},
{"name": "66%11.5-54.5-0磷酸一铵", "nitrogen": 0.115, "phosphorus": 0.545, "potassium": 0.0, "price": 4312},
{"name": "68%10-58-0磷酸一铵", "nitrogen": 0.1, "phosphorus": 0.58, "potassium": 0.0, "price": 4404},
{"name": "68%11-57-0磷酸一铵", "nitrogen": 0.11, "phosphorus": 0.57, "potassium": 0.0, "price": 4404},
{"name": "72%12-60-0磷酸一铵", "nitrogen": 0.12, "phosphorus": 0.6, "potassium": 0.0, "price": 5596},
{"name": "62进口氯化钾", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.62, "price": 2410},
{"name": "52%曼海姆硫酸钾", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.52, "price": 3180},
{"name": "52%罗布泊硫酸钾", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.52, "price": 2880},
{"name": "60%氯化钾", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.6, "price": 2350}
]
from pulp import LpProblem, LpVariable, LpMinimize, lpSum, value
def calculate_minimum_cost(raw_materials, target_total_content, target_element_content, fluctuation):
# 创建线性规划问题
problem = LpProblem("Minimum Cost", LpMinimize)
# 创建变量
amounts = [LpVariable(material["name"], lowBound=0, cat="Continuous") for material in raw_materials]
# 定义目标函数(最小化成本)
problem += lpSum(material["price"] * amount for material, amount in zip(raw_materials, amounts))
# 定义约束条件(目标含量)
for element in ["nitrogen", "phosphorus", "potassium"]:
problem += lpSum(material[element] * amount for material, amount in zip(raw_materials, amounts)) >= \
(target_element_content[element] - fluctuation)
problem += lpSum(material[element] * amount for material, amount in zip(raw_materials, amounts)) <= \
(target_element_content[element] + fluctuation)
# 约束条件(总和为目标总含量)
problem += lpSum(material["nitrogen"] * amount for material, amount in zip(raw_materials, amounts)) + \
lpSum(material["phosphorus"] * amount for material, amount in zip(raw_materials, amounts)) + \
lpSum(material["potassium"] * amount for material, amount in zip(raw_materials, amounts)) == \
target_total_content
# 求解线性规划问题
problem.solve()
# 输出结果
if problem.status == 1: # 若求解成功
optimal_amounts = [value(amount) for amount in amounts]
# 构建最终使用的原料和用量
used_materials = []
for material, amount in zip(raw_materials, optimal_amounts):
if amount > 0:
used_materials.append({"name": material["name"], "amount": amount})
# 计算实际的氮磷钾含量
actual_nitrogen = sum(material["nitrogen"] * amount for material, amount in zip(raw_materials, optimal_amounts))
actual_phosphorus = sum(material["phosphorus"] * amount for material, amount in zip(raw_materials, optimal_amounts))
actual_potassium = sum(material["potassium"] * amount for material, amount in zip(raw_materials, optimal_amounts))
# 计算最终成本
total_cost = value(problem.objective)
# 返回结果
return used_materials, actual_nitrogen, actual_phosphorus, actual_potassium, total_cost
else:
return None, None, None, None, None
# 目标总含量和目标单元素含量
target_total_content = 0.45
target_element_content = {"nitrogen": 0.15, "phosphorus": 0.15, "potassium": 0.15}
# 波动范围
fluctuation = 0.005
# 计算最低成本
used_materials, actual_nitrogen, actual_phosphorus, actual_potassium, total_cost = calculate_minimum_cost(raw_materials, target_total_content, target_element_content, fluctuation)
if used_materials is not None:
# 输出最终使用的原料和用量
print("最终使用的原料和用量:")
for material in used_materials:
print(material["name"], ": ", material["amount"])
# 输出最终的氮磷钾含量
print("最终的氮磷钾含量:")
print("氮含量: ", actual_nitrogen)
print("磷含量: ", actual_phosphorus)
print("钾含量: ", actual_potassium)
# 输出最终的成本
print("最终的成本: ", total_cost)
else:
print("无法找到满足要求的解决方案。")
0 Comments latest
No comments.