将LP从Excel转换为Python Pulp

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

我需要通过混合7种合金零件来生产5000公斤钢。我需要降低成本,所以我需要拿起最好的零件。

结果必须尊重主要的钢特性,例如,碳含量必须在2%到3%之间,不能多于或少于此。

Excel线性求解器程序已经存在,并且源于专业书籍。

现在,我正在尝试将其转换为PULP代码。

我的问题是:如何创建铜,碳和锰约束?有2个数组,所以我不知道该怎么办。

全部以百分比表示,我不知道该怎么做。我的结果实际上是错误的,我留下了我为信息做的不良约束。似乎我需要一次除以5000,但该怎么办?

让我尝试向您解释我无法理解的内容:

我需要5000公斤的钢材才能包含0.60%的铜,但是我的铜合金零件包含90%和96%的铜。您是否了解我的意思,以及为什么很难描述我的约束条件?

对不起,我的英语

"" "
 Mining and metals

We make steel with raw materials, we want to reduce the cost of producing this steel
to make more money, but still respecting the minimum characteristics of quality steel

"" "

# Minimize the cost of metal alloys.
# Characteristics of the steel to be made

"" "Element      %Minimum %Max   %Real ( it is a var)
    Carbon       2         3     2.26
    Copper       0.4       0.6   0.60
    Manganese    1.2       1.65  1.20

 "" "
# Characteristics, stocks and purchase price of alloys
"" "

Alloy          C%   Cu%   Mn%     Stocks kg Price € / kg
Iron alloy     2.50 0.00  1.30    4000      1.20
Iron alloy     3.00 0.00  0.80    3000      1.50
Iron alloy     0.00 0.30  0.00    6000      0.90
Copper alloy   0.00 90.00 0.00    5000      1.30
Copper alloy   0.00 96.00 4.00    2000      1.45
Aluminum alloy 0.00 0.40  1.20    3000      1.20
Aluminum alloy 0.00 0.60  0.00   2,500      1.00

"" "

# Import the PuLP lib
from pulp import *

# Create the problem variable
prob = LpProblem ("MinimiserLpAlliage", LpMinimize)

# The 7 vars have a zero limit
x1 = LpVariable ("Iron alloy 1", 0)
x2 = LpVariable ("Iron alloy 2", 0)
x3 = LpVariable ("Iron alloy 3", 0)
x4 = LpVariable ("Copper alloy 1", 0)
x5 = LpVariable ("Copper alloy 2", 0)
x6 = LpVariable ("Aluminum alloy 1", 0)
x7 = LpVariable ("Aluminum alloy 2", 0)


# The objective function is to minimize the total cost of the alloys in EUROS for a given quantity in KGS
prob + = 1.20 * x1 + 1.50 * x2 + 0.90 * x3 + 1.30 * x4 + 1.45 * x5 + 1.20 * x6 + 1.00 * x7, "AlliageCost"

# Quantity constraint in KGS.
prob + = x1 + x2 + x3 + x4 + x5 + x6 + x7 == 5000, "RequestedQuantity"

# MIN constraints of% carbon, by alloy  // ITS NOT WHAT I NEED
prob + = x1> = 2.5, "MinCarboneRequirement1"
prob + = x2> = 3, "MinCarboneRequirement2"
prob + = x3> = 0, "MinCarboneRequirement3"
prob + = x4> = 0, "MinCarboneRequirement4"
prob + = x5> = 0, "MinCarboneRequirement5"
prob + = x6> = 0, "MinCarboneRequirement6"
prob + = x7> = 0, "MinCarboneRequirement7"

# MIN constraints of% copper, by alloy // ITS WRONG ITS NOT WHAT I NEED
prob + = x1> = 0, "MinCuivreRequirement1"
prob + = x2> = 0, "MinCuivreRequirement2"
prob + = x3> = 0.3, "MinCuivreRequirement3"
prob + = x4> = 90, "MinCuivreRequirement4"
prob + = x5> = 96, "MinCuivreRequirement5"
prob + = x6> = 0.4, "MinCuivreRequirement6"
prob + = x7> = 0.6, "MinCuivreRequirement7"

# MIN constraints of% of Manganese, by alloy // ITS WRONG ITS NOT WHAT I NEED
prob + = x1> = 1.3, "MinManganeseRequirement1"
prob + = x2> = 0.8, "MinManganeseRequirement2"
prob + = x3> = 0, "MinManganeseRequirement3"
prob + = x4> = 0, "MinManganeseRequirement4"
prob + = x5> = 4, "MinManganeseRequirement5"
prob + = x6> = 1.2, "MinManganeseRequirement6"
prob + = x7> = 0, "MinManganeseRequirement7"

# MAX constraints of% of Manganese, by alloy // ITS WRONG ITS NOT WHAT I NEED
prob + = x1 <= 1.3, "MaxManganeseRequirement1"
prob + = x2 <= 0.8, "MaxManganeseRequirement2"
prob + = x3 <= 0, "MaxManganeseRequirement3"
prob + = x4 <= 0, "MaxManganeseRequirement4"
prob + = x5 <= 4, "MaxManganeseRequirement5"
prob + = x6 <= 1.2, "MaxManganeseRequirement6"
prob + = x7 <= 0, "MaxManganeseRequirement7"


# 5. MAX constraints from available stock, by alloy // I THINK IT IS OK
prob + = x1 <= 4000, "MaxStock"
prob + = x2 <= 3000, "MaxStock1"
prob + = x3 <= 6000, "MaxStock2"
prob + = x4 <= 5000, "MaxStock3"
prob + = x5 <= 2000, "MaxStock4"
prob + = x6 <= 3000, "MaxStock5"
prob + = x7 <= 2500, "MaxStock6"



# The problem data is written to an .lp file
prob.writeLP ( "WhiskasModel.lp")

# We use the solver
prob.solve ()

# The status of the solution
print ("Status:", LpStatus [prob.status])

# We magnify and display the optimums of each var
for v in prob.variables ():
    print (v.name, "=", v.varValue)

# The result of the objective function is here
print ("Total", value (prob.objective))

这是答案,但是当然,这是错误的,因为我不知道如何执行约束:

Status: Optimal
Aluminum_alloy_1 = 1.2
Aluminum_alloy_2 = 0.6
Copper_alloy_1 = 90.0
Alloy_of_copper_2 = 96.0
Alloy_of_fer_1 = 2.5
Alloy_of_fer_2 = 3.0
Iron_alloy_3 = 4806.7
Total 4,591.76,999,999,999,995

EDIT您好!这是我代码的改进版本2,抱歉,它是法语的,但是我敢打赌,您可以明白我的意思,它仍然无法正常工作,以为...但是更接近我的需求:

Mining and metals

In the manufacture of steel with permeable materials, sur wants to reduce the cost of producing this steel
to earn more money but still respecting the important characteristics of quality steel



    # Characteristics of the steel to be made



    """ Elément     % minimal   % Max   
    Carbone             2         3 
    Cuivre              0.4      0.6    
    Manganèse           1.2      1.65 

     """
    # Characteristics, stocks and purchase price of alloys at KILO
    """ 
    Alliage             C %     Cu %    Mn %    Stocks kg   Prix €/kg
    Alliage de fer 1    2,50    0,00    1,30    4000        1,20
    Alliage de fer 2    3,00    0,00    0,80    3000        1,50
    Alliage de fer 3    0,00    0,30    0,00    6000        0,90
    Alliage de cuivre 1 0,00    90,00   0,00    5000        1,30
    Alliage de cuivre 2 0,00    96,00   4,00    2000        1,45
    Alliage d'alu 1     0,00    0,40    1,20    3000        1,20
    Alliage d'alu 2     0,00    0,60    0,00    2500        1,00 
    """

    # Importer la lib PuLP 
    from pulp import *

    #Créer la variable du problème
    prob = LpProblem("MinimiserLpAlliage",LpMinimize)

    # The 7 vars have a zero limit, these decision variables are expressed in KILOS
    x1 = LpVariable("Alliage de fer 1",0)
    x2 = LpVariable("Alliage de fer 2",0)
    x3 = LpVariable("Alliage de fer 3",0)
    x4 = LpVariable("Alliage de cuivre 1",0)
    x5 = LpVariable("Alliage de cuivre 2",0)
    x6 = LpVariable("Alliage d'alu 1",0)
    x7 = LpVariable("Alliage d'alu 2",0)


    # The objective function is to minimize the total cost of the alloys in EUROS


    prob += 1.20 * x1 + 1.50 * x2 + 0.90 * x3 + 1.30 * x4 + 1.45 * x5 + 1.20 * x6 + 1.00 * x7, "CoutAlliages"

    # Quantity constraint in KGS.
    prob += x1 + x2 + x3 + x4 + x5 + x6 + x7 == 5000, "QuantitéDemandée"

    # Carbon stress.
    prob += (2.50 * x1  + 3.00 * x2 + x3 + x4 + x5 + x6 + x7 ) / 5000 <= 3,"carBmax"
    prob += (2.50 * x1  + 3.00 * x2 + x3 + x4 + x5 + x6 + x7 ) / 5000 >= 2,"carBmin"

    # Constraint cu  .
    prob += (x1 + x2 + 0.30 * x3 +  90 * x4  +  96 * x5 + 0.40 * x6 + 0.60 * x7) / 5000 <= 0.6,"cuBmax"
    prob += (x1 + x2 + 0.30 * x3 +  90 * x4  +  96 * x5 + 0.40 * x6 + 0.60 * x7) / 5000 >= 0.4,"cuBmin"

    # Constraint Manganèse.
    prob += (1.30 * x1 + 0.80 * x2 + x3 + x4  + 4 *  x5  + 1.20 * x6 + x7 ) / 5000 <= 1.65,"mgBmax"
    prob += (1.30 * x1 + 0.80 * x2 + x3 + x4  + 4 *  x5  + 1.20 * x6 + x7 ) / 5000 >= 1.2,"mgBmin"

    # 5. MAX constraints from available stock, by alloy
    prob += x1 <= 4000 , "MaxStock"
    prob += x2 <= 3000 , "MaxStock1"  
    prob += x3 <= 6000  , "MaxStock2"  
    prob += x4 <= 5000 , "MaxStock3"   
    prob += x5 <= 2000 , "MaxStock4" 
    prob += x6 <= 3000  , "MaxStock5"
    prob += x7 <= 2500  , "MaxStock6"


    # The problem data is written to an .lp file
    prob.writeLP("acier.lp")

    # On utilise le solveur
    prob.solve()

    # The status of the solution
    print ("Status:", LpStatus[prob.status])

    # We magnify and display the optimums of each var
    for v in prob.variables():
        print (v.name, "=", v.varValue)

    # The result of the objective function is here
    print ("Total payable in euros", value(prob.objective))

    """ Status: Infeasible
    Alliage_d'alu_1 = 0.0
    Alliage_d'alu_2 = 0.0
    Alliage_de_cuivre_1 = 0.0
    Alliage_de_cuivre_2 = 0.0
    Alliage_de_fer_1 = 0.0
    Alliage_de_fer_2 = 0.0
    Alliage_de_fer_3 = 10000.0
    Total à payer en euros 9000.0 """
python linear-programming pulp
1个回答
0
投票

我认为下面的代码可以满足您的要求-但我得到的结果表明您提供的材料数据不可行:

"""
 Mining and metals

We make steel with raw materials, we want to reduce the cost of producing this steel
to make more money, but still respecting the minimum characteristics of quality steel

"""

# Minimize the cost of metal alloys.
# Characteristics of the steel to be made

"""Element      %Minimum  %Max   %Real (it is a var)
   Carbon       2         3      2.26
   Copper       0.4       0.6    0.60
   Manganese    1.2       1.65   1.20

"""

# Characteristics, stocks and purchase price of alloys
"""
Alloy          C%   Cu%   Mn%     Stocks kg Price € / kg
Iron alloy     2.50 0.00  1.30    4000      1.20
Iron alloy     3.00 0.00  0.80    3000      1.50
Iron alloy     0.00 0.30  0.00    6000      0.90
Copper alloy   0.00 90.00 0.00    5000      1.30
Copper alloy   0.00 96.00 4.00    2000      1.45
Aluminum alloy 0.00 0.40  1.20    3000      1.20
Aluminum alloy 0.00 0.60  0.00    2500      1.00
"""

# Import the PuLP lib
from pulp import *

# Create the problem variable
prob = LpProblem ("MinimiserLpAlliage", LpMinimize)

# Problem Data
input_mats = ["iron_1", "iron_2", "iron_3",
              "cu_1", "cu_2",
              "al_1", "al_2"]

input_costs = {"iron_1": 1.20, "iron_2": 1.50, "iron_3": 0.90,
               "cu_1":   1.30, "cu_2": 1.45,
               "al_1":   1.20, "al_2":   1.00}

#                               C%   Cu%   Mn%
input_composition = {"iron_1": [2.5, 0.0,  1.3],
                     "iron_2": [3.0, 0.0,  0.8],
                     "iron_3": [0.0, 0.3,  0.0],
                     "cu_1":   [0.0, 90.0, 0.0],
                     "cu_2":   [0.0, 96.0, 4.0],
                     "al_1":   [0.0, 0.4,  1.2],
                     "al_2":   [0.0, 0.6,  0.0]}

input_stock = {"iron_1": 4000, "iron_2": 3000, "iron_3": 6000,
               "cu_1": 5000, "cu_2":  2000,
               "al_1": 3000, "al_2": 2500}

request_quantity = 5000

# Problem variables - amount in kg of each input
x = LpVariable.dicts("input_mat", input_mats, 0)

# The objective function is to minimize the total cost of the alloys in EUROS for a given quantity in KGS
prob += lpSum([input_costs[i]*x[i] for i in input_mats]), "AlliageCost"

# Quantity constraint in KGS.
prob += lpSum([x[i] for i in input_mats]) == request_quantity, "RequestedQuantity"

# MIN/MAX constraint of carbon in resultant steel
prob += lpSum([x[i]*input_composition[i][0] for i in input_mats]) >= (2.0/100.0)*request_quantity, "MinCarbon"
prob += lpSum([x[i]*input_composition[i][0] for i in input_mats]) <= (3.0/100.0)*request_quantity, "MaxCarbon"

# MIN/MAX constraints of copper in resultant steel
prob += lpSum([x[i]*input_composition[i][1] for i in input_mats]) >= (0.4/100.0)*request_quantity, "MinCu"
prob += lpSum([x[i]*input_composition[i][1] for i in input_mats]) <= (0.6/100.0)*request_quantity, "MaxCu"

# MIN/MAX constraints of manganese in resultant steel
prob += lpSum([x[i]*input_composition[i][2] for i in input_mats]) >= (1.2/100.0)*request_quantity, "MinMn"
prob += lpSum([x[i]*input_composition[i][2] for i in input_mats]) <= (1.65/100.0)*request_quantity, "MaxMn"


# MAX constraints of available stock
for i in input_mats:
    x[i] <= input_stock[i], ("MaxStock_" + i)


# The problem data is written to an .lp file
prob.writeLP ( "SteelModel.lp")

# We use the solver
prob.solve()

# The status of the solution
print ("Status:", LpStatus [prob.status])

# Dislay the optimums of each var
for v in prob.variables ():
    print (v.name, "=", v.varValue)

# Display mat'l compositions
Carbon_value = 100*(sum([x[i].varValue*input_composition[i][0] for i in input_mats])/request_quantity)
Cu_value = 100*(sum([x[i].varValue*input_composition[i][1] for i in input_mats])/request_quantity)
Mn_value = 100*(sum([x[i].varValue*input_composition[i][2] for i in input_mats])/request_quantity)

print ("Carbon content: " + str(Carbon_value))
print ("Copper content: " + str(Cu_value))
print ("Manganese content: " + str(Mn_value))

# The result of the objective function is here
print ("Total", value (prob.objective))

我从中得到:

Status: Infeasible
input_mat_al_1 = 0.0
input_mat_al_2 = 0.0
input_mat_cu_1 = 0.0
input_mat_cu_2 = 0.0
input_mat_iron_1 = 4900.0
input_mat_iron_2 = 0.0
input_mat_iron_3 = 100.0
Carbon content: 245.00000000000003
Copper content: 0.6
Manganese content: 127.4
Total 5970.0

如果放松碳/铜/锰组成的限制使其变得可行,您会看到很有意义的结果。

© www.soinside.com 2019 - 2024. All rights reserved.