Backtracking method to solve eight-digit python

The artificial intelligence homework this time was to use the backtracking method to solve the eight-digit problem. After more than a day of work, I finally wrote it out. The following is the topic

The backtracking method is an important blind search algorithm in the field of artificial intelligence. What is a blind algorithm? It is based on rules and constantly trying possible paths until the target solution is reached.
The backtracking method (exploration and backtracking method) is a optimization search method, also known as the heuristic method, which searches forward according to the optimization conditions to achieve the goal. But when you reach a certain step in the exploration and find that the original choice is not optimal or cannot achieve the goal, you will take a step back and make another choice. This technique of going back and trying again when it doesn't work is the backtracking method, and the point in a certain state that satisfies the backtracking conditions Called the "backtrack point".

The backtracking method generally requires three tables,
the ps table : used to save the state of the current path. If the target state is found, ps is an ordered set of states on the problem-solving path.
nps table : new path status table. It contains states waiting to be searched, whose descendant states have not yet been searched, that is, no extensions have been generated.
NSS table : Unsolvable state set, which lists the states in which the solution path cannot be found. If the state expanded during the search is an element of the table, the state will be excluded.
In addition, there is a condition for the solution of the eight-digit number, that is, the parity of the reverse numbers of the initial state and the target state is the same.
Reverse numbers: A state is expressed in a one-dimensional form. Find the sum of the reverse numbers of all numbers except 0, that is, the sum of the numbers before each number that is greater than it. This is called the reverse sequence of this state.
The schematic diagram of the search process of the backtracking method is as follows:
Write the picture description here.
The starting point of the search is the initial value of A: ps=[A], nps=[A], nss=[], and the target point is G.

0 Search points ps nps nss
1 A [A] [A] [ ]
2 B [BA] [BCDA] [ ]
3 E [EBA] [EFBCDA] [ ]
4 I [IJEBA] [IJEFBCD] [ ]
5 J [JEBA ] [JEFBCDA] [I]
6 F [FBA] [FBCDA] [EJI]
7 K [KFBA] [KFBCDA] [EJI]
8 C [CA] [CDA] [BFKEJI]
9 G [GCA] [GHCDA] [BFKEJI ]
During the search process, first conduct a depth search until the pointing depth is reached, or the unsolvable point returns, and the state is set to the unsolvable point, and then returns to the previous node for expansion. Until the result is found or all depths are searched.
The same goes for the backtracking method to realize the eight-digit idea.
Initial state:
2 8 3
1 6 4
7 0 5

Target state:
1 2 3
8 0 4
7 6 5

The following is the python code. The digital status is represented by a one-dimensional array.
The node status class Node.py

#encoding:utf-8
from Node import *
class back:
    def __init__(self,orignate,target,length):
        self.origate=orignate  #初始状态
        self.target=target  #目标状态
        self.ps=[]  #PS表,用于保存当前搜索路径的状态
        self.nps=[] #nps表,用于保存等待搜索的状态
        self.nss=[] #nss表,用于保存不可到达目的地的状态集
        self.spce=[-3,3,-1,1] #上下左右四个移动方向
        self.length=length
        self.MaxDegree=5  #深度限制,到达此深度回溯

    def issolve(self): #判断到目标状态是否有解
        targetVer=self.getreVersNum(self.target.state)
        orinateVer=self.getreVersNum(self.origate.state)
        if(targetVer%2!=orinateVer%2):
            return False
        else:
            return True



    def getreVersNum(self,state):  #获取逆序数
        sum=0
        for i in range(0,len(state)):
            if(state[i]==0):
                continue
            else:
                for j in range(0,i):
                    if(state[j]>state[i]):
                        sum+=1

        return sum

    # def getspaceIndex(self): #获得空格所在的位置
    # for i in range(len(self.origate)-1):
    # if(self.origate[i]==0):
    # return i

    def copyArray(self,state):
        arr=[]
        return arr+state


    #判断状态数码是否存在
    def isexit(self,node,table):
        for i in table:
            if(i.state==node.state):
                return True
        return False




    #主要算法,回溯过程
    def backMainProcess(self):
        self.ps.append(self.origate)
        self.nps.append(self.origate)
        while(len(self.nps)):
            originateState=self.ps[-1]

            spacIndex=originateState.state.index(0)
            if(originateState.state==self.target.state):
                return True
            else:

                #到达指定深度,回溯
                if(originateState.degree>=self.MaxDegree):


                    self.ps.pop()
                    self.nps.pop()
                    if(self.nps[-1]!=self.ps[-1]):

                      self.ps.append(self.nps[-1])
                    self.nss.insert(0,originateState)
                    continue
                flag=False
                for i in range(len(self.spce)):

                    if((i==0 and (spacIndex+self.spce[i])>=0) or
                    (i==1 and (spacIndex+self.spce[i])<len(self.target.state)-1)
                    or(i==2 and (spacIndex%self.length!=0 )) or
                    (i==3 and ((spacIndex+1)%self.length)!=0)):
                        state=self.copyArray(originateState.state)
                        #扩展状态
                        temp=state[spacIndex+self.spce[i]]
                        state[spacIndex+self.spce[i]]=0
                        state[spacIndex]=temp
                        #判断新的状态是否已经存在
                        nodeState=Node(state,originateState.degree+1)

                        if(self.isexit(nodeState,self.nps))or (self.isexit(nodeState,self.nss)):
                            continue
                        else:
                            flag=True

                            self.nps.append(nodeState)
                if(not flag):

                    self.ps.pop()
                    self.nps.pop()
                    if(self.nps[-1]!=self.ps[-1]):
                      self.ps.append(self.nps[-1])
                    self.nss.append(originateState)
                if(flag):#展开有子节点
                    self.ps.append(self.nps[-1])
    #输出结果路径
    def showLine(self):
        for node in self.ps:
            i=0
            print(node.state[i],node.state[i+1],node.state[i+2])
            print(node.state[i+3],node.state[i+4],node.state[i+5])
            print(node.state[i+6],node.state[i+7],node.state[i+8])
            print('->:')








if __name__ == '__main__':


    originate=[2,8,3,1,6,4,7,0,5]
    target=[1,2,3,8,0,4,7,6,5]
    node1=Node(originate,0)
    node2=Node(target,0)
    c=back(node1,node2,3)
    if(c.issolve()):
        if(c.backMainProcess()):
            print('已找到解!!!!,路径如下')
            c.showLine()
    else:
        print('此过程无解')

operation result:

已找到解!!!!,路径如下
(2, 8, 3)
(1, 6, 4)
(7, 0, 5)
->:
(2, 8, 3)
(1, 0, 4)
(7, 6, 5)
->:
(2, 0, 3)
(1, 8, 4)
(7, 6, 5)
->:
(0, 2, 3)
(1, 8, 4)
(7, 6, 5)
->:
(1, 2, 3)
(0, 8, 4)
(7, 6, 5)
->:
(1, 2, 3)
(8, 0, 4)
(7, 6, 5)
->:

Guess you like

Origin blog.csdn.net/qq_41563601/article/details/123504720