这个算法有什么缺陷?

时间:2016-08-03 03:53:16

标签: c# algorithm performance optimization greedy

我试图弄清楚我的算法实施的问题是什么,以尽可能最低的成本将N金矿合并到K,其中的成本是从一个矿到另一个矿的黄金等于它们之间的距离乘以矿源中的黄金重量。

我的算法示例:

我们说我们有以下N=3地雷

A = { Distance = 10, Gold = 2 }
B = { Distance = 12, Gold = 1 }
C = { Distance = 15, Gold = 1 } 

我们希望将黄金合并到K=1矿井中。第一次合并黄金的成本如下:

Cost(B,A) = |12 - 10| * 1 = 2
Cost(B,C) = |12 - 15| * 1 = 3
Cost(C,B) = |15 - 12| * 1 = 3
Cost(A,B) = |10 - 12| * 2 = 4
Cost(C,A) = |15 - 10| * 1 = 5
Cost(A,C) = |10 - 15| * 2 = 10

因此,让我们进行首次合并,将黄金从B移至A

我们的总费用是2,我们的地雷看起来像

A = { Distance = 10, Gold = 3 }
C = { Distance = 15, Gold = 1 } 

我们的订单成本是

Cost(C,A) = |15 - 10| * 1 = 5
Cost(A,C) = |10 - 15| * 3 = 15

(请注意我们如何从我们的费用列表中删除任何涉及B的费用,因为它现在已经消失了。)

我们的下一次合并再次是有序的成本列表中的第一个元素。

进行合并后,将折叠从C移至A,我们的总费用现为2 + 5 = 7,我们的地雷

A = { Distance = 10, Gold = 4 }

因为该组的大小为K=1,所以我们已经完成了。

泛化伪代码:

 Mines = list of mines, 
 K = desired number mines,
 sum = 0
 while(Mines.Count != K)
 {
     Find m1,m2 in Mines such that Cost(m1,m2) is minimized

     sum += Cost(m1,m2)

     m2.Gold += m1.Gold

     Mines.Remove(m1)

 }

有人可以告诉我为什么这不起作用吗?

2 个答案:

答案 0 :(得分:2)

您的算法是greedy algorithm。做出本地最佳选择并不总是最好的。

在这种情况下,您的算法找不到最佳解决方案

A = { Distance = 10, Gold = 1 }
B = { Distance = 0, Gold = 10 }
C = { Distance = 15, Gold = 2 } 

对正确解决方案的直观猜测是将AC移至B,因为B有很多难以移动的黄金。但是,您的算法首先将A局部最优移动到C。然后,必须遵循CB,总费用为5 + 45 = 50

更好的解决方案是将A移至B然后C移至B,费用为10 + 30 = 40

解决这些问题并不总是很容易,一种方法是执行brute-force search,但如果地雷数量很大,这会变得难以处理

答案 1 :(得分:1)

必须来自:https://www.hackerrank.com/challenges/mining

这也可以使用混合整数编程模型轻松建模。给定数据c(i,j)(将所有黄金从i移动到j的成本)和k(合并点数)我们可以写:

enter image description here

如果我们将事物从i移动到j(否则为0),x(i,j)为1。 y(j)=1如果我们选择我的j作为合并点(否则为0)。可以使用任何MIP求解器解决此模型。