import numpy as np
from scipy.optimize import linprog
# STTPC: 0.07012109264995775 0.0441 + 0.08512
# SSWWV: 0.11292593635595609
# OHAFV: 0.16176470588235292
# 原料数据
raw_materials = [
    {"name": "BYQVO", "nitrogen": 0.31, "phosphorus": 0.63, "potassium": 0.0, "price": 2203},
    {"name": "UBDSV", "nitrogen": 0.47, "phosphorus": 0.76, "potassium": 0.0, "price": 2515},
    {"name": "VZZJV", "nitrogen": 0.95, "phosphorus": 0.19, "potassium": 0.0, "price": 2080},
    {"name": "STTPC", "nitrogen": 0.63, "phosphorus": 0.89, "potassium": 0.0, "price": 2136},
    {"name": "SVVGM", "nitrogen": 0.53, "phosphorus": 0.21, "potassium": 0.0, "price": 1665},
    {"name": "TXPFY", "nitrogen": 0.71, "phosphorus": 0.45, "potassium": 0.0, "price": 1984},
    {"name": "MBCKN", "nitrogen": 0.90, "phosphorus": 0.29, "potassium": 0.0, "price": 2425},
    {"name": "SSWWV", "nitrogen": 0.76, "phosphorus": 0.51, "potassium": 0.0, "price": 1886},
    {"name": "WEWNQ", "nitrogen": 0.90, "phosphorus": 0.55, "potassium": 0.0, "price": 2638},
    {"name": "CERDK", "nitrogen": 0.85, "phosphorus": 0.15, "potassium": 0.0, "price": 2182},
    {"name": "QZZLP", "nitrogen": 0.28, "phosphorus": 0.31, "potassium": 0.0, "price": 2093},
    {"name": "IGBWD", "nitrogen": 0.23, "phosphorus": 0.77, "potassium": 0.0, "price": 2434},
    {"name": "MFKAT", "nitrogen": 0.37, "phosphorus": 0.79, "potassium": 0.0, "price": 2282},
    {"name": "TPEIW", "nitrogen": 0.22, "phosphorus": 0.30, "potassium": 0.0, "price": 2904},
    {"name": "LTJBV", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.3, "price": 1531},
    {"name": "BMFBA", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.7, "price": 2639},
    {"name": "QESHH", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.21, "price": 2892},
    {"name": "XCKXJ", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.51, "price": 2984},
    {"name": "GRLOR", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.52, "price": 2098},
    {"name": "OHAFV", "nitrogen": 0.0, "phosphorus": 0.0, "potassium": 0.68, "price": 2044}
]

# 目标养分含量
target_nitrogen = 0.13
target_phosphorus = 0.12
target_potassium = 0.11

# 提取相关养分值和价格
nutrient_values = np.array([[raw_material["nitrogen"], raw_material["phosphorus"], raw_material["potassium"]] for raw_material in raw_materials])
prices = np.array([raw_material["price"] for raw_material in raw_materials])

# 变量的下界和上界(非负)
bounds = [(0, None)] * len(raw_materials)

# 不等式约束矩阵
A_ub = -nutrient_values.T  # 注意取负号
b_ub = -np.array([target_nitrogen, target_phosphorus, target_potassium])

# 目标函数系数
c = prices.copy()

# 添加低价值元素的约束条件
low_price_indices = [i for i, raw_material in enumerate(raw_materials) if raw_material["price"] < 2000]
A_ub_low_price = np.zeros((3, len(raw_materials)))
for i in low_price_indices:
    A_ub_low_price[:, i] = nutrient_values[i, :]
b_ub_low_price = np.array([0.45 - target_nitrogen, 0.45 - target_phosphorus, 0.45 - target_potassium])

A_ub = np.vstack((A_ub, A_ub_low_price))
b_ub = np.concatenate((b_ub, b_ub_low_price))

# 求解线性规划问题
result = linprog(c=c, A_ub=A_ub, b_ub=b_ub, bounds=bounds)

# 提取解决方案
x = result.x

# 计算总成本
total_cost = np.dot(prices, x)

# 计算总养分含量
total_nitrogen = np.dot(nutrient_values[:, 0], x)
total_phosphorus = np.dot(nutrient_values[:, 1], x)
total_potassium = np.dot(nutrient_values[:, 2], x)

# 打印结果
print("最优原料配方:")
for i, raw_material in enumerate(raw_materials):
    if x[i] > 0:
        print(f"{raw_material['name']}: {x[i]}")

print(f"\n总成本: {total_cost}")
print(f"总氮含量: {total_nitrogen}")
print(f"总磷含量: {total_phosphorus}")
print(f"总钾含量: {total_potassium}")



print(f"\n最低的总养分含量为:{total_nitrogen + total_phosphorus + total_potassium}")
# 获取含量金额
nutrient_prices = np.array([[raw_material["nitrogen"], raw_material["phosphorus"], raw_material["potassium"], raw_material["price"]] for raw_material in raw_materials])




# 达到45%还缺少的养分含量
needed_percent = 0.45 - (total_nitrogen + total_phosphorus + total_potassium)

ratios = []
for raw_material in raw_materials:
    nutrient_sum = raw_material["nitrogen"] + raw_material["phosphorus"] + raw_material["potassium"]
    ratio = nutrient_sum / raw_material["price"]
    ratios.append(ratio)
    raw_material['totalprice'] = ratio * 100


# 获取列表的第二个元素
def sortWithTotalPrice(elem):
    return elem['totalprice']
# 依据原料的总养分含量价格来排序
raw_materials.sort(key=sortWithTotalPrice)

# 取出最便宜的总养分单价原料
cheapest_material = raw_materials[0]

# 计算出需要原料吨数,比如少9%
x = needed_percent / ((cheapest_material['nitrogen'] + cheapest_material['phosphorus'] + cheapest_material['potassium']))

print(f'混合单元素最低原料为:{cheapest_material}, 需要量为{x}吨')
print('金额为:', x * cheapest_material['price'])

print('生产一吨45%含量的化肥总原料费用为:', total_cost + x * cheapest_material['price'])

0 Comments latest

No comments.