這篇來聊一下運輸問題裡很常見的「西北角法」。
西北角法的玩法很單純,就是從運輸表左上角(也就是所謂的西北角)開始分配數量,一路往右、往下走,把供給跟需求配到剛好。
西北角法它的好處是:
算法超直覺、步驟固定。
很快就能拼出一個「可行解」,程式也好寫。
念書念到這個,想了一下發願AI,這種規則這麼機械,很適合交給 AI 生個雛形,再用 VBA 包一包來玩看看。
教科書習題:
習題解答:
Sub NorthwestCornerMethod()
On Error GoTo LINE1
Dim ws As Worksheet
Set ws = ActiveSheet
' 設定輸入範圍 (請依實際資料調整)
Dim supplyRange As Range, demandRange As Range, costRange As Range
Set supplyRange = ws.Range("E2:E4") ' 供給: 3供應點
Set demandRange = ws.Range("B5:D5") ' 需求: 3需求點
Set costRange = ws.Range("B2:D4") ' 運費矩陣 3x3
Dim m As Integer, n As Integer
m = supplyRange.Rows.Count
n = demandRange.Columns.Count
' 讀取資料到陣列
Dim supply() As Double, demand() As Double, cost() As Double
Dim allocation() As Double, i As Integer, j As Integer
ReDim supply(0 To m - 1), demand(0 To n - 1)
ReDim cost(0 To m - 1, 0 To n - 1)
ReDim allocation(0 To m - 1, 0 To n - 1)
Dim k As Integer
On Error Resume Next
For k = 0 To m - 1
supply(k) = supplyRange.Cells(k + 1, 1).Value
Next k
For k = 0 To n - 1
demand(k) = demandRange.Cells(1, k + 1).Value
Next k
For i = 0 To m - 1
For j = 0 To n - 1
cost(i, j) = costRange.Cells(i + 1, j + 1).Value
Next j
Next i
On Error GoTo LINE1
' 西北角法核心演算法
i = 0: j = 0
Dim totalCost As Double: totalCost = 0
Do While i < m And j < n
Dim amount As Double
amount = WorksheetFunction.Min(supply(i), demand(j))
allocation(i, j) = amount
totalCost = totalCost + amount * cost(i, j)
supply(i) = supply(i) - amount
demand(j) = demand(j) - amount
If supply(i) = 0 Then i = i + 1
If demand(j) = 0 Then j = j + 1
Loop
' 輸出結果 (從F2開始)
ws.Range("G1").Value = "分配結果"
For i = 0 To m - 1
For j = 0 To n - 1
ws.Cells(i + 2, 7 + j).Value = allocation(i, j)
Next j
Next i
ws.Range("H1").Value = "總成本"
ws.Range("I1").Value = totalCost
MsgBox "西北角法計算完成!總成本: " & Format(totalCost, "0.00")
Exit Sub
LINE1:
MsgBox "ERROR"
Resume
End Sub
再來一試:
步驟:
1.找尋最低成本的方格,優先滿足。
2.再找次成本最低,以此類推。
案例:
結果:
Sub LeastCostMethod()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim supplyRng As Range, demandRng As Range, costRng As Range
Set supplyRng = ws.Range("E2:E4") ' 供給
Set demandRng = ws.Range("B5:D5") ' 需求
Set costRng = ws.Range("B2:D4") ' 成本
Dim m As Integer, n As Integer: m = supplyRng.Rows.Count: n = demandRng.Columns.Count
Dim supply() As Double, demand() As Double, cost() As Double, allocation() As Double
ReDim supply(0 To m - 1), demand(0 To n - 1), cost(0 To m - 1, 0 To n - 1), allocation(0 To m - 1, 0 To n - 1)
' 讀取資料
Dim i As Integer, j As Integer, k As Integer
For k = 0 To m - 1: supply(k) = supplyRng.Cells(k + 1, 1).Value: Next
For k = 0 To n - 1: demand(k) = demandRng.Cells(1, k + 1).Value: Next
For i = 0 To m - 1
For j = 0 To n - 1: cost(i, j) = costRng.Cells(i + 1, j + 1).Value: Next
Next i
Dim totalCost As Double: totalCost = 0
Do While i < m + n
' 找最低成本位置 (排除已滿足行列)
Dim minCost As Double: minCost = 1E+30
Dim minI As Integer, minJ As Integer
For i = 0 To m - 1
If supply(i) > 0 Then
For j = 0 To n - 1
If demand(j) > 0 And cost(i, j) < minCost Then
minCost = cost(i, j): minI = i: minJ = j
End If
Next j
End If
Next i
If minCost = 1E+30 Then Exit Do
Dim amount As Double: amount = WorksheetFunction.Min(supply(minI), demand(minJ))
allocation(minI, minJ) = amount
totalCost = totalCost + amount * minCost
supply(minI) = supply(minI) - amount
demand(minJ) = demand(minJ) - amount
Loop
' 輸出
ws.Range("G1").Value = "最小成本法": ws.Range("H1").Value = "總成本": ws.Range("I1").Value = totalCost
For i = 0 To m - 1
For j = 0 To n - 1: ws.Cells(i + 2, 7 + j).Value = allocation(i, j): Next
Next i
MsgBox "最小成本法完成!總成本: " & Format(totalCost, "#,##0") '[web:42]
End Sub
VBA 使用操作步驟:
準備工作:
開啟 EXCEL 並建立資料表
準備運輸表:成本矩陣放在 B2:D4(以此例為 3×3)
供給量放在 E2:E4(對應三個供應地)
需求量放在 B5:D5(對應三個需求地)
確認總供給 = 總需求(平衡問題)
進入 VBA 編輯環境
按 Alt + F11 開啟 VBA 編輯器
在左邊專案視窗中,找到你的工作簿,右鍵點選 → 插入 → 模組
新建模組會出現在右邊編輯區
貼上程式碼
將上方「西北角法」或「最小成本法」的完整程式碼複製
貼到 VBA 編輯器的新模組中
如果使用自己的範圍,記得修改這三行:
Set supplyRange = ws.Range("E2:E4") ' 改成你的供給範圍
Set demandRange = ws.Range("B5:D5") ' 改成你的需求範圍
Set costRange = ws.Range("B2:D4") ' 改成你的成本矩陣範圍
執行程式
方法一:在編輯器中執行
點選程式碼任意位置
按 F5 或點選功能表「執行」→「執行副程式」
選擇要執行的副程式(如 NorthwestCornerMethod)
方法二:從 EXCEL 執行
關閉 VBA 編輯器(Alt + F11)
在 EXCEL 功能表:「開發人員」→「巨集」
選擇副程式名稱(如 NorthwestCornerMethod)→「執行」
若沒看到「開發人員」標籤,需先在「檔案」→「選項」→「自訂功能區」打勾啟用
方法三:建立快速鍵(選擇性)
在 EXCEL「開發人員」→「巨集」
選擇副程式 → 「選項」
在「快速鍵」欄位輸入(如 Ctrl+Shift+N)
日後可直接用快速鍵執行
檢查結果
程式執行完後,會跳出訊息框顯示「計算完成!總成本:XXXX」
點「確定」後,回到工作表
P.S 範例引用 全華 管理數學(第八版)(附範例光碟) 王妙伶 9789865037697,好書一本多多使用
沒有留言:
張貼留言