我有一个矩阵(0和1),代表城墙和周围环境。
我的任务是以某种方式将n
弓箭手放在墙上,以尽可能多地覆盖周围环境。有两条规则:
1 :每个射手的射程都是1 - 这意味着,他只可以在相邻的地砖上射击(每个地块都有8个邻居),这不是围墙(此军队禁止友军射击) !)。
2 :如果发生这种情况,多个弓箭手可以在同一个牌上进行射击,那个牌只计为一个。
我正在努力为此找到有效的解决方案 - 部分是因为我不知道,如果在多项式时间内存在任何问题。 有没有?
我猜第一步是使用BFS算法对矩阵上的每个图块进行评级,但我不知道如何使用第二个规则有效地解决它。蛮力解决方案非常简单 - 评估每个位置,然后尝试所有这些,这将是非常非常无效的 - 我认为O(|可能的位置| ^ n),这是不好的。
简单示例:
灰色瓷砖代表墙壁。瓷砖内的数字表示放置在该瓷砖上的射手的覆盖范围。可以肯定的是,我添加了橙色,代表了位于瓷砖b2上的弓箭手的覆盖范围。最后的信息 - 正确的解决方案是b2和b6,覆盖率为14.它不能是b2和b4,因为它们只覆盖了11个瓷砖。
答案 0 :(得分:5)
我不知道如何在保证多项式时间内解决问题,但您可以将问题表达为整数线性程序,可以使用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])
。
例如,假设这是地图(.
所在的地方,#
城堡墙),并且想要放置两个弓箭手。
....
.###
....
然后我们有这个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]