zoukankan      html  css  js  c++  java
  • Pulp之三:官网上的应用样例(4)-Blending Problem (混合问题)

    We're going to make some sausages!
    We have the following ingredients available to us:
    Ingredient Cost (€/kg) Availability (kg)
    Pork 4.32 30
    Wheat 2.46 20
    Starch 1.86 17

    We'll make 2 types of sausage:
    Economy (>40% Pork)
    Premium (>60% Pork)
    One sausage is 50 grams (0.05 kg)
    According to government regulations, the most starch we can use in our sausages is 25%
    We have a contract with a butcher, and have already purchased 23 kg pork, that will go bad if it's not used.
    We have a demand for 350 economy sausages and 500 premium sausages.
    We need to figure out how to most cost effectively blend our sausages.

    Let's model our problem
    pe = Pork in the economy sausages (kg)
    we = Wheat in the economy sausages (kg)
    se = Starch in the economy sausages (kg)
    pp = Pork in the premium sausages (kg)
    wp = Wheat in the premium sausages (kg)
    sp = Starch in the premium sausages (kg)
    We want to minimise costs such that:
    Cost = 0.72(pe + pp) + 0.41(we + wp) + 0.31(se + sp)

    With the following constraints:
    pe + we + se = 350 * 0.05
    pp + wp + sp = 500 * 0.05
    pe ≥ 0.4(pe + we + se)
    pp ≥ 0.6(pp + wp + sp)
    se ≤ 0.25(pe + we + se)
    sp ≤ 0.25(pp + wp + sp)
    pe + pp ≤ 30
    we + wp ≤ 20
    se + sp ≤ 17
    pe + pp ≥ 23

    问题描述:
    假设有如下3种原料(ingredients)猪肉、小麦和淀粉,它们各自的价格和数量如下表:
    原料 成本 (€/kg) 数量 (kg)
    猪肉 pork 4.32 30
    小麦 wheat 2.46 20
    淀粉 starch 1.86 17

    我们可以用这些原料(sausage_types)制作两种烤肠:
     economy便宜的 (猪肉含量>40%)
     premium贵的 (猪肉含量>60%)
    每根香肠重量为50克(0.05 kg)。政府部门规定淀粉的含量不能超过25%。另外我们和一个屠宰场签定了合约,
    至少要购买23kg的猪肉。我们的客户向我们订购了350个便宜的烤肠和500个贵的烤肠,
    现在我们需要设计这两种烤肠里3种原料的比例,目标是用最少的成本。

    """

    import pulp
    # Instantiate our problem class
    model = pulp.LpProblem("Cost_minimising_blending_problem", pulp.LpMinimize)
    # Construct our decision variable lists
    sausage_types = ['economy', 'premium']
    ingredients = ['pork', 'wheat', 'starch']
    
    ing_weight = pulp.LpVariable.dicts("weight kg",
                                         ((i, j) for i in sausage_types for j in ingredients),
                                         lowBound=0,
                                         cat='Continuous')
    
    # 先定义目标函数:Objective Function
    model += (
        pulp.lpSum([
            4.32 * ing_weight[(i, 'pork')]
            + 2.46 * ing_weight[(i, 'wheat')]
            + 1.86 * ing_weight[(i, 'starch')]
            for i in sausage_types])
            )
    
    # 约束
    # 350个便宜的和500个贵的烤肠,每个0.05 kg
    model += pulp.lpSum([ing_weight['economy', j] for j in ingredients]) == 350 * 0.05
    model += pulp.lpSum([ing_weight['premium', j] for j in ingredients]) == 500 * 0.05
    
    # 便宜的烤肠猪肉占比大于pork,贵的大于60%,
    # 其实pulp.lpSum([ing_weight['economy', j] for j in ingredients]) == 350 * 0.05
    # 改成350 * 0.05更简单
    model += ing_weight['economy', 'pork'] >= (
        0.4 * pulp.lpSum([ing_weight['economy', j] for j in ingredients]))
    
    model += ing_weight['premium', 'pork'] >= (
        0.6 * pulp.lpSum([ing_weight['premium', j] for j in ingredients]))
    
    # 淀粉比率小于25%
    model += ing_weight['economy', 'starch'] <= (
        0.25 * pulp.lpSum([ing_weight['economy', j] for j in ingredients]))
    
    model += ing_weight['premium', 'starch'] <= (
        0.25 * pulp.lpSum([ing_weight['premium', j] for j in ingredients]))
    
    # 我们最多用30kg猪肉,20kg小麦和17kg淀粉 
    model += pulp.lpSum([ing_weight[i, 'pork'] for i in sausage_types]) <= 30
    model += pulp.lpSum([ing_weight[i, 'wheat'] for i in sausage_types]) <= 20
    model += pulp.lpSum([ing_weight[i, 'starch'] for i in sausage_types]) <= 17
    
    # 我们已经预定了23kg猪肉,所以一定要用掉
    model += pulp.lpSum([ing_weight[i, 'pork'] for i in sausage_types]) >= 23
    #前面我们用+号来表示线性约束,但是现在我们要对很多个变量进行线性约束,这个时候就需要用到pulp.lpSum函数来简化。
    #比如第一个约束:我们当然可以这样来写:
    #model += [ing_weight['economy', 'pork'] +  [ing_weight['economy', 'wheat'] + ing_weight['economy', 'starch'] == 350 * 0.05
    #如果变量成百上千,那这行代码就上万列了,而且写起来也得累死。我们用lpSum就简单的多:
    #model += pulp.lpSum([ing_weight['economy', j] for j in ingredients]) = 350 * 0.05
    #然后就是求解和输出结果:
    # Solve our problem
    model.solve()
    print(pulp.LpStatus[model.status])
    
    for var in ing_weight:
        var_value = ing_weight[var].varValue
        print("The weight of {0} in {1} sausages is {2} kg".format(var[1], var[0], var_value))
    
    total_cost = pulp.value(model.objective)
    print("The total cost is €{} for 350 economy sausages and 500 premium sausages".format(round(total_cost, 2)))
    
    

    运行结果:

  • 相关阅读:
    给自己一个书单
    pureMVC学习之一
    泛型与无聊
    队列与DelphiXe新语法
    有道理的前端
    具备 jQuery 经验的人如何学习AngularJS(附:学习路径)
    Blogging with github Pages
    Cookie/Session机制
    通往全栈工程师的捷径 —— react
    女生应该找个有独立博客的男朋友
  • 原文地址:https://www.cnblogs.com/treasury-manager/p/13800182.html
Copyright © 2011-2022 走看看