我在攻读研究生算法课时遇到了这个问题:
假设您要在p
个城市中放置n
塔,其中每个城市都是1到n之间的整数。放置塔楼的成本是从塔楼到其他城市的预期距离。问题是提供一种有效的算法来放置所有p
塔,同时最大限度地降低成本。
这里有一种贪婪的方法:https://www.mssanz.org.au/modsim2015/J11/dzator.pdf,但它看起来效率不高。
到目前为止,我已尝试使用动态编程来解决问题。例如,如果有1个塔楼和5个城市,我会通过每个城市作为塔楼的潜在候选人,并计算将塔楼放置在那里的成本。然后,我选择最小化成本的城市。
但是,当有2座或更多塔楼时,我无法跟进。我试图将城市分成不同的,连续的子集,但我似乎无法从中取得进展 - 即我似乎无法识别子问题。
任何指针?
编辑:
塔的成本完全如问题所述:它是从塔的位置到城市的距离。然而,放置塔楼将影响其他塔楼的放置方式,因为特定城市的人们将前往最近的塔楼。
答案 0 :(得分:1)
根据您的链接判断,您要做的是将p
塔放置在n
个不同大小的均匀间隔的城市中,其中i
城市的大小为,s(i)
。您希望最小化每个人到最近的塔的平均距离。或者,等效地,最小化从人到塔的距离的总和。
我说错了吗?
如果是这样,子问题是将k
塔放在两个标记i
和j
之间(这些标记位于城市之间或不同之处),以便距离总和从人到塔是最低限度的。作为进一步的限制,k
是2的幂,否则标记离开地图的右边缘,k
是n
的二进制表示的尾端
对于每个子问题,如果1 < k
,则信息是分割成较小子问题的最佳位置,否则它是k = 1
的塔的放置位置。 (记住,如果k
是2的幂,我们会均匀地拆分塔,否则,如果我们的范围偏离右边缘,k
是O(log(p) * n^2)
,则分成2的幂和表示的其余部分不是2的力量。)
需要考虑<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row border-bottom white-bg dashboard-header">
<div class="col-xs-3 col-md-3">
<h4>Dummy Name</h4>
<small>Dummy Street</small><br>
<small>Dummy Apt, Some City, Some State</small><br>
<small>United States</small><br>
</div>
<div class="col-xs-3 col-md-3">
<h5>123-456-7890</h5>
</div>
<div class="col-xs-3 col-md-3">
<h5>some_name@somecompany.com</h5>
</div>
<div class="col-xs-3 col-md-3 text-right">
<h2>Active</h2><br>
<button type="button" class="btn btn-w-m btn-primary">Primary</button>
</div>
</div>
</div>
</div>
个子问题,这应该完全适合动态编程,可以自上而下或自下而上实现。
答案 1 :(得分:1)
一次增加一个塔并遍历所有城市。让g(i)
成为将塔放置在i
位置的费用 - 根据您的帖子,此功能取决于塔楼和城市的位置,后者已经修复。我将把这个计算的细节留给读者。
让m(t,i)
成为将t
塔放到索引i
的费用。然后一般情况是:
m(t, i) = min(
// Place a tower at i
g(i) + m(t - 1, i - 1),
// Do not place a tower at i
m(t, i - 1)
)
正如我们所看到的,在自下而上的方法中,m
中的两个查找都已经被记录,因为我们正在迭代增加数量的塔,每次从第一个城市到最后一个城市位置
由于这个问题现在有了额外的信息,“放置一座塔将影响其他塔楼的放置方式,因为某个城市的人们将前往他们最近的塔楼”,这是一个O(t * n^2)
公式。让f(t, i)
代表放置在t
的{{1}}塔,i
代表c[i]
城市,i
代表d(c, t)
距离/成本函数城市c
到t
的塔楼。然后,从左到右迭代:
f(t, i) =
if t is the leftmost tower:
// cities left of t
sum d(c[0..i], i)
otherwise:
min(
// cities right of and closer to (t - 1)
sum d(c[l..m], l) +
// cities left of and closer to t
sum d(c[m+1..i], i)
if t is the rightmost tower, also add:
// cities right of t
sum d(c[i..last c], i) +
where l is the location of the neighbouring tower
to the left and m is the middle city, closer to l
)
for all l
for all i