Mathematica Integer Linear Programming โดยใช้สาขาและขอบเขต
ตามที่ได้รับการกล่าวถึงปัญหานี้สามารถแก้ไขได้โดยใช้การเขียนโปรแกรมเชิงเส้นจำนวนเต็ม (ซึ่งเป็นNP-Hard ) Mathematica มี ILP ในตัวอยู่แล้ว"To solve an integer linear programming problem Mathematica first solves the equational constraints, reducing the problem to one containing inequality constraints only. Then it uses lattice reduction techniques to put the inequality system in a simpler form. Finally, it solves the simplified optimization problem using a branch-and-bound method."
[ดูการสอนการเพิ่มประสิทธิภาพข้อ จำกัดใน Mathematica]
ฉันได้เขียนรหัสต่อไปนี้ซึ่งใช้ไลบรารี ILP ของ Mathematica มันเร็วอย่างน่าประหลาดใจ
solveMatrixBombProblem[problem_, r_, c_] :=
Module[{},
bombEffect[x_, y_, m_, n_] :=
Table[If[(i == x || i == x - 1 || i == x + 1) && (j == y ||
j == y - 1 || j == y + 1), 1, 0], {i, 1, m}, {j, 1, n}];
bombMatrix[m_, n_] :=
Transpose[
Table[Table[
Part[bombEffect[(i - Mod[i, n])/n + 1, Mod[i, n] + 1, m,
n], (j - Mod[j, n])/n + 1, Mod[j, n] + 1], {j, 0,
m*n - 1}], {i, 0, m*n - 1}]];
X := x /@ Range[c*r];
sol = Minimize[{Total[X],
And @@ Thread[bombMatrix[r, c].X >= problem] &&
And @@ Thread[X >= 0] && Total[X] <= 10^100 &&
Element[X, Integers]}, X];
Print["Minimum required bombs = ", sol[[1]]];
Print["A possible solution = ",
MatrixForm[
Table[x[c*i + j + 1] /. sol[[2]], {i, 0, r - 1}, {j, 0,
c - 1}]]];]
สำหรับตัวอย่างที่ให้ไว้ในปัญหา:
solveMatrixBombProblem[{2, 3, 4, 7, 1, 1, 5, 2, 6, 2, 4, 3, 4, 2, 1, 2, 1, 2, 4, 1, 3, 1, 3, 4, 1, 2, 1, 4, 3, 2, 6, 9, 1, 6, 4}, 7, 5]
เอาท์พุท
สำหรับทุกคนที่อ่านข้อความนี้ด้วยอัลกอริทึมโลภ
ลองใช้รหัสของคุณกับปัญหา 10x10 ต่อไปนี้:
5 20 7 1 9 8 19 16 11 3
17 8 15 17 12 4 5 16 8 18
4 19 12 11 9 7 4 15 14 6
17 20 4 9 19 8 17 2 10 8
3 9 10 13 8 9 12 12 6 18
16 16 2 10 7 12 17 11 4 15
11 1 15 1 5 11 3 12 8 3
7 11 16 19 17 11 20 2 5 19
5 18 2 17 7 14 19 11 1 6
13 20 8 4 15 10 19 5 11 12
ที่นี่คั่นด้วยจุลภาค:
5, 20, 7, 1, 9, 8, 19, 16, 11, 3, 17, 8, 15, 17, 12, 4, 5, 16, 8, 18, 4, 19, 12, 11, 9, 7, 4, 15, 14, 6, 17, 20, 4, 9, 19, 8, 17, 2, 10, 8, 3, 9, 10, 13, 8, 9, 12, 12, 6, 18, 16, 16, 2, 10, 7, 12, 17, 11, 4, 15, 11, 1, 15, 1, 5, 11, 3, 12, 8, 3, 7, 11, 16, 19, 17, 11, 20, 2, 5, 19, 5, 18, 2, 17, 7, 14, 19, 11, 1, 6, 13, 20, 8, 4, 15, 10, 19, 5, 11, 12
สำหรับปัญหานี้ทางออกของฉันมี208ระเบิด นี่เป็นวิธีแก้ปัญหาที่เป็นไปได้ (ฉันสามารถแก้ไขได้ในเวลาประมาณ 12 วินาที)
เป็นวิธีการทดสอบผลลัพธ์ที่ Mathematica ผลิตดูว่าอัลกอริทึมโลภของคุณสามารถทำได้ดีกว่านี้หรือไม่