我一直在尝试解决麻省理工学院的计算机科学数学习题集,这里有一个问题:
Each monk entering the Temple of Forever is given a bowl with 15 red beads and 12 green beads. Each time the Gong of Time rings, a monk must do one of two things:
- Exchange: If he has 3 red beads in his bowl, then he may exchange 3 red beads for 2 green beads.
- Swap: He may replace each green bead in his bowl with a red bead and replace each red bead in his bowl with a green bead. That is, if he starts with i red beads and j green beads, then after he performs this operation, he will have j red beads and i green beads.
A monk may leave the Temple of Forever only when he has exactly 5 red beads and 5 green beads in his bowl.
这其中有一些子问题:
在花了相当长的时间思考子问题3之后,我放弃了,决定写一个程序来计算唯一状态的数量
class Node:
def __init__(self, r, g):
self.r = r
self.g = g
def swap(self):
if self.g <= 0 or self.r <= 0:
return None
return Node(self.g, self.r)
def exchange(self):
if self.r >= 3:
return Node(self.r - 3, self.g + 2)
return None
def __hash__(self):
return hash((self.r, self.g))
def __eq__(self, other):
if self is None and other is None:
return True
if self is None or other is None:
return False
return self.r == other.r and self.g == other.g
def __repr__(self):
return "({}, {})".format(self.r, self.g)
start = Node(15, 12)
queue = []
graph = []
visited = set()
queue.append(start)
while (queue):
curr = queue.pop(0)
visited.add(curr)
graph.append(curr)
s = curr.swap()
e = curr.exchange()
for el in [s, e]:
if el != None:
if el not in visited:
queue.append(el)
print(visited, len(visited))
我从程序中得到的答案是
{(6, 9), (16, 9), (0, 7), (2, 5), (8, 5), (5, 8), (10, 8), (10, 7), (16, 3), (5, 18), (0, 17), (14, 1), (8, 15), (10, 13), (4, 16), (9, 16), (7, 5), (14, 2), (13, 10), (3, 1), (6, 13), (20, 3), (3, 11), (4, 12), (10, 3), (6, 14), (7, 15), (18, 5), (3, 6), (8, 6), (4, 1), (9, 7), (6, 4), (11, 4), (16, 4), (5, 17), (11, 9), (0, 18), (14, 6), (13, 6), (19, 2), (18, 6), (1, 19), (15, 7), (0, 8), (4, 11), (3, 5), (4, 6), (9, 2), (5, 7), (4, 17), (11, 3), (7, 4), (14, 12), (12, 4), (19, 1), (3, 15), (1, 3), (5, 13), (3, 21), (11, 14), (12, 9), (18, 1), (15, 12), (2, 19), (3, 10), (1, 14), (8, 10), (9, 11), (3, 16), (8, 16), (11, 13), (0, 22), (17, 5), (6, 18), (7, 14), (12, 14), (19, 6), (15, 3), (2, 20), (1, 4), (0, 12), (1, 9), (4, 2), (2, 14), (9, 6), (5, 3), (6, 8), (11, 8), (16, 8), (14, 7), (13, 5), (1, 18), (2, 4), (9, 12), (4, 7), (9, 1), (12, 5), (15, 8), (0, 3), (2, 9), (8, 1), (5, 12), (3, 20), (10, 12), (6, 3), (9, 17), (7, 10), (12, 10), (13, 11), (1, 13), (8, 11), (2, 10), (0, 23), (17, 4), (6, 19), (14, 11), (12, 15), (7, 9), (13, 1), (17, 9), (15, 2), (20, 2), (0, 13), (21, 3), (1, 8), (2, 15), (5, 2), (10, 2)} 129
所以,129。但当我看问题集的解决方案时(对于子问题#3),下面是它的说明
Each move in the sequence must be either an exchange or swap, since these are the only legal moves. Now, whenever the monk performs an exchange operation, the sum r + g decreases by one.
(r - 3) + (g + 2) = (r + g) - 1
In contrast, swaps do not have any effect on the sum. Furthermore, we know that the sum r + g must be at least 3 to perform an exchange operation. Therefore, there can be at most 25 exchange operations in the sequence.
Now consider swap operations: between each pair of exchanges in the sequence, there may be an unlimited number of swaps. However, only a single swap can take the monk to a new state: if at step k the monk is in state (r, g), then at step k + 2, he will return to the same state. Therefore, an upper bound on the number of unique states in any execution of the machine is 25 + 26 + 1 = 52 (if swaps are inserted at both the beginning and end of the sequence).
我的程序哪里出错了?我对问题陈述的理解是否不正确(与我编写的程序不符)?而且,我真的不理解他们给出的解决方案。有更好的解释方法吗?例如,我不了解的一个问题/事情是,解决方案指出,每次交换操作,珠子的总和减少1。因此,我们可以通过交换操作获得25个新的州。但图中每一层的每一个和都可以用多种方式表示,是吗?那么必须有更多的状态是通过exchange操作创建的?这是完整问题集的link,它是solution
由问题中的代码构建的图形连接了每个可能的状态,因此计算了状态机可能的状态总数,但不计算僧侣在执行“永恒之殿”机器时可以访问的唯一状态的最大数量
通过以类似BFS的方式计算节点,我假设可以通过任何其他状态到达每个状态。事实并非如此。交换操作创建新状态后,不可能通过交换(显然)返回到其“父”状态,因此一旦在锣圈做出选择,就不会有任何返回
因此,我们真正需要做的是构建图,从起始节点开始执行DFS,并跟踪在DFS遍历期间实现的最大深度。这个最大深度就是我们想要的解决方案
代码如下:
编辑:根据OP自己的回答和我们在评论中的讨论,这是关键问题:
我们必须区分两个不同的数字:
请注意,N是在任何一条路径中访问的状态集的并集(接管所有可能路径)的基数。这意味着n<;=N,很容易看出这些数字是不相等的。麻省理工学院的问题是关于n,而OP的原始代码是为了找到n
引用的证明是正确的,因此“关于[n]的上限是25+26+1=52”
我尝试了一种蒙特卡罗方法来近似N:只要有选择,就随机决定是交换还是交换,重复这个过程,直到这个过程在(2,0)和(0,2)之间振荡,并且重复所有这一切很多次,同时跟踪所有唯一的访问状态
然而,这似乎并不实际,因为可能路径的数量太多,因此我们得到的数量在任何可行的迭代次数下都不接近N。以下代码在我的机器上已经花费了大约15分钟
被访问国:{(18,0)、(4,7)、(1,3)、(3,0)、(0,2)、(4,12)、(11,14)、(2,5)、(0,3)、(8,5)、(5,8)、(15,12)、(8,1)、(16,3)、(5,18)、(1,14)、(14,1)、(3,16)、(8,16)、(4,1)、(12,14)、(2,20)、(0,18)、(2,10)、(1,4)、(1,19)、(4,2)、(17,4)、(5,3)、(14,11)、(4,6)、(15,2)、(20,2)、(16,8)、(4,17)、(3)、(4)、(1),(14,12),(1,8),(12,4),(2,0),(19,1),(5,2),(2,4),(10,2)}
访问的国家数目:46
更新:这里是完整状态空间的绘图N=140
这是一条访问52个州的路线。绿色的X是起点,每个蓝色的圆圈表示一个访问状态。因为我们从引用的证据中知道,n<;=52,这证明了n=52
相关问题 更多 >
编程相关推荐