将LP从Excel转换为Python

2024-09-30 20:28:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要通过混合7个合金零件来生产5000公斤的钢材。 我需要降低成本,所以我需要挑选最好的零件。你知道吗

结果必须尊重钢材的主要特性,例如,碳含量必须在2%到3%之间,不能多,不能少。你知道吗

Excel线性解算程序已经存在,并且源于一本专业书籍。你知道吗

我现在正试着把它翻译成一个低俗的代码。你知道吗

我的问题是:如何创建铜、碳和锰约束?有两个数组,所以我不知道怎么做。你知道吗

都是百分比,我不知道怎么办。我的结果实际上是错误的,我留下了我所做的坏的信息约束。似乎我需要一次除以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

编辑你好! 这是我的代码的改进版本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 """
The book says the result with the excel solver is :

iron_1 : 4000 kgs 
iron_2 : 0 kgs 
iron_3 : 397.76kgs 
cu_1   : 0 kgs 
cu_2   : 27.61kgs 
al_1   : 574.62kgs 
al_2   : 0kgs

Cost in euros 5887.57 
Steel contains 2% carb, 0.6 % cu, 1.2 %

Excel选项卡: Excel pic

解算器图片: solver pic


Tags: ofthedex1x2alloyx3prob
1条回答
网友
1楼 · 发布于 2024-09-30 20:28:08

你的部分问题是你如何理解/应用百分比。我的建议是尽早将百分比[0-100]转换为小数[0-1.0]。你知道吗

在excel中,当单元格显示50%时,单元格的数值实际上是0.5。以这种方式处理百分比意味着你不必一直除以100,可以用一个百分比乘以另一个百分比,一切都很正常。你知道吗

下面的代码符合您的要求:

"""
 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": [0.025, 0.000,  0.013],
                     "iron_2": [0.030, 0.000,  0.008],
                     "iron_3": [0.000, 0.003,  0.000],
                     "cu_1":   [0.000, 0.900,  0.000],
                     "cu_2":   [0.000, 0.960,  0.040],
                     "al_1":   [0.000, 0.004,  0.012],
                     "al_2":   [0.000, 0.006,  0.000]}

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

Carbon_min = 0.02
Carbon_max = 0.03

Cu_min = 0.004
Cu_max = 0.006

Mn_min = 0.012
Mn_max = 0.0165

# 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]) >= Carbon_min*request_quantity, "MinCarbon"
prob += lpSum([x[i]*input_composition[i][0] for i in input_mats]) <= Carbon_max*request_quantity, "MaxCarbon"

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

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


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

# Solve the problem
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 = sum([x[i].varValue*input_composition[i][0] for i in input_mats])/request_quantity
Cu_value = sum([x[i].varValue*input_composition[i][1] for i in input_mats])/request_quantity
Mn_value = 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: Optimal
input_mat_al_1 = 574.62426
input_mat_al_2 = 0.0
input_mat_cu_1 = 0.0
input_mat_cu_2 = 27.612723
input_mat_iron_1 = 4000.0
input_mat_iron_2 = 0.0
input_mat_iron_3 = 397.76302
Carbon content: 0.02
Copper content: 0.006000000036
Manganese content: 0.012000000008
Total 5887.57427835

相关问题 更多 >