目錄??????
前言
一 優化模型的類型
?二? 線性規劃1
? ? ? 線性規劃2
?三 0-1規劃
總結
前言
數學建模主要是將問題轉化為模型,然后再以編程的形式輸出出來
算法都知道,數學建模也需要用到算法,但是不是主要以編程形式展示,而是利用模型和有關于數學建模的公具加以展示,這里主要以問題的形式引出數學建模的知識點和編程知識點
一 優化模型的類型
1 線性規劃 2 非線性規劃 3 正數規劃 4 "0-1"規劃
?二? 線性規劃1
問題一:合理利用線材問題
現在要做100套鋼架,每套用長為2.9m,2.1m,1.5m的元鋼各一根,已知原料長7.4m,問應該如何進行下料使用的原材料更小
首先我們要知道我們這個題目明顯是一個取最優解的問題,那么就是一個切割最優問題
其次就要去找題目里面的未知量,找到未知量,才可以構建出模型
模型的確定是根據目標函數和約束條件確定的
為什么是線性規劃
我們需要確定如何從7.4米長的原料中切割出所需的2.9米、2.1米和1.5米的元鋼,以最小化浪費的材料。這個問題可以表示為一個線性規劃問題,因為:
目標函數是線性的:我們的目標是最小化使用的原料根數,即 x1?+x2?+x3?+x4?+x5?+x6?,這是一個線性函數。
約束條件是線性的:我們需要滿足切割出的元鋼總數至少為100根的條件,這些條件可以表示為線性不等式,例如 2.9*x1?+2.9*2x2?+2.9x5?≥100。
變量是非負的:切割的套數 xi? 必須是非負整數。
那么我們知道這些未知量了,我們就要構建模型,首先我們來構建一個表格
方案1 方案2 方案3 方案4 方案5 2.9 1 2 ?? 1 ?? 2.1 ?? ?? 2 2 1 1.5 3 1 2 ?? 3 首先我們有這么多種的方案,每一個方案構建的總值都是小于7.4m的
這里講講為什么不考慮使用2.9 2.1 1.5各自取一根不加?
📌 結論
- 單看浪費大小不夠,要考慮整體優化。
- 如果一個方案的浪費比其他方案都大,通常不會被選入最優解。
- 有些方案即使浪費稍多,但可能是拼湊 100 套鋼架的“必要補充”,可以加入。
- 最好的方法是用整數規劃(ILP)求解,讓計算機自動決定是否要用某個方案。
💡 所以,加不加 6.5m 方案?可以加,但最終讓計算機決定! 🚀
因為我們看倒數第二個,這個是已經到7.1了,之前都是7.4,7.3,7.2,這個是7.1所以加入,但是我們到第五種方案的時候已經到達了6.6,跨度很大,這個時候,我們就取這個,首先我們電腦是會自己判斷這個方案取不取的,這個時候我們加上是為了避免電腦取最優解要用到,保險,這個時候,其實沒有必要加這個方案六,每個都取一根,因為我們已經有一個保險的了
即使你加了也沒事,因為這個電腦可能不會選擇,不考慮這個方案,我們這個題目是要減少浪費的
那么我們要怎么判斷是否要加上方案呢?以下是al分析,作者先記下來,方便下次復習看
📌 原則 1:能否減少浪費?
- 計算當前已有方案的最小浪費(例如,方案 2 只浪費 0.1m)。
- 如果你的新方案浪費比所有已知方案都多(例如浪費 0.9m),那它幾乎不會被選入最優解。
- ? 選擇浪費更少的方案,? 排除浪費更多的方案。
示例對比(假設現有方案最小浪費 0.1m):
方案 切割方式 總長 浪費 方案 2 2.9m ×2 + 1.5m ×1 7.3m 0.1m ?(最優之一) 方案 3 2.1m ×2 + 1.5m ×2 7.2m 0.2m ? 方案 5 2.1m ×1 + 1.5m ×3 6.6m 0.8m ?(可能需要) 你的方案 2.9m ×1 + 2.1m ×1 + 1.5m ×1 6.5m 0.9m ?(比 0.8m 更差,不需要) 🔍 如果新方案的浪費比已有方案大,基本就不會被選取
📌 原則 2:能否幫助滿足 100 套需求?
即使方案本身浪費稍多,但如果它能讓其他方案更好地拼接成 100 套,也可能有用!
如何判斷?
- 嘗試去掉某個方案,看看是否還能剛好滿足 100 套需求。
- 如果去掉某個方案會導致解不可行,說明它是必要的,即使它浪費稍多。
- 如果所有方案能湊夠 100 套,而某個方案總是沒被選中,那它可以去掉。
💡 結論:如果一個方案不會被用到,或者可以被更優的方案替代,就不取!
📌 實踐方法:讓 ILP 自動決定
如果你不確定某個方案是否應該加入,可以讓整數規劃(ILP)自動決定:
- 先把所有可能的方案(包括 6.5m 方案)都放進去。
- 讓 ILP 計算最優解,如果某個方案沒有被選取,說明它不是最優的。
- 查看最終結果,看看哪些方案真正被使用了。
接下來我們就要把這個模型轉換到這歌軟件上進行操作
接下來我們就要用到這個LINGO來編寫
首先這個sets:和endsets是表示定義一個aa集合,aa集合里面有x這個變量,然后這個1..5就是這個變量的下標
然后這個min就是求解最小值,@sum表示求和,遍歷集合aa的里的i,然后緊接著根據這個aa(i)遍歷里面的變量
也就是遍歷里面aa里面的i,然后這個后面這個是aa集合里面的變量,隨著者aa里的i進行改變
下面就是一些約束條件了
@gin(x(i))
指定x(i)
必須是整數變量,然后for循環就是遍歷這里面的變量,這些變量的值不可以是小數,而是整數
最后就輸出90根鋼鐵了
三? 線性規劃2
問題二? 某晝夜服務的公交路線每天個時間區段都需要的工作人員如下表格,設工作人員分別再各個時間區段一開始上班,并連續工作8小時,問該公交至少需要多少工作人員
?
班次 時間 需要人數 1 6:00-10:00 60 2 10:00-14:00 70 3 14:00-18:00 60 4 18:00-22:00 50 5 22:00-2:00 20 6 2:00-6:00 30 接下來我們要分這個題目?
首先我們題目問的是總共的工作人員最少,那么就是每個時間段的人我都是不知道那么是多少,刪一個題目每一根鋼材我都是知道的,我只需要設置出方案數量,然后把這些方案給規劃起來求出值
所以我們這里設置的未知量就是每一個時間段的人數,考慮這里面的未知量
接下來我們就分析出了模型,接下來我們就可以編程了
?編程答案Sets:aa /1..6/: y;bb/1..6/: x; Endsetsdata:x = 60,70,60,50,20,30; enddataMin = @sum(aa(i): y(i));y(1) + y(6) >= x(1); y(2) + y(1) >= x(2); y(3) + y(2) >= x(3); y(4) + y(3) >= x(4); y(5) + y(4) >= x(5); y(6) + y(5) >= x(6);! 變量必須是整數; @for(aa(i): @gin(y(i)));
這樣才是正確的,答案為14
?三 0-1規劃
在一個公司在市東南西三區建立門市部,有7個位置點(Ai,i=1.2.3...7)可供選擇,規定:
1)在東區,由A1 A2 A3三個點至多選擇兩個
2)在西區,由A4 A5兩個點至少選擇一個
3)在南區,由A6 A7兩個點至少選擇一個
如果選用Ai點,設備投資估計為bi元,每年獲利利潤估計為ci元,但是投資總量不可以超過M元,問應該選擇哪幾個點建立門市部使得年利潤最大
首先這個就是典型的0-1問題,每一個點我們都有選擇和不選擇,1就是選擇,0就是不選擇
那么我們就要考慮怎么選擇就好了
接下來我們就只需要編程就好了
sets:aa/1..7/:b,c,x; endsetsdata:c = 1,5,7,4,6,8,9; b = 12,56,45,34,32,78,89;M = 200; enddatamax = @sum(aa(i):c(i)*x(i)); x(1) + x(2) + x(3) <= 2; x(4) + x(5) >=1; x(6) + x(7) >=1; @sum(aa(i):b(i)*x(i)) <= M; @for(aa(i):@bin(x(i)));
?1? for循環的錯誤使用
@sum(@for(aa(i):b(i)*x(i))) <= M;
這樣是不對的,sum里面已經隱式包括了相加的迭代,所以這么寫會出現語法錯誤?
2? 錯誤提示欄的報錯
這個通常是我么缺少了右括號才有的錯誤
這里的bin函數是直接隨機取值,然后轉化為01,這樣就可以運用到0-1規劃
總結
首先我們學習到了線性規劃和0-1規劃
0-1規劃還是很好理解,但是這個線性規劃還是有點抽象
首先第一個鋼鐵問題就是取走最優的部分,你可以看到這個就是把資源浪費最少的放上去,然后最后一個弄一個保險的就好了
第二個就是找出安排時間的問題,我們只需要把相鄰的時間段弄出來,然后最后算出最后人數的最小值就好了因為這個是一環扣著一環的
你只需要把問題利用數學模型描述出來,編程就會自動幫你跑出來,也就是C++里面的抽象