【问题标题】:What is the flaw in this algorithm?这个算法有什么缺陷?
【发布时间】:2016-08-03 03:53:16
【问题描述】:

我正试图找出问题是在实施我的算法时,以尽可能低的成本将 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)

 }

谁能告诉我为什么这不起作用?

【问题讨论】:

标签: c# algorithm performance optimization greedy


【解决方案1】:

您的算法是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,但如果地雷数量很大,这可能会变得棘手

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-29
      • 2015-07-06
      • 2020-06-06
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      相关资源
      最近更新 更多