肉孜買買提·馬合木提
[摘? ? ? ? ? ?要]? 分析當(dāng)前運(yùn)籌學(xué)實(shí)驗(yàn)課的發(fā)展趨向,把Python語言結(jié)合到運(yùn)籌學(xué)規(guī)劃問題上來,通過Pulp 和 Tkinter模塊設(shè)計了可以簡單地求規(guī)劃問題(包括整數(shù)變量、0-1變量)最優(yōu)解的界面。
[關(guān)? ? 鍵? ?詞]? 運(yùn)籌學(xué);線性規(guī)劃;Python;Tkinter
[中圖分類號]? G642? ? ? ? ? ? ? ? ? ? [文獻(xiàn)標(biāo)志碼]? A? ? ? ? ? ? ? ? ? [文章編號]? 2096-0603(2022)06-0088-03
一、引言
(一)規(guī)劃問題
運(yùn)籌學(xué)是一門系統(tǒng)性的應(yīng)用型科學(xué),提供決策目標(biāo)和數(shù)量分析[1,2]。運(yùn)籌學(xué)包括線性規(guī)劃、運(yùn)輸問題、整數(shù)規(guī)劃、混合線性規(guī)劃、目標(biāo)規(guī)劃和動態(tài)規(guī)劃等。運(yùn)籌學(xué)原來以講授理論為主,隨著計算機(jī)科學(xué)技術(shù)在各領(lǐng)域中的應(yīng)用變強(qiáng),運(yùn)籌學(xué)應(yīng)用也得到極大的促進(jìn)。在這種情況下,開設(shè)運(yùn)籌學(xué)試驗(yàn)課是大勢所趨。
最近國內(nèi)運(yùn)籌學(xué)試驗(yàn)課程得到巨大的發(fā)展,目前常有的運(yùn)籌學(xué)試驗(yàn)軟件有Lingo[3]、Matlab[4]和Excel[5]。其實(shí)Python對運(yùn)籌學(xué)的應(yīng)用也是強(qiáng)大的,但是此方面的研究較少。本文介紹Python語言在運(yùn)籌學(xué)試驗(yàn)教學(xué)中的應(yīng)用,尤其是在線性規(guī)劃、整數(shù)規(guī)劃和混合線性規(guī)劃中的應(yīng)用。
(二)Python語言
Python是一種面向?qū)ο蟮摹⒔忉屝缘母呒壋绦蛟O(shè)計語言。當(dāng)前Python與高校專業(yè)課程內(nèi)容的融合變得十分重要[6]。Python是簡單易學(xué),非常適合初學(xué)者,而且包含豐富的庫,目前最接近自然語言的編程語言[7]。其中的Tkinter模塊在界面可視化工程中得到編程者的喜愛。本文首先介紹Tkinter模塊,且通過Tkinter模塊造出可視化界面,應(yīng)用于線性規(guī)劃、整數(shù)規(guī)劃和混合線性規(guī)劃中,提高學(xué)生解決實(shí)際問題的能力。
Tkinter是Python的標(biāo)準(zhǔn)GUI庫,由于簡單而好學(xué),在程序界面設(shè)計工作中受編程者的喜好[8]。因?yàn)門kinter是Python的標(biāo)準(zhǔn)庫,因此編程過程中只需用import Tk-inter來調(diào)用即可。詳細(xì)內(nèi)容請見參考文獻(xiàn)[8]。
二、主要技術(shù)實(shí)現(xiàn)過程
(一)模塊的安裝
本文將使用以下擴(kuò)展庫:
-numpy:針對存儲和處理高維數(shù)組和矩陣運(yùn)算
-Tkinter:GUI設(shè)計
-sympy:符號運(yùn)算和矩陣運(yùn)算
-Pulp:求解線性規(guī)劃包(可以處理整數(shù)規(guī)劃問題)
下面介紹各模塊的下載和安裝。Windows 7或Win-dows 10中先按Window+R,并運(yùn)行cmd,并輸入
pip install Pulp
pip install numpy
pip install sympy
命令進(jìn)行安裝。
(二)實(shí)現(xiàn)過程
首先通過以下代碼可以建立我們的界面。
from tkinter import Tk
root = Tk()
root.title("混合線性規(guī)劃")
root.geometry(′800 × 430′)
root.resizable(width = False,height = False)
zsWindow(root)
root.mainloop()
其中,zsWindow()是一個類,被定義為
class zsWindow:
? ? ? ? ?def __init__(self,root):
? ? ? ? ? ? ? ? ? # 創(chuàng)建一個下拉列表
? ? ? ? ? ? ? ? ? self.max_min = StringVar()
? ? ? ? ? ? ? ? ? self.numberChosen = ttk.Combobox(root,
? ? ? ? ? ? ? ? ? ? ? ? ? ? font=(′Arial′,13),width=12,
? ? ? ? ? ? ? ? ? ? ? ? ? ? textvariable=self.max_min)
? ? ? ? ? ? ? ? ? # 設(shè)置下拉列表的值
? ? ? ? ? ? ? ? ? self.numberChosen[′values′]=(′max′,′min′)
? ? ? ? ? ? ? ? ? self.numberChosen.place(x=50,y=30,
? ? ? ? ? ? ? ? ? ? ? ? ? ? height=30,width=120)
? ? ? ? ? ? ? ? ? self.numberChosen.current(0)
? ? ? ? ? ? ? ? ? self.numberChosen[′state′] = ′readonly′
………
代碼包括100多行,本文中忽略剩下代碼。得到的窗口為圖1所示。
界面中左上的第一個下拉單中可以選擇“max”或“min”,表示該問題是最大值問題或者最小值問題。右邊的下拉單中可以選擇該問題中的變量數(shù)。下面三個下拉單中可以設(shè)置變量的取值范圍和整數(shù)性。在默認(rèn)狀態(tài)下變量的取值范圍為非零數(shù)和一般連續(xù)變量。變量也可以設(shè)置為“Integer”,表示該變量為整數(shù)變量,也可以設(shè)置為“Binary”,表示該變量為0-1變量。因此,此界面可以求一般線性規(guī)劃問題、整數(shù)規(guī)劃問題和混合規(guī)劃問題的解。文本框A、b、c分別為系數(shù)矩陣、條件系數(shù)和目標(biāo)系數(shù)。大小符號框只能輸入“>、<或=”符號,如果放空,就默認(rèn)識別為“<”符號。求解按鈕通過以下命令設(shè)置:
#命令按鈕
self.But1 = Button(root,font=(′Roman′,13),text=\
? ? ? ? ? ? ?"求解",command = self.do_job_Button)
self.But1.place(x=50,y=360,width=150,height=40)
其中do_job_Button函數(shù)被頂以為:
def do_job_Button(self,ev=None):
? ? ? ?c = self.var.get()
? ? ? ?c_list = c.split()
? ? ? ?self.lb1.delete(0,END)
? ? ? ?#如果輸入內(nèi)容不是數(shù)字出現(xiàn)錯誤框
? ? ? ?try:
self.c = np.array(c_list,dtype=float)
? ? ? ?except:
messagebox.showerror(title=′Error Message′,
message = ′輸入有錯誤!′)
return
? ? ? ? #如果c的長度與變量數(shù)不一致
? ? ? ? if len(self.c) != self.v_num:
? ? ? ? ? ? messagebox.showerror(title=′Error
? ? ? Message′,
? ? ? ? message=′c的長度與變量數(shù)不一致!′)
? ? ? ? return
……………………
res = self.Linear_Op(objective ,constraints)
#輸出結(jié)果
self.lb1.insert(END,′最優(yōu)解為:′)
self.lb1.insert(END,′? ? ? ′ + str(res))
#若最優(yōu)解存在,則輸出目標(biāo)函數(shù)值
if (self.status == 1):
? self.lb1.insert(END,′最優(yōu)目標(biāo)函數(shù)值為:′)
self.lb1.insert(END,′? ? ? ′+\ str(np.dot(self.c,res)))
按“求解”按鈕后召喚do_job_Button函數(shù)。首先讀取所有信息,并轉(zhuǎn)換成數(shù)組。如果輸入有誤會自動報錯。讀取信息后,執(zhí)行“Linear_Op”函數(shù)?!癓inear_Op”函數(shù)被定義為:
def Linear_Op(self,objective,constraints):
? ? ? ? #確定最大化問題還是最小化問題
? ? ? ? if self.max_min.get() == ′max′:
? ? ? ? ? ? ? ? ?maxmin = pulp.LpMaximize
? ? ? ? else:
maxmin = pulp.LpMinimize
? ? ? ?#創(chuàng)建線性規(guī)劃問題
? ? ? ?prob = pulp.LpProblem(′LP1′,maxmin)
? ? ? ?prob += objective
? ? ? ?for cons in constraints:
? ? ? ? ? ? ? ?prob += cons
? ? ? ?lb_list = str(prob).split(′\n′)
? ? ? ?self.status = prob.solve()
? ? ? ?if self.status == -1 :
? ? ? ? ? ? ? ?return ′無可行解′
? ? ? ?elif self.status == -2 :
? ? ? ? ? ? ? ?return ′無界解′
? ? ? ?else :
? ? ? ? ? ? ? ?return [v.varValue.real for v in\
? ? ? ? ? ? ? ?prob.variables()]
(三)舉例操作
例題1.求下面規(guī)劃問題的最優(yōu)解
s.t.max z = 12x1+6x2+3x32x1+3x2-4x3>-9x1+5x2+x3<10x1≥0,x2∈R(整數(shù)),x3:0-1變量
首先該問題是最大值問題,包括三個變量(三個變量的設(shè)置如圖2所示)。
圖2 x1設(shè)置為(0,+∞)上的連續(xù)變量,x2設(shè)置為
(-∞,+∞)上的整數(shù),x3設(shè)置為0-1變量
具體輸入方法和運(yùn)行結(jié)果如圖3所示。
最優(yōu)解為(x1,x2,x3)=(3,1,0),最優(yōu)值為z=30。
本程序可以用if語句、ry-excep語句和message-box.showerror函數(shù)報錯誤,如果向量c中包含“字符”,則可以通過以下代碼達(dá)到圖4的效果。
#如果輸入內(nèi)容不是數(shù)字出現(xiàn)錯誤框
try:
? ? ? self.c = np.array(c_list,dtype=float)
except:
? ? ? messagebox.showerror(title=′Error Message′,\
? ? ? message=′輸入有錯誤!′)
? ? return
如果向量c的長度和矩陣A的列數(shù)不一致,則
#如果c的長度與變量數(shù)不一致
if len(self.c) != self.v_num:
messagebox.showerror(title=′Error Message′,\
message=′c的長度與變量數(shù)不一致!′)
? ? ? return
三、結(jié)論
本文我們通過Tkinter模塊,簡單地構(gòu)造了界面,并用Pulp模塊求規(guī)劃問題的最優(yōu)解。使用起來方便、簡單,可用于線性規(guī)劃問題、整數(shù)規(guī)劃問題和混合問題,效果良好。在編程和使用此界面過程當(dāng)中使學(xué)生會掌握Python基礎(chǔ)語言、Tkinter和Pulp模塊的使用。同時也可分辨出線性規(guī)劃、證書規(guī)劃和混合問題之間的區(qū)別。對提升教學(xué)質(zhì)量和培養(yǎng)學(xué)生的學(xué)習(xí)熱情起很大的作用。其實(shí)動態(tài)規(guī)劃和目標(biāo)規(guī)劃問題也可以通過本文構(gòu)造的界面解決,但需要先建立問題的規(guī)劃模型。下一步要構(gòu)造出能方便地解決運(yùn)輸問題、目標(biāo)規(guī)劃等規(guī)劃問題的界面。
參考文獻(xiàn):
[1]運(yùn)籌學(xué)教材編寫組.運(yùn)籌學(xué)[M].北京:清華大學(xué)出版社,2005.
[2]胡運(yùn)權(quán).運(yùn)籌學(xué)基礎(chǔ)及應(yīng)用(第六版)[M].北京:高等教育出版社,2014.
[3]丁小妹,王平.Lingo軟件在運(yùn)籌學(xué)實(shí)驗(yàn)教學(xué)中的應(yīng)用[J].武夷學(xué)院學(xué)報,2017(9):108-110.
[4]張明,王文文.Matlab在經(jīng)管類運(yùn)籌學(xué)教學(xué)中的探索與實(shí)踐[J].大學(xué)教育,2012(7):81-89.
[5]于瑛英.EXCEL在運(yùn)籌學(xué)規(guī)劃論教學(xué)中的應(yīng)用[J].教育教學(xué)論壇,2014(10):278-280.
[6]嵩天,黃天羽,禮欣.Python語言:程序設(shè)計課程教學(xué)改革的理想選擇[J].中國大學(xué)教學(xué),2016(2):42-47.
[7]毛焱穎,張羽,焦柳丹.Python語言程序設(shè)計課程教學(xué)實(shí)踐[J].電子技術(shù),2021(50):76-77.
[8]高秀艷.基于Tkinter的多語語料庫分段與對齊工具實(shí)現(xiàn)研究[J].河北軟件職業(yè)技術(shù)學(xué)院學(xué)報,2020(22):5-8.
◎編輯 馬燕萍