我有一个矩阵(分别为0和1),代表城堡的城墙及其周围环境。

我的任务是以某种方式将n弓箭手放在墙上,使他们尽可能地覆盖周围的环境。有两个规则:

1 :每个弓箭手的射程均为1-也就是说,他只能在相邻的地砖(每个地砖有8个邻居)上射击,而该地不是墙(这支军队禁止友好射击!)。

2 :如果发生这种情况,则多个弓箭手可以在同一块地上射击,该地块仅算作一个。

我正在努力寻找有效的解决方案-部分原因是我不知道多项式时间是否存在。 有吗?

我想第一步是使用BFS算法对矩阵上的每个图块进行评分,但是我不知道如何用第二条规则有效地解决它。蛮力解决方案非常简单-给每个位置评分,然后尝试所有位置,这将是非常无效的-我认为O(|可能的位置| ^ n)不好。

简单示例:

灰色瓷砖代表墙壁。磁贴中的数字表示放置在该磁贴上的弓箭手的覆盖范围。可以肯定的是,我添加了橙色的那些,它们代表了站在b2上的弓箭手的覆盖范围。最后一个信息-对此的正确解决方案是b2和b6,覆盖范围为14。它不能是b2和b4,因为它们仅覆盖11个图块。

algorithm - 将弓箭手放在墙上-LMLPHP

最佳答案

我看不到如何在保证的多项式时间内解决问题,但是您可以将问题表达为整数线性程序,可以使用ILP求解器(例如GLPK)来解决。

c[i]为0-1整数变量,周围的每平方代表一个整数。这些将代表该广场是否至少被一个弓箭手覆盖。

a[i]为0-1整数变量,城堡墙的每平方一个。这些将代表弓箭手是否站在这个广场上。

最多必须有n弓箭手:sum(a[i] for i in castle walls) <= n
如果没有相邻的弓箭手,则c[i]必须为零:sum(a[j] for j castle wall adjacent to i) >= c[i]
优化目标是最大化sum(c[i])

例如,假设这是 map (其周围是.#城堡墙),并且想要放置两个弓箭手。

....
.###
....

然后我们有这个ILP问题,其中所有变量都是0-1整数变量。
maximize (
      c[0,0] + c[0,1] + c[0,2] + c[0,3]
    + c[1,0]
    + c[2,0] + c[2,1] + c[2,2] + c[2,3])

such that:

a[1,1] + a[1,2] + a[1,3] <= 2

c[0,0] <= a[1,1]
c[0,1] <= a[1,1] + a[1,2]
c[0,2] <= a[1,1] + a[1,2] + a[1,3]
c[0,3] <= a[1,2] + a[1,3]
c[1,0] <= a[1,1]
c[2,0] <= a[1,1]
c[2,1] <= a[1,1] + a[1,2]
c[2,2] <= a[1,1] + a[1,2] + a[1,3]
c[2,3] <= a[1,2] + a[1,3]

关于algorithm - 将弓箭手放在墙上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36833838/

10-11 17:59