0

作为一个简单的 Web 开发人员 :) 在使用 SciPy Optimize 最小化功能时,我无法找出更多关注数据科学的问题。给定一组界限和一系列约束,我试图在这种情况下找到 8 种成分的值(谁的总数必须等于 100)。

约束规定了整体常量营养素值的最小值/最大值,例如。必须是至少 40% 的固体,或者必须具有等于 13.0 等的 rs 值(相对甜度)。

我已经为这些成分中的每一种设置了我的约束(我希望是正确的)和一系列界限(其中一些可以在 0 到 100 之间),但其他成分的上限和下限相同,即。固定的?。在提供的答案中,我很困惑,因为我成功运行了优化,但某些成分的值不在设置的范围内。

到目前为止,请参见下面的代码。非常感谢您的帮助!


cream = {
    "rs": 0.0,
    "se": 0.0,
    "solids": 0.454,
    "water": 0.0,
    "fat": 0.4,
    "saturated": 0.4,
    "unsaturated": 0.26,
    "msnf": 0.14,
    "protein": 0.054,
    "brix": 0.019,
    "acid": 0.0
}

whole_milk = {
    "rs": 0.0,
    "se": 0.0,
    "solids": 0.128,
    "water": 0.872,
    "fat": 0.037,
    "saturated": 0.024,
    "unsaturated": 0.013,
    "msnf": 0.091,
    "protein": 0.035,
    "brix": 0.049,
    "acid": 0.0
}

sucrose = {
    "rs": 1.0,
    "se": 1.0,
    "solids": 1.0,
    "water": 0.0,
    "fat": 0.0,
    "saturated": 0.0,
    "unsaturated": 0.0,
    "msnf": 0.0,
    "protein": 0.0,
    "brix": 1.0,
    "acid": 0.0
}

skim_milk_powder = {
    "rs": 0.0,
    "se": 0.0,
    "solids": 0.97,
    "water": 0.0,
    "fat": 0.07,
    "saturated": 0.05,
    "unsaturated": 0.02,
    "msnf": 0.963,
    "protein": 0.38,
    "brix": 0.54,
    "acid": 0.0
}

buttermilk = {
    "rs": 0.0,
    "se": 0.0,
    "solids": 0.099,
    "water": 0.901,
    "fat": 0.009,
    "saturated": 0.005,
    "unsaturated": 0.003,
    "msnf": 0.095,
    "protein": 0.033,
    "brix": 0.048,
    "acid": 0.0
}

tapioca_starch = {
    "rs": 0.0,
    "se": 0.0,
    "solids": 0.867,
    "water": 0.133,
    "fat": 0.0,
    "saturated": 0.0,
    "unsaturated": 0.0,
    "msnf": 0.0,
    "protein": 0.0,
    "brix": 0.0,
    "acid": 0.0
}

salt = {
    "rs": 0.0,
    "se": 5.9,
    "solids": 1.0,
    "water": 0.0,
    "fat": 0.0,
    "saturated": 0.0,
    "unsaturated": 0.0,
    "msnf": 0.0,
    "protein": 0.0,
    "brix": 0.0,
    "acid": 0.0
}

sugared_egg_yolk = {
    "rs": 0.1,
    "se": 0.1,
    "solids": 0.529,
    "water": 0.471,
    "fat": 0.239,
    "saturated": 0.09,
    "unsaturated": 0.143,
    "msnf": 0.0,
    "protein": 0.143,
    "brix": 0.105,
    "acid": 0.0
}

import numpy as np
from scipy.optimize import minimize

initial_guess = np.array([12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5])
x0 = np.zeros(8)

fat_value = 15.0
rs_value = 13.0
solids_value = 40.0
msnf_value = 11.0

def optimize_function(x):
    return x[0] + x[2] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7]

def total_amount_constraint(x):
    return x[0] + x[2] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] - 100

def total_fat_constraint(x):
    return (x[0] * cream["fat"] + \
    x[2] * whole_milk["fat"] + \
    x[2] * sucrose["fat"] + \
    x[3] * skim_milk_powder["fat"] + \
    x[4] * buttermilk["fat"] + \
    x[5] * tapioca_starch["fat"]+ \
    x[6] * salt["fat"] + \
    x[7] * sugared_egg_yolk["fat"]) - fat_value

def total_rs_constraint(x):
    return (x[0] * cream["rs"] + \
    x[2] * whole_milk["rs"] + \
    x[2] * sucrose["rs"] + \
    x[3] * skim_milk_powder["rs"] + \
    x[4] * buttermilk["rs"] + \
    x[5] * tapioca_starch["rs"]+ \
    x[6] * salt["rs"] + \
    x[7] * sugared_egg_yolk["rs"]) - rs_value

def total_solids_constraint(x):
    return (x[0] * cream["solids"] + \
    x[2] * whole_milk["solids"] + \
    x[2] * sucrose["solids"] + \
    x[3] * skim_milk_powder["solids"] + \
    x[4] * buttermilk["solids"] + \
    x[5] * tapioca_starch["solids"]+ \
    x[6] * salt["solids"] + \
    x[7] * sugared_egg_yolk["solids"]) - solids_value

def total_msnf_constraint(x):
    return (x[0] * cream["msnf"] + \
    x[2] * whole_milk["msnf"] + \
    x[2] * sucrose["msnf"] + \
    x[3] * skim_milk_powder["msnf"] + \
    x[4] * buttermilk["msnf"] + \
    x[5] * tapioca_starch["msnf"]+ \
    x[6] * salt["msnf"] + \
    x[7] * sugared_egg_yolk["msnf"]) - msnf_value

b = (0.0, 100.0)
salt_bound = (0.1, 0.1)
buttermilk_bound = (9.0, 9.0)
tapioca_starch_bound = (1.0, 1.0)
sugared_egg_yolk_bound = (7.77, 7.77)

bnds = (b, b, b, b, buttermilk_bound, tapioca_starch_bound, salt_bound, sugared_egg_yolk_bound)

cons = [
    {'type': 'eq', 'fun': total_amount_constraint},
    {'type': 'eq', 'fun': total_fat_constraint},
    {'type': 'ineq', 'fun': total_solids_constraint},
    {'type': 'eq', 'fun': total_rs_constraint},
    {'type': 'eq', 'fun': total_msnf_constraint},
]

options = {
    'maxiter': 1000
}

response = minimize(optimize_function, initial_guess, method="trust-constr", tol=1e-10, constraints = cons, bounds = bnds, options = options)

print(response)```

The solution set given is the following:
```x: array([29.12370093, 37.03694111, 12.45159589,  3.03213572,  8.99735476,
        1.2025148 ,  0.33409969,  7.82503797])```

Given that I set the bounds of 9, 1, 0.1 and 7.77 for the last 4 entries in this solution set, I would expect the last 4 values in the above array to be equal to that fixed bound value.


  [1]: https://i.stack.imgur.com/MDDa4.png
  [2]: https://i.stack.imgur.com/7aMgy.png
4

0 回答 0