本文會介紹怎么用python解決線性規劃問題,為什么要用python而不是matlab和lingo呢?因為matlab的函數寫法不太符合正常的思維方式,編起來很復雜。而lingo雖然編寫容易,但報錯不詳細,一旦有錯很難查出來。而python就沒有這些問題。
關于python的語法就不再介紹了,主要介紹pulp庫的用法。
以此題為例:計算6個生產點8個銷售點的最小費用運輸問題。產銷單位運價如下表。
先建模,很容易得到以下模型:
現在開始編程:
引入頭文件是必須的:
#-*- coding: UTF-8 -*-
importnumpyasnp
frompulpimport*
step1先新建一個問題,隨便取名為prob:
prob = LpProblem("test1", LpMinimize)
step2然后定義變量為x,每個x代表了對應的A點賣到B點的數量:
foriinrange(1, 49, 1):
exec('x%s= LpVariable("x%s", 0, None, LpInteger,[])'%(i,i))
x = [[x1,x2,x3,x4,x5,x6,x7,x8],[x9,x10,x11,x12,x13,x14,x15,x16],
[x17,x18,x19,x20,x21,x22,x23,x24],[x25,x26,x27,x28,x29,x30,x31,x32],
[x33,x34,x35,x36,x37,x38,x39,x40],[x41,x42,x43,x44,x45,x46,x47,x48]]
對于LpVariable函數包含的參數,一次為 變量名,變量值的最小值,變量值的最大值,變量類型。
這里LpInteger表示變量的類型是int型,根據題目的需要還可以改成LpContinuous(實數型)和LpBinary(二值型,即0或1)。
step3開始寫入數據:
cost = np.array([[6,2,6,7,4,2,9,5],[4,9,5,3,8,5,8,2],[5,2,1,9,7,4,3,3],
[7,6,7,3,9,2,7,1],[2,3,9,5,7,2,6,5],[5,5,2,2,8,1,4,3]])
capacity = np.array([60,55,51,43,41,52])
demand = np.array([35,37,22,32,41,32,43,38])
產地的產量為capacity,銷地的銷量為demand,單位運價為cost
step4設定目標函數:
result = 0
foriinrange(0, 6):
forjinrange(0, 8):
result += x[i][j]*cost[i][j]
prob += result, "obj"
是以result最小為目標的,如果要求結果最大為目標的題目可在result前面加上負號。
step5還要設置約束:
產量的約束:
foriinrange(1,7,1):#設置產量的約束
exec('prob += sum(x[%s]) <= capacity[%s]' % (i - 1, i - 1))
銷量的約束:
foriinrange( 1 , 9 , 1):#設置銷量的約束
z=0
forjinrange( 1 , 7 , 1):
z+=x[j-1][i-1]
exec('prob += z >= demand[%s]'%(i-1))
step6需要編寫的部分就已經完成了,只需要輸出結果就行了
# Solve the problem using the default solver
prob.solve()
# Print the status of the solved LP
print ( "Status:", LpStatus[prob.status] )
# Print the value of the variables at the optimum
forvinprob.variables():
print (v.name, "=", v.varValue)
# Print the value of the objective
print ( "objective=", value(prob.objective) )
輸出的內容分別是計算狀態(optimal時就說明結果正常),變量值,和目標函數值。
這題就做完啦~
最后把代碼匯總一下:
#-*- coding: UTF-8 -*-
import numpy as np
from pulp import *
# A new LP problem
prob = LpProblem("test1", LpMinimize)
cost = np.array([[6,2,6,7,4,2,9,5],[4,9,5,3,8,5,8,2],[5,2,1,9,7,4,3,3],
[7,6,7,3,9,2,7,1],[2,3,9,5,7,2,6,5],[5,5,2,2,8,1,4,3]])
capacity = np.array([60,55,51,43,41,52])
demand = np.array([35,37,22,32,41,32,43,38])
# Variables
for i in range(1, 49, 1):
exec('x%s= LpVariable("x%s", 0, None, LpInteger,[])'%(i,i))
x = [[x1,x2,x3,x4,x5,x6,x7,x8],[x9,x10,x11,x12,x13,x14,x15,x16],
[x17,x18,x19,x20,x21,x22,x23,x24],[x25,x26,x27,x28,x29,x30,x31,x32],
[x33,x34,x35,x36,x37,x38,x39,x40],[x41,x42,x43,x44,x45,x46,x47,x48]]
# Objective
result = 0
for i in range(0, 6):
for j in range(0, 8):
result += x[i][j]*cost[i][j]
prob += result, "obj"
# (the name at the end is facultative)
# Constraints
# for i in range(1,7,1):#先對y賦值
for i in range(1,7,1):#設置產量的約束
exec('prob += sum(x[%s]) <= capacity[%s]' % (i - 1, i - 1))
for i in range( 1 , 9 , 1):#設置銷量的約束
z=0
for j in range( 1 , 7 , 1):
z+=x[j-1][i-1]
exec('prob += z >= demand[%s]'%(i-1))
# Solve the problem using the default solver
prob.solve()
# Print the status of the solved LP
print? ( "Status:", LpStatus[prob.status] )
# Print the value of the variables at the optimum
for v in prob.variables():
print (v.name, "=", v.varValue)
# Print the value of the objective
print? ( "objective=", value(prob.objective)? )