用Python写八数码问题

来源:互联网 发布:苹果内购验证 java 编辑:程序博客网 时间:2024/06/05 17:45

这两天学习了下Python这个脚本语言,语法简单且丰富。

尝试用Python写了个八数码问题的算法,很方便就写出来了。

使用广度优先算法,改进了下,搜索下一个节点时评估一下,这样速度会快很多。

# coding=utf-8'''Created on 2014年12月18日@author: osborn'''#实现字符串任两个位置的字符交换def switchchar(str, p1, p2):    left = p1    right = p2    if(p1 > p2):        left = p2        right = p1    elif(p1 == p2):        return str    lstr = ""    rstr = ""    mstr = ""    if(left == 0):        lstr = ""    else:        lstr = str[:left]    if(right == len(str) - 1):        rstr = ""    else:        rstr = str[right + 1:]    if((right - left) == 1):        mstr = ""    else:        mstr = str[left + 1: right]    return lstr + str[right] + mstr + str[left] + rstr# 用对象表示状态点    class StateNode:    def __init__(self, value, dstvalue, step):        self.value = value        self.index = value.find("*")        self.assess = 0        self.dstvalue = dstvalue        if(self.index < 0):            print(self.tostring() + " error")            raise RuntimeError        for i in range(len(value)):            if(value[i] == dstvalue[i]):                self.assess += 1        self.step = step                def tostring(self):        return "Node:{0} assess={1} step={4}\n     {2}\n     {3}\n".format(self.value[:3], self.assess, self.value[3:6], self.value[6:],self.step)    def left(self):        if(self.index % 3 != 0):            return StateNode(switchchar(self.value, self.index -1, self.index), self.dstvalue, self.step +1)    def right(self):        if(self.index % 3 != 2):            return StateNode(switchchar(self.value, self.index +1, self.index), self.dstvalue, self.step +1)            def up(self):        if(self.index > 2):            return StateNode(switchchar(self.value, self.index -3, self.index), self.dstvalue, self.step +1)            def down(self):        if(self.index < 6):            return StateNode(switchchar(self.value, self.index +3, self.index), self.dstvalue, self.step +1)    def calc(startval, endval):    startNode = StateNode(startval, endval, 0)    openlist = [startNode]    closelist = []    while True:        #评估,使用assess值        openlist = sorted(openlist, key=lambda node: node.assess)        curNode = openlist.pop()        if(curNode == None):            print("End")            return             print(curNode.tostring())                if(curNode.assess == 9):            print("Found,end!")            return                leftNode = curNode.left()        rightNode = curNode.right()        upNode = curNode.up()        downNode = curNode.down()        if(leftNode != None):            exist = False            for node in openlist:                if(leftNode.value == node.value):                    exist = True                    break            for node in closelist:                if(leftNode.value == node.value):                    exist = True                    break            if(not exist):                openlist.append(leftNode)            if(rightNode != None):            exist = False            for node in openlist:                if(rightNode.value == node.value):                    exist = True                    break            for node in closelist:                if(rightNode.value == node.value):                    exist = True                    break            if(not exist):                openlist.append(rightNode)                    if(upNode != None):            exist = False            for node in openlist:                if(upNode.value == node.value):                    exist = True                    break            for node in closelist:                if(upNode.value == node.value):                    exist = True                    break            if(not exist):                openlist.append(upNode)                    if(downNode != None):            exist = False            for node in openlist:                if(downNode.value == node.value):                    exist = True                    break            for node in closelist:                if(downNode.value == node.value):                    exist = True                    break            if(not exist):                openlist.append(downNode)                    closelist.append(curNode)         if __name__ == '__main__':    calc("12345678*","*12345678")

这段代码只是找出正确解,但是没有找最优解。

有时间我会研究下A*算法,找最优解。

0 0