头歌人工智能原理

盲目搜索 

 

 

def PlayMazz(mazz, start, end):
 
    '''
    走迷宫,从start走到end
    :param mazz: 图
    :param start: 图的起点
    :param end: 图的出口
    '''
 
    # queue为队列,当队列为空或者当前地点为终点时搜索结束
 
    queue =list()
 
    closed=set()
 
    queue.append(start)
 
    #********* Begin *********#
 
    while(queue!=0):
 
        closed.add(queue[0])
 
        if queue[0]==end:
 
            print(end,end='')
 
            break
 
 
 
        else:
 
            print(queue[0],end='')
 
            for i in mazz[queue[0]]:
 
                if i in closed:
 
                    pass
 
                else:
 
                    queue.append( i )
 
 
 
        queue.remove(queue[0])
 
 
 
 
 
    #********* End *********#

启发式搜索 - 扫地机器人最短路径搜索

 

 

from a_star_utils import Node
 
def A_star(map, mapSize, start, end):
 
    '''
    A*算法,从start走到end
    :param map:地图
    :param mapSize:地图大小,例如[10,10]表示地图长10宽10
    :param start:表示出发地,类型为列表,如[1,2]表示出发地为地图中的第1行第2列的方块
    :param end:表示目的地,类型为列表,如[1,2]表示目的地为地图中的第1行第2列的方块
    :return:从出发地到目的地的路径
    '''
 
    openedList = []
 
    #********* Begin *********#
 
    # 获得出发地方块的信息,并将信息保存为node变量
 
    node = map[start[0]][start[1]]  
 
    #********* End *********#
 
    node.distanceFromOri = 0
 
    node.allDistance = 0
 
    #********* Begin *********#
 
    # 将当前方块存到开启列表中
 
    openedList.append (node)
 
    node.added = True
 
    #********* End *********#
 
    while len(openedList) != 0:
 
        node = openedList.pop(0)
 
        node.closed = True
 
        if node.y == end[0] and node.x == end[1]:
 
            finalListNeedReverse = []
 
            while node != None:
 
                finalListNeedReverse.append(node)
 
                node = node.parent
 
            finalListNeedReverse.reverse()
 
            return finalListNeedReverse
 
        neighboursList = []
 
        y = node.y
 
        x = node.x
 
        parentDistanceFromOri = node.distanceFromOri
 
        for needNodey in (y + 1, y, y - 1):
 
            if needNodey < 0 or needNodey >= mapSize[0]:
 
                continue
 
            for needNodex in (x + 1, x, x - 1):
 
                if needNodex < 0 or needNodex >= mapSize[1]:
 
                    continue
 
                needNode = map[needNodey][needNodex]
 
                if needNode.unable == True or needNode.closed == True or needNode.added == True:
 
                    continue
 
                yOffset = needNodey - y
 
                xOffset = needNodex - x
 
                allOffset = yOffset + xOffset
 
                if allOffset == 1 or allOffset == -1:
 
                    distanceFromOri = parentDistanceFromOri + 1
 
                else:
 
                    distanceFromOri = parentDistanceFromOri + 1.4
 
                if needNode in neighboursList:
 
                    # 若新的G值比老的G值低,则更新成老的G值
 
                    if distanceFromOri < needNode.distanceFromOri:
 
                        needNode.distanceFromOri = distanceFromOri
 
                else:
 
                    needNode.distanceFromOri = distanceFromOri
 
                    neighboursList.append(needNode)
 
        for needNode in neighboursList:
 
            needNode.parent = node
 
            # 更新F值
 
            needNode.allDistance = needNode.distanceFromOri + needNode.distanceFromDes
 
            needNode.added = True
 
            openedList.append(needNode)
 
        openedList.sort(key=lambda x: x.allDistance)
 
    return None

 搜索算法应用 - 四皇后问题

 

 

 

def make(mark):
 
    '''
    标记皇后的位置,例如mark[0] = 2, 表示第1行皇后放在第3列的位置
    :param mark: 皇后的位置信息
    :return: 拼接好的结果
    '''
 
    #初始化数组
 
    r = [['X' for _ in range(len(mark))] for _ in range(len(mark))]
 
    #将每一行中皇后的位置用‘Q’代替
 
    for i in mark:
 
        r[i][mark[i]] = 'Q'
 
    #枚举,将原来散的元素连接成字符串
 
    for k, v in enumerate(r):
 
        r[k] = ''.join(v)
 
    return r
 
def FourQueens(mark, cur, ret):
 
    '''
    深度优先搜索的方式求解四皇后问题
    :param mark:表示皇后的位置信息,例如[0,1,3,2]表示棋盘的第1行第1列,第2行第2列,第3行第4列,第4行第3列放置了皇后。例如[1, None, None, None]表示第1行第2列放置了皇后,其他行没有放置皇后。初始值为[None,None,None,None]
    :param cur:表示当前准备在第几行放置皇后,例如`cur=1`时,表示准备在第`2`行放置皇后。初始值为0
    :param ret:表示存放皇后摆放结果的列表,类型为列表。初始值为[]
    :return:无
    '''
 
    if cur == len(mark):
 
        #********* Begin *********#
 
        # 如果当前行是最后一行,记录一个解,并返回结束此次搜索
 
        ret.append(make(mark))
 
        return
 
        #********* End *********#
 
    #试探处理,将当前行的皇后应该在的位置遍历每一列,如果满足条件,递归调用处理下一行
 
    for i in range(len(mark)):
 
        mark[cur], down = i, True
 
        for j in range(cur):
 
            # 当想在当前位置放皇后会与其他皇后冲突时不放置皇后
 
            if mark[j] == i or abs(i-mark[j]) == cur - j:
 
                down = False
 
                break
 
        if down:
 
            # 准备在下一行找能放置换后的位置
 
            FourQueens(mark, cur+1, ret)

 产生式系统

 

 

 

# 动物识别系统
# 自定义函数,判断有无重复元素
def judge_repeat(value, list=[]):
    for i in range(0, len(list)):
        if (list[i] == value):
            return 1
        else:
            if (i != len(list) - 1):
                continue
            else:
                return 0


# 自定义函数,对已经整理好的综合数据库real_list进行最终的结果判断
def judge_last(list):
    for i in list:
        if (i == '23'):
            for i in list:
                if (i == '12'):
                    for i in list:
                        if (i == '21'):
                            for i in list:
                                if (i == '13'):
                                    print("黄褐色,有斑点,哺乳类,食肉类->金钱豹\n")
                                    print("所识别的动物为金钱豹")
                                    return 0
                                elif (i == '14'):
                                    print("黄褐色,有黑色条纹,哺乳类,食肉类->虎\n")
                                    print("所识别的动物为虎")
                                    return 0


        elif (i == '14'):
            for i in list:
                if (i == '24'):
                    print("有黑色条纹,蹄类->斑马\n")
                    print("所识别的动物为斑马")
                    return 0
        elif (i == '24'):
            for i in list:
                if (i == '13'):
                    for i in list:
                        if (i == '15'):
                            for i in list:
                                if (i == '16'):
                                    print("有斑点,有黑色条纹,长脖,蹄类->长颈鹿\n")
                                    print("所识别的动物为长颈鹿")
                                    return 0
        elif (i == '20'):
            for i in list:
                if (i == '22'):
                    print("善飞,鸟类->信天翁\n")
                    print("所识别的动物为信天翁")
                    return 0
        #********* Begin *********#
        elif(i == '22'):
             for i in list:
                 if(i == '4'):
                     for i in list:
                         if(i == '15'):
                             for i in list:
                                 if(i == '16'):
                                     print("不会飞,长脖,长腿,鸟类->鸵鸟\n")
                                     print('所识别的动物为鸵鸟')
                                     return 0
       
       
        # ********* End *********#
        elif (i == '4'):
            for i in list:
                if (i == '22'):
                    for i in list:
                        if (i == '18'):
                            for i in list:
                                if (i == '19'):
                                    print("不会飞,会游泳,黑白二色,鸟类->企鹅\n")
                                    print("所识别的动物企鹅")
                                    return 0

        else:
            if (list.index(i) != len(list) - 1):
                continue
            else:
                print("\n根据所给条件无法判断为何种动物")

 框架表示法

 

#encoding=utf8

def d():
    #********* Begin *********#
    d = {'name':'蔡徐坤','age':'21','hobby':'rap','sex':'male'}
    #********* End *********#
    return d

逻辑表示法

 

 

#encoding=utf8

'''
请将下面代码空缺部分补全
'''
  
def x(p):
    #********* Begin *********#
    if p == '打雷':
        q = '下雨'
    elif p == '动物会飞会下蛋':
        q = '该动物是鸟'
    #********* End *********#
    print(q)

归结反演

 

S = []  # 以列表形式存储子句集S
 
""" 读取子句集文件中子句,并存放在S列表中 - 每个子句也是以列表形式存储 - 以析取式分割 - 例如:~p ∨ ~q ∨ r 存储形式为 ['~p', '~q', 'r'] """
 
 
def readClauseSet(filePath):
    global S
    for line in open(filePath, mode='r', encoding='utf-8'):
        line = line.replace(' ', '').strip()
        line = line.split('∨')
        S.append(line)
 
 
""" - 为正文字,则返回其负文字 - 为负文字,则返回其正文字 """
 
 
def opposite(clause):
    if '~' in clause:
        return clause.replace('~', '')
    else:
        return '~' + clause
 
 
""" 归结 """
 
 
def resolution():
    global S
    end = False
    while True:
        if end: break
        father = S.pop()
        for i in father[:]:
            if end: break
            for mother in S[:]:
                if end: break
                j = list(filter(lambda x: x == opposite(i), mother))
                if j == []:
                    continue
                else:
                    print('\n亲本子句:' + ' ∨ '.join(father) + ' 和 ' + ' ∨ '.join(mother))
                    father.remove(i)
                    mother.remove(j[0])
                    #********** Begin **********#
                    if father == [] and mother == []:
                        print('归结式:NIL')
                        end = True
                    elif father == []:
                        print('归结式:' + ' ∨ '.join(mother))
                    elif mother == []:
                        print('归结式:' + ' ∨ '.join(father))
                    else:
                        print('归结式:' + ' ∨ '.join(father) + ' ∨ ' + ' ∨ '.join(mother))
                    #********** End **********#

模糊推理及其应用

 

 
def ruleMD(stain):
    if stain < 0 or stain > 100:
        return 0.0
    else:  # 当传入的参数在0-100之间时,该处有两种情况
        # 计算MD的结果,并且和同参数下的SD结果相比较,得出一个结果
        if stain >= 0 and stain <= 50:
            return stain / 50.0
        else:
            # 同上的操作,得出结果和同参数下的LD相比较
            return (100 - stain) / 50.0
 
 
def ruleSD(stain):
    # SD部分的rule
    # 当输入的参数0 <= x <= 50, 执行该方法
    result = (50 - stain) / 50.0
    returnMDresult = ruleMD(stain)
    # 传参数到MD中,计算,并比较
    # 1、相同,则返回结果为SD,2、SD的结果大,则返回SD,3、MD的结果大,则返回MD的返回值
    if result < returnMDresult:
        return 2.0
    else:
        return 1.0
 
 
def ruleLD(stain):
    # LD部分的rule
    # 当输入的参数在50 - 100之间时,执行
    result = (stain - 50) / 50
    returnMDresult = ruleMD(stain)
    # 同时将参数传入给MD,同时比较MD方法传回来的参数和该方法求出的值相比较,求出最后的最适合的预测值
    # ********** Begin **********#
    if result < returnMDresult:
        return 2.0
    else:
        return 3.0
    # ********** End **********#
 
 
def ruleMG(oil):
    # 当传入的参数在0 - 100之间时,该处有两种情况
    if oil < 0 or oil > 100:
        return 0  # 当在论域之外时,直接返回无结果
    else:
        if oil >= 0 and oil <= 50:
            return oil / 50.0  # 计算MD的结果,并且和同参数下的SD结果相比较,得出一个结果
        else:
            return (100 - oil) / 50  # 同上的操作,得出结果和同参数下的LD相比较
 
 
def ruleSG(oil):
    if oil < 0 or oil > 50:
        return 0.0
    else:
        # SG部分的rule
        # 当输入的参数0<=x<=50,执行该方法
        result = (50 - oil) / 50.0
        returnMGresult = ruleMG(oil)
        # 传参数到MD中,计算,并比较
        # 1、相同,则返回结果为SD,2、SD的结果大,则返回SD,3、MD的结果大,则返回MD的返回值
        if result < returnMGresult:
            return 2.0
        else:
            return 1.0
 
 
def ruleLG(oil):
    # LD部分的rula
    # 当输入的参数在50 - 100之间时,执行
    # 同时将参数传入给MG,同时比较MG方法传回来的参数和该方法求出的值相比较,求出最后的最适合的预测值
    returnMGresult = ruleMG(oil)
    result = (oil - 50) / 50.0
    # 比较后,得到预测值
    if result < returnMGresult:
        return 2.0
    else:
        return 3.0
 
 
# F函数,总的函数,从该函数中分流到rule的三个函数中
def Function(oil, stain):
    # VS: SD, SG
    # S: MD, SG
    # M: SD, MG     MD, MG     LD, SG
    # L: SD, LG     MD,LG     LD,MG
    # XL: LD, LG
    # 根据规则输出最后的洗涤时间
    # 需要客户的正确输入
    # ********** Begin **********#
    if stain >= 0 and stain <= 50:
        result_D = ruleSD(stain)
    else:
        result_D = ruleLD(stain)
 
    if oil >= 0 and oil <= 50:
        result_G = ruleSG(oil)
    else:
        result_G = ruleLG(oil)
        # ********** End **********#
        # 比较最后的结果,返回结果控制规则表,例如VS在表格中的坐标是(1,1),S的坐标是(2,1)
    if result_D == 1.0 and result_G == 1.0:
        return 1  # return VS
    elif result_G == 1.0 and result_D == 2.0:
        return 2  # return S
    elif (result_D == 1.0 and result_G == 2.0) or (result_G == 2.0 and result_D == 2.0) or (
            result_G == 1.0 and result_D == 3.0):
        return 3  # reutrn M
    elif (result_D == 1.0 and result_G == 3.0) or (result_D == 2.0 and result_G == 3.0) or (
            result_D == 3.0 and result_G == 2.0):
        return 4  # return L
    elif result_G == 3.0 and result_D == 3.0:
        return 5  # return VL
 

A*搜索算法

 

class Array2D:
    """
        说明:
            1.构造方法需要两个参数,即二维数组的宽和高
            2.成员变量w和h是二维数组的宽和高
            3.使用:‘对象[x][y]’可以直接取到相应的值
            4.数组的默认值都是0
    """
 
    def __init__(self, w, h):
        self.w = w
        self.h = h
        self.data = []
        self.data = [[0 for y in range(h)] for x in range(w)]
 
    def showArray2D(self):
        for y in range(self.h):
            for x in range(self.w):
                print(self.data[x][y], end=' ')
            print("")
 
    def __getitem__(self, item):
        return self.data[item]
 
 
class Point:
    """
    表示一个点
    """
 
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
    def __eq__(self, other):
        if self.x == other.x and self.y == other.y:
            return True
        return False
 
    def __str__(self):
        return "x:" + str(self.x) + ",y:" + str(self.y)
 
 
class AStar:
    """
    AStar算法的Python3.x实现
    """
 
    class Node:  # 描述AStar算法中的节点数据
        def __init__(self, point, endPoint, g=0):
            self.point = point  # 自己的坐标
            self.father = None  # 父节点
            self.endPoint = endPoint
            self.g = g  # g值,g值在用到的时候会重新算
            self.h = (abs(endPoint.x - point.x) + abs(endPoint.y - point.y)) * 10  # 计算h值
 
    def __init__(self, map2d, startPoint, endPoint, passTag=0):
        """
        构造AStar算法的启动条件
        :param map2d: Array2D类型的寻路数组
        :param startPoint: Point或二元组类型的寻路起点
        :param endPoint: Point或二元组类型的寻路终点
        :param passTag: int类型的可行走标记(若地图数据!=passTag即为障碍)
        """
        # 开启表
        self.openList = []
        # 关闭表
        self.closeList = []
        # 寻路地图
        self.map2d = map2d
        # 起点终点
        # ********** Begin **********#
        self.startPoint = startPoint
        self.endPoint = endPoint
 
        # ********** End **********#
        # 可行走标记
        self.passTag = passTag
 
    def getMinNode(self):
        """
        获得openlist中F值最小的节点
        :return: Node
        """
 
        # ********** Begin **********#
        nowf = self.openList[0]
        minf=self.openList[0].g +self.openList[0].h
        for i in self.openList:
            if minf > i.g + i.h:
                minf = i.g + i.h
                nowf = i
        return nowf
 
 
 
        # ********** End **********#
 
    def pointInCloseList(self, point):
        for node in self.closeList:
            if node.point == point:
                return True
        return False
 
    def pointInOpenList(self, point):
        for node in self.openList:
            if node.point == point:
                return node
        return None
 
    def endPointInCloseList(self):
        for node in self.openList:
            if node.point == self.endPoint:
                return node
        return None
 
    def searchNear(self, minF, offsetX, offsetY):
        """
        搜索节点周围的点
        :param minF:F值最小的节点
        :param offsetX:坐标偏移量
        :param offsetY:
        :return:
        """
        # 越界检测
        # ********** Begin **********#
        if minF.point.x + offsetX >= self.map2d.w or minF.point.y + offsetY >= self.map2d.h or minF.point.x + offsetX < 0 or minF.point.y + offsetY < 0:
            return
 
        # ********** End **********#
        # 如果是障碍,就忽略
        if self.map2d[minF.point.x + offsetX][minF.point.y + offsetY] != self.passTag:
            return
        # 如果在关闭表中,就忽略
        currentPoint = Point(minF.point.x + offsetX, minF.point.y + offsetY)
        currentNode = AStar.Node(currentPoint,self.endPoint)
        if self.pointInCloseList(currentPoint):
            return
        # 设置单位花费
        if offsetX == 0 or offsetY == 0:
            step = 10
        else:
            step = 14
        # 如果不再openList中,就把它加入openlist
        # ********** Begin **********#
        if not self.pointInOpenList(currentPoint):
            # print(currentNode.g)
            currentNode.g = step + minF.g
            # print(currentNode)
            currentNode.father = minF
            self.openList.append(currentNode)
        # ********** End **********#
        # 如果在openList中,判断minF到当前点的G是否更小
        if minF.g + step < currentNode.g:  # 如果更小,就重新计算g值,并且改变father
            currentNode.g = minF.g + step
            currentNode.father = minF
 
    def start(self):
        """
        开始寻路
        :return: None或Point列表(路径)
        """
        # 判断寻路终点是否是障碍
        if self.map2d[self.endPoint.x][self.endPoint.y] != self.passTag:
            return None
 
        # 1.将起点放入开启列表
        startNode = AStar.Node(self.startPoint, self.endPoint)
        self.openList.append(startNode)
        # 2.主循环逻辑
        while True:
            # 找到F值最小的点
            minF = self.getMinNode()
            # 把这个点加入closeList中,并且在openList中删除它
            self.closeList.append(minF)
            self.openList.remove(minF)
            # 判断这个节点的上下左右节点
            # ********** Begin **********#
            self.searchNear(minF,0,-1)
            self.searchNear(minF,1,0)
            self.searchNear(minF,-1,0)
            self.searchNear(minF,0,1)
 
            # ********** End **********#
            # 判断是否终止
            point = self.endPointInCloseList()
            if point:  # 如果终点在关闭表中,就返回结果
                # print("关闭表中")
                cPoint = point
                pathList = []
                while True:
                    if cPoint.father:
                        pathList.append(cPoint.point)
                        cPoint = cPoint.father
                    else:
                        return list(reversed(pathList))
            if len(self.openList) == 0:
                return None

盲目搜索之宽度优先搜索算法

 

# -*- coding:utf-8 -*-
class Maze:
    def __init__(self, map, n, m, x, y):
        self.ans = 0            #最短步长结果
        self.map = map          #迷宫地图map[0,n-1][0,m-1](下标0开始)
        self.n = n              #迷宫地图行数n
        self.m = m              #迷宫地图列数m
        self.x = x              #起点,行坐标(下标0开始)
        self.y = y              #起点,列坐标(下标0开始)
        
class Solution:
    def solveMaze(self, maze):
        """求解迷宫问题
        :type: maze: class Maze #迷宫的数据结构类
        :rtype: maze.ans: int   #返回最短路径长度
        """
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        maze.ans = 0
        que = [(maze.x, maze.y, maze.ans)]              #宽度搜索——队列(列表类型)
        vis = {(maze.x, maze.y):True}                   #访问标记——字典类型
        dir = [[0, -1], [0, 1], [-1, 0], [1, 0]]        #移动方向控制
        while que.__len__()>0:
            node = que[0]                               #出队
            del que[0]
            x = node[0]
            y = node[1]
            ans = node[2]
            if x==0 or x==maze.n-1 or y==0 or y==maze.m-1:  #边界,出迷宫,更新结果
                if maze.ans==0 or maze.ans>ans:
                    maze.ans = ans
            for i in range(4):                              #上下左右移动
                newx = x + dir[i][0]                        #新的行坐标
                newy = y + dir[i][1]                        #新的列坐标
                if 0<=newx and newx<maze.n and 0<=newy and newy<maze.m \
                        and maze.map[newx][newy]==1 and (newx, newy) not in vis:
                    vis[(newx, newy)] = True
                    que.append((newx, newy, ans+1))         #入队
        return maze.ans                                     #返回结果
        #********** End **********#

盲目搜索之深度优先搜索算法

 

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self, n=0):
        self.vis = [[]]             #用于标记是否存在皇后的二维列表(初始值全为0)
        self.ans = 0                #用于存储答案(N皇后方案数,初始值0)
        self.n = n                  #用于存储皇后数量n
    def solveNQueens(self):
        """求解N皇后问题(调用self.DFS函数)
        :rtype: self.ans: int    #返回N皇后放置方案数
        """
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        self.vis = [[0 for j in range(50)] for i in range(3)]
        self.ans = 0
        self.DFS(1, self.n)
        return self.ans
        #********** End **********#
    def DFS(self, row, n):
        """深度优先搜索N皇后问题的解空间
        :type: row: int      #NxN棋盘的第row行
        :type: n: int        #皇后数量n
        :rtype: None         #无返回值
        """
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if row == n+1:
            self.ans += 1
            return
        for i in range(1,n+1,1):
            if self.vis[0][row-i+n]==0 and self.vis[1][i]==0 and self.vis[2][row+i]==0 :
                self.vis[0][row-i+n] = self.vis[1][i] = self.vis[2][row+i] = 1
                self.DFS(row+1, n)
                self.vis[0][row-i+n] = self.vis[1][i] = self.vis[2][row+i] = 0
        #********** End **********#

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值