所以,我的妻子在Steam上玩Hammerwatch.她遇到了一个难题,我决定尝试编写一个解决方案.
以下是拼图的工作原理:
激活开关可以打开或关闭该开关,也可以切换其相邻的开关.
这是游戏中拼图的YouTube视频:
http://www.youtube.com/watch?v=OM1XD7IZ0cg
我想出了如何让拼图的机制正常工作.我终于意识到我有两个选择让电脑解决这个问题:
A)通过随机选择开关让计算机解决
…要么…
B)创建一种算法,使计算机能够更有效地解决难题.
作为一名新程序员(在CodeAcademy教程的中途,在LPTHW中途,目前正在通过麻省理工学院edX计算机科学Python课程),我觉得我的能力有限,无法解决这个问题.我来学习了!请帮忙!
请帮助:
我需要帮助找出一个更好的方法来随机解决这个问题,甚至更好,有一个算法,让计算机系统地解决这个难题.我唯一能做的就是让计算机将拼图状态存储在列表或字典中,通过跳过这些存储的状态来协助程序,将程序指向新的可能解决方案
当前程序的工作原理:
我打算允许用户使用前9个raw_input输入拼图板的当前状态.然后它进入一个循环,随机切换拼图板的开关,直到它们全部打开.
P.S.:当我注册StackOverflow帐户并输入此消息时,我的计算机一直在后台运行该程序以找到解决方案.大约一个小时,仍然没有找到解决方案,它目前正在进行~92,000,000次迭代.我觉得它不起作用……
import random def switcheroo(x): """ switches 'x' to 1 if it's a 0 and vice-versa """ if x == 0: x = 1 else: x = 0 return x # original input variables a1 = 0 a2 = 0 a3 = 0 b1 = 0 b2 = 0 b3 = 0 c1 = 0 c2 = 0 c3 = 0 # puzzleboard print "\n\n" print " 1 2 3 " print " -------------" print "a |",a1,"|",a2,a3,"|" print " -------------" print "b |",b1,b2,b3,"|" print " -------------" print "c |",c1,c2,c3,"|" print " -------------" print "\n\n" print "What's ON/OFF? (type 0 for OFF,1 for ON)" a1 = int(raw_input("a1: ")) a2 = int(raw_input("a2: ")) a3 = int(raw_input("a3: ")) b1 = int(raw_input("b1: ")) b2 = int(raw_input("b2: ")) b3 = int(raw_input("b3: ")) c1 = int(raw_input("c1: ")) c2 = int(raw_input("c2: ")) c3 = int(raw_input("c3: ")) # for counting the iterations within the loop iteration = 0 # to stop loop if all switches are ON ans = a1 and a2 and a3 and b1 and b2 and b3 and c1 and c2 and c3 while ans == False: # randomly generates number,flipping random switches counter = random.randint(1,9) if counter == 1: switch = "a1" elif counter == 2: switch = "a2" elif counter == 3: switch = "a3" elif counter == 4: switch = "b1" elif counter == 5: switch = "b2" elif counter == 6: switch = "b3" elif counter == 7: switch = "c1" elif counter == 8: switch = "c2" elif counter == 9: switch = "c9" # PUZZLE MECHANICES # if switch == "a1": a1 = switcheroo(a1) a2 = switcheroo(a2) b1 = switcheroo(b1) if switch == "a2": a2 = switcheroo(a2) a1 = switcheroo(a1) a3 = switcheroo(a3) b2 = switcheroo(b2) if switch == "a3": a3 = switcheroo(a3) a2 = switcheroo(a2) b3 = switcheroo(b3) if switch == "b1": b1 = switcheroo(b1) b2 = switcheroo(b2) a1 = switcheroo(a1) c1 = switcheroo(c1) if switch == "b2": b2 = switcheroo(b2) a2 = switcheroo(a2) b1 = switcheroo(b1) b3 = switcheroo(b3) c2 = switcheroo(c2) if switch == "b3": b3 = switcheroo(b3) b1 = switcheroo(b1) b2 = switcheroo(b2) c3 = switcheroo(c3) # Edit 1 if switch == "c1": c1 = switcheroo(c1) c2 = switcheroo(c2) b1 = switcheroo(b1) if switch == "c2": c2 = switcheroo(c2) c1 = switcheroo(c1) c3 = switcheroo(c3) b2 = switcheroo(b2) if switch == "c3": c3 = switcheroo(c3) c2 = switcheroo(c2) b3 = switcheroo(b3) if switch == "stop": break # prints puzzle-board state at end of loop iteration print "\n\n" print " 1 2 3 " print " -------------" print "a |","|" print " -------------" print "b |","|" print " -------------" print "c |","|" print " -------------" print "\n\n" # prints which # was randomly generated print "random #: ",counter # tracks loop iteration iteration += 1 print "iteration",iteration if ans == True: print "I figured it out!"
解决方法
假设您正在解决3×3问题,并且变量设置如下:
x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9
这个初始状态是:
a_1 a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9
现在,您可以写下解决方案必须满足的一些方程式(算术模2).它基本上编码关于哪些开关导致特定灯光切换的规则.
a_1 = x_1 + x_2 + x_4 a_2 = x_1 + x_2 + x_3 + x_5 ... a_5 = x_2 + x_4 + x_5 + x_6 + x_8 ... a_9 = x_6 + x_8 + x_9
现在你可以使用高斯消元法来解决这组联立方程.因为你在算术模2中工作,它实际上比实数上的联立方程更容易.例如,要删除第二个等式中的x_1,只需将第一个等式添加到其中即可.
a_1 + a_2 = (x_1 + x_2 + x_4) + (x_1 + x_2 + x_3 + x_5) = x_3 + x_4 + x_5
具体来说,这是算术模2中的高斯消元算法:
>选择一个带有x_1的等式.将其命名为E_1.
>将E_1添加到其他每个未命名的等式中,其中包含x_1.
>重复x_2,x_3,….,x_n.
现在,E_n是仅包含x_n的等式.您可以将从此处获得的x_n值替换为先前的等式.重复E_ {n-1},E_1.
总的来说,这解决了O(n ^ 3)操作中的问题.
这是一些代码.
class Unsolvable(Exception): pass def switches(n,m,vs): eqs = [] for i in xrange(n): for j in xrange(m): eq = set() for d in xrange(-1,2): if 0 <= i+d < n: eq.add((i+d)*m+j) if d != 0 and 0 <= j+d < m: eq.add(i*m+j+d) eqs.append([vs[i][j],eq]) N = len(eqs) for i in xrange(N): for j in xrange(i,N): if i in eqs[j][1]: eqs[i],eqs[j] = eqs[j],eqs[i] break else: raise Unsolvable() for j in xrange(i+1,N): if i in eqs[j][1]: eqs[j][0] ^= eqs[i][0] eqs[j][1] ^= eqs[i][1] for i in xrange(N-1,-1,-1): for j in xrange(i): if i in eqs[j][1]: eqs[j][0] ^= eqs[i][0] eqs[j][1] ^= eqs[i][1] return [(i//m,i%m) for i,eq in enumerate(eqs) if eq[0]] print switches(4,3,([1,0],[0,1,1],0]))
您可以为其指定开关阵列的高度和宽度,以及一次一行的初始状态.它返回您需要按下的开关以关闭所有灯.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。