不懂先生

人工智能答案
序言人工智能考试结束了,然后educoder上也算入总成绩,对此我整理了一下答案,方便大家享用。正文神经网络第一关...
扫描右侧二维码阅读全文
07
2021/08

人工智能答案

序言

人工智能考试结束了,然后educoder上也算入总成绩,对此我整理了一下答案,方便大家享用。

正文

神经网络

第一关 神经网络概述

1.A
2.ABCD
3.A

第二关 BP 神经网络

import numpy as np

def loaddataset(filename):
    fp = open(filename)

    #存放数据
    dataset = []

    #存放标签
    labelset = []
    for i in fp.readlines():
        a = i.strip().split()

        #每个数据行的最后一个是标签数据
        dataset.append([float(j) for j in a[:len(a)-1]])
        labelset.append(int(float(a[-1])))
    return dataset, labelset


#x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
def parameter_initialization(x, y, z):

    #隐层阈值
    value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)

    #输出层阈值
    value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)

    #输入层与隐层的连接权重
    weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)

    #隐层与输出层的连接权重
    weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)

    return weight1, weight2, value1, value2

#返回sigmoid函数值
def sigmoid(z):
#********** Begin **********#
    return 1 / (1 + np.exp(-z))
#********** End **********#


'''
weight1:输入层与隐层的连接权重
weight2:隐层与输出层的连接权重
value1:隐层阈值
value2:输出层阈值
'''
def trainning(dataset, labelset, weight1, weight2, value1, value2):
    #x为步长
    x = 0.01
    for i in range(len(dataset)):
        #输入数据
        inputset = np.mat(dataset[i]).astype(np.float64)
        #数据标签
        outputset = np.mat(labelset[i]).astype(np.float64)
        #隐层输入
        input1 = np.dot(inputset, weight1).astype(np.float64)
        #隐层输出
        output2 = sigmoid(input1 - value1).astype(np.float64)
        #输出层输入
        input2 = np.dot(output2, weight2).astype(np.float64)
        #输出层输出
        output3 = sigmoid(input2 - value2).astype(np.float64)
 
        #更新公式由矩阵运算表示
        a = np.multiply(output3, 1 - output3)
        g = np.multiply(a, outputset - output3)
        b = np.dot(g, np.transpose(weight2))
        c = np.multiply(output2, 1 - output2)
        e = np.multiply(b, c)
 
        value1_change = -x * e
        value2_change = -x * g
        weight1_change = x * np.dot(np.transpose(inputset), e)
        weight2_change = x * np.dot(np.transpose(output2), g)
 
        #更新参数
        value1 += value1_change
        value2 += value2_change
        weight1 += weight1_change
        weight2 += weight2_change
    return weight1, weight2, value1, value2


def testing(dataset, labelset, weight1, weight2, value1, value2):
    #记录预测正确的个数
    rightcount = 0
    for i in range(len(dataset)):
        #计算每一个样例通过该神经网路后的预测值
        inputset = np.mat(dataset[i]).astype(np.float64)
        outputset = np.mat(labelset[i]).astype(np.float64)
        output2 = sigmoid(np.dot(inputset, weight1) - value1)
        output3 = sigmoid(np.dot(output2, weight2) - value2)
 
        #确定其预测标签
        if output3 > 0.5:
            flag = 1
        else:
            flag = 0
        if labelset[i] == flag:
            rightcount += 1
        #输出预测结果
        print("预测为%d   实际为%d"%(flag, labelset[i]))
    #返回正确率
    return rightcount / len(dataset)

第三关 Hopfield 神经网络

import numpy as np
import random
from random import randint
from matplotlib import pyplot as plt
#根据Hebb学习规则计算神经元之间的连接权值
def calcWeight(savedsample):
    N = len(savedsample[0])
    P = len(savedsample)
    mat = [0]*N
    returnMat = []
    for i in range(N):
        m = mat[:]
        returnMat.append(m)
    for i in range(N):
        for j in range(N):
            if i==j:
                continue
            sum = 0
            for u in range(P):
                sum += savedsample[u][i] * savedsample[u][j]
            returnMat[i][j] = sum/float(N)
    return returnMat
#根据神经元的输入计算神经元的输出(静态突触)
def calcXi(inMat , weighMat):
    #假设计算第t次循环后神经元的输出时,输入的参数inMat表示第t-1次循环后神经元的输出。即用上一次循环的输出做本次循环的输入。
    #weighMat权值矩阵
    returnMat = inMat
    choose = []
    for i in range(len(inMat)//5):
        #随机改变N/5个神经元的值,该参数可调,也可同时改变所有神经元的值
        choose.append(random.randint(0,len(inMat)-1))
    for i in choose:
        sum = 0
        #网络动态演变
        #********** Begin **********#
        for j in range(len(inMat)):
            sum += weighMat[i][j] * inMat[j]
        if sum>=0:
            returnMat[i] = 1
        else: returnMat[i] = -1
        #********** End **********#
    return returnMat
    
#加噪函数,在记忆样本的基础上增加30%的噪声:
def addnoise(mytest_data,n):
    #mytest_data:网络矩阵 n:节点数 
    #********** Begin **********#
    for x in range(n):
        for y in range(n):
            if random.randint(0, 10) > 7:
                mytest_data[x * n + y] = -mytest_data[x * n + y]
    #********** End **********#
    return mytest_data
    
#标准输出函数:data 为联想记忆后的矩阵,N 为方阵行数:
def regularout(data,N):
    for j in range(N):
        ch = ""
        for i in range(N):
        #矩阵元素值为 1 则输出“ X ”,否则输出“ ”
        #********** Begin **********#
         ch += " " if data[j*N+i] == -1 else "X"
        #********** Begin **********#
        print(ch)

第四关 卷积神经网络

import numpy as np

def my_conv(inputmatrix,kernel):
    output_size = (len(inputmatrix)-len(kernel)+1)
    res = np.zeros([output_size,output_size],np.float32)
    for i in range(len(res)):
        for j in range(len(res)):
            res[i][j] = compute_conv(inputmatrix,kernel,i,j)
    return res

#两个矩阵的卷积算法
def compute_conv(inputmatrix,kernel,i,j):
    #inputmatrix为输入矩阵,kernel为卷积核,i,j分别是每次卷积运算的首元素地址
    res = 0
    #********** Begin **********#
    for kk in range(3):
        for k in range(3):
            #print(input[i+kk][j+k])
            res +=inputmatrix[i+kk][j+k]*kernel[kk][k] 
    #********** End **********#
    return res

机器学习

第一关 机器学习概述

A
AB
A

第二关 线性回归

import numpy as np
import pandas as pd
#计算代价函数J(θ)
def computeCost(X, y, theta):
# X 、 y 、 theta 与数据预处理参数保持一致
#返回代价函数的值(参考编程要求中的代价函数函数)
#********** Begin **********#
    inner=np.power(((X*theta.T)-y),2) 
    return np.sum(inner)/(2*len(X))   
#********** End **********#

#批量梯度下降
#返回参数 θ 的值和每次迭代后代价函数的值,梯度下降公式参考编程要求梯度下降公式
def gradientDescent(X, y, theta, alpha, epoch):
# X 、 y 、 theta 与数据预处理参数保持一致
# alpha :学习率(取值:alpha = 0.01)
# epoch :迭代次数(取值:epoch = 1000)
    cost = np.zeros(epoch)  # 初始化一个 ndarray ,包含每次 epoch 的cost
    #********** Begin **********#
    temp=np.matrix(np.zeros(theta.shape))
    parameters=int(theta.flatten().shape[1])
    cost=np.zeros(epoch)
    m=X.shape[0]

    for i in range(epoch):
        temp=theta-(alpha/m)*(X*theta.T-y).T*X
        theta=temp
        cost[i]=computeCost(X,y,theta)
    #********** End **********#
    return theta, cost

第三关 逻辑回归

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.optimize as opt

# S 型函数
def sigmoid(z):
    #返回 sigmoid 的函数值,z 为函数变量(参考编程要求中的 sigmoid 函数)
    #********** Begin **********#
     return 1 / (1 + np.exp(-z))
    #********** End **********#

#代价函数
def cost(theta, X, y):
    #X 、 y 、 theta 与数据预处理参数保持一致
    #返回代价函数的值(参考编程要求中的代价函数)
    #********** Begin **********#
    first = (-y) * np.log(sigmoid(X @ theta))
    second = (1 - y)*np.log(1 - sigmoid(X @ theta))
    return np.mean(first - second) 
    #********** End **********#

#批量梯度下降
def gradient(theta, X, y):
    return (X.T @ (sigmoid(X @ theta) - y))/len(X)

#假设函数
def predict(theta, X):
    #X 、 y 、 theta 与数据预处理与参数保持一致
    #将所有预测出的值存储在 list 中并返回(参考编程要求中的假设函数)
    #********** Begin **********#
    probability = sigmoid(X@theta)
    return [1 if x >= 0.5 else 0 for x in probability]  # return a list
    #********** End **********#

第四关 支持向量机

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
from sklearn.svm import SVC

#读文件
data1=loadmat('/data/workspace/myshixun/project/src/step4/ex6data1.mat')
#数据预处理
data=pd.DataFrame(data1['X'],columns=['x1','x2'])
data['y']=data1['y']

#初始化 SVC
#********** Begin **********#
svc1=SVC(C=1,kernel='linear')
#********** End **********#

#在数据集(X,y)上使用 SVM 模型进行数据拟合
#********** Begin **********#
svc1.fit(data1['X'],data1['y'].ravel())#拟合
#当前分类器的准确率
svc1.score(data1['X'],data1['y'].ravel())
#********** End **********#


#在数据集(X,y)上使用 SVM 模型进行数据拟合
#********** Begin **********#

#********** End **********#

第五关 聚类

import scipy.io as sio # load mat
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans

#生成随机的k个中心,请使用sample(k)
def random_init(data, k):
    #data:数据集 k:聚类中心个数
    #返回 k 个聚类中心并转换成array数组
    #********** Begin **********#
    return data.sample(k).as_matrix() #as_matrix(): 转换成array
    #********** End **********#

#单个找寻聚类
def find_cluster(x, centroids):
    #x:待聚类点坐标  centroids:中心坐标
    #********** Begin **********#
    distances = np.apply_along_axis(func1d=np.linalg.norm, axis=1 , arr=x-centroids )
    #********** End **********#
    return np.argmin(distances)

# 集体data聚类标签
def assign_cluster(data, centroids):
    return np.apply_along_axis(lambda x: find_cluster(x, centroids), axis=1, arr=data.as_matrix())
#  data中增加一列聚类标签C
def combineDataC(data, C):
    dataC = data.copy()
    dataC['C'] = C
    return dataC

# 新中心点,同时去掉C, 再转换成array数组
def newCentroids(data, C):
    dataC = combineDataC(data, C)
    return dataC.groupby('C', as_index=False).mean().sort_values(by='C').drop('C', axis=1).as_matrix()


# 损失函数
def cost(data, centroids, C):
    #data:数据集 centroids:中心坐标 C:聚类标签
    m = data.shape[0] # 样本量
    dataCentroids = centroids[C] # 各行的中心坐标
    #********** Begin **********#
    distances = np.apply_along_axis(func1d=np.linalg.norm, axis= 1, arr= data.as_matrix()-dataCentroids )
    #********** End **********#
    return distances.sum()/m


# kmeans通道,运行一次
def kMeansIter(data, k, epoch=100, tol=0.0001):
    # 生成最初的中心坐标
    centroids = random_init(data, k)

    costProgress = []  # 用来存放递归聚类的每次损失
    # 分配聚类标签
    for i in range(epoch):
        C = assign_cluster(data, centroids)
        centroids = newCentroids(data, C)
        costProgress.append(cost(data, centroids, C))

        if len(costProgress) > 1:
            if np.abs(costProgress[-1] - costProgress[-2]) / costProgress[-1] < tol:
                break

    return C, centroids, costProgress[-1]

# 每个k运行n_init次,套用kmeans通道
def kMeans(data, k, epoch=100, n_init=10):
    tries = np.array([kMeansIter(data, k) for _ in range(n_init)])
    leasrCostIndex = np.argmin(tries[:, -1])
    return tries[leasrCostIndex]

确定性推理

第一关 推理概述

1.A
2.D
3.ABC
4.ABCD
5.C
6.ABCD

第二关 自然演绎推理

1.C
2.F

第三关 鲁宾孙归结原理

1.A
2.A
3.A

第四关 归结反演

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(mother))
                    else:
                        print('归结式:' + ' ∨ '.join(father) + ' ∨ ' + ' ∨ '.join(mother))
                    #********** End **********#

不确定性推理

第一关 可信度方法

1.C
2.A
3.D

第二关 证据理论

1.D
2.B
3.A

第三关 模糊推理基础

1.A 
2.B
3.C
4.A
5.B

第四关 模糊推理及其应用

OIL=100.0#定义油渍论域
Stain=100.0#定义污渍论域
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之间时,执行
    #同时将参数传入给MD,同时比较MD方法传回来的参数和该方法求出的值相比较,求出最后的最适合的预测值
    # ********** Begin **********#
    returnMDresult = ruleMD(stain)
    result = (stain - 50) / 50.0
    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 oil<0 or oil>OIL or stain<0 or stain>Stain:
          return 0.0
        else:
          if oil>=0 and oil<=50:
             result_G = ruleSG(oil)
          else:
             result_G = ruleLG(oil)
          if stain>=0 and stain<=50:
             result_D = ruleSD(stain)
          else: 
             result_D = ruleLD(stain)

    # ********** 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

知识表示概述

第一关

B
ABCD
A

一般谓词逻辑表示法

第一关

A
B
D

第二关

B
C
ABD
B
B

第三关

ABCD
A
A

产生式表示法与框架表示法

第一关 产生式表示法

A
D
A
ABCD
ABCD

第二关 产生式系统

# 动物识别系统
# 自定义函数,判断有无重复元素
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
        # ********* Begin *********#
        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根据所给条件无法判断为何种动物")

第三关 框架表示法

B
B
ACD

问题求解的基本原理

第一关 状态空间法问题求解

A
ABC
B

第二关 问题归约法问题求解

B
BCD
ACD

盲目搜索算法

第一关 广度优先搜索

def PlayMazz(mazz, start, end):
    '''
    走迷宫,从start走到end
    :param mazz: 图
    :param start: 图的起点
    :param end: 图的出口
    '''
    # queue为队列,当队列为空或者当前地点为终点时搜索结束
    visited, queue = set(), [start]
    ans = []
    #********* Begin *********#
    while queue:
        node = queue.pop(0)
        ans.append(node)
        if node==end:
            break
        for c in mazz[node]:
            queue.append(c)
    print(''.join(ans))

    #********* End *********#

第二关 深度优先搜索

def PlayMazz(graph, start,end, visited=None):
    '''
    深度优先搜索,从1走到9
    :param graph: 搜索的空间
    :param start: 开始搜索的起点
    :param visited:  已经搜索过的点集合
    '''
    if visited is None:
        visited = set()
    # visited.add(start)
    # print(start, end='')
    # 当前地点为终点时结束搜索
    # if start == end:
    #     return
    #********* Begin *********#
    # 看看当前位置有哪些路可以走,如果能走并且之前没有走过就走
    stack = [start]
    ans = []
    while stack:
        node = stack.pop(-1)
        if node in visited:
            continue
        ans.append(node)
        visited.add(node)
        if node==end:
            break
        for c in graph[node][::-1]:
            stack.append(c)
    print(''.join(ans))
        
    #********* End *********#

第三关 盲目搜索算法的应用

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self, n=0):
        # self.vis = [[0]*n for _ in range(n)]    #用于标记是否存在皇后的二维列表(初始值全为0)
        self.ans = 0                #用于存储答案(N皇后方案数,初始值0)
        self.n = n                  #用于存储皇后数量n

    def solveNQueens(self):
        """求解N皇后问题(调用self.DFS函数)
        :rtype: self.ans: int    #返回N皇后放置方案数
        """
        #请在这里补充代码,完成本关任务
        #********** Begin ********#
        self.exit_column = set()
        self.exit_diagonal1 = set()
        self.exit_diagonal2 = set()
        self.DFS(0, 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:
            self.ans += 1
            return

        for i in range(n):
            if i not in self.exit_column and i+row not in self.exit_diagonal1 and i-row not in self.exit_diagonal2:
                self.exit_column.add(i)
                self.exit_diagonal1.add(i+row)
                self.exit_diagonal2.add(i-row)

                self.DFS(row+1, n)

                self.exit_column.remove(i)
                self.exit_diagonal1.remove(i+row)
                self.exit_diagonal2.remove(i-row)
        #********** End **********#

启发式搜索算法

第一关 评估函数和启发信息

A
A

第二关 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.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 **********#
        if isinstance(startPoint, Point) and isinstance(endPoint, Point):
            self.startPoint = startPoint
            self.endPoint = endPoint
        else:
            self.startPoint = Point(*startPoint)
            self.endPoint = Point(*endPoint)
        #********** End **********#
        # 可行走标记
        self.passTag = passTag
        
    def getMinNode(self):
        """
        获得openlist中F值最小的节点
        :return: Node
        """

        #********** Begin **********#
        currentNode = self.openList[0]
        for node in self.openList:
            if node.g + node.h < currentNode.g + currentNode.h:
                currentNode = node
        return currentNode
        #********** 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 < 0 or minF.point.x + offsetX > self.map2d.w - 1 or minF.point.y + offsetY < 0 or minF.point.y + offsetY > self.map2d.h - 1:
            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)
        if self.pointInCloseList(currentPoint):
            return
        # 设置单位花费
        if offsetX == 0 or offsetY == 0:
            step = 10
        else:
            step = 14
        # 如果不再openList中,就把它加入openlist
        #********** Begin **********#
        currentNode = self.pointInOpenList(currentPoint)
        if not currentNode:
            currentNode = AStar.Node(currentPoint, self.endPoint, g=minF.g + step)
            currentNode.father = minF
            self.openList.append(currentNode)
            return
        #********** 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, 0, 1)
            self.searchNear(minF, -1, 0)
            self.searchNear(minF, 1, 0)
            #********** 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

博弈中的搜索

第一关 博弈概述

A
A

第二关 极小极大算法

# -*- coding:utf-8 -*-
import copy     # 注意对象的深拷贝和浅拷贝的使用!!!
class GameNode:
    '''博弈树结点数据结构
    成员变量:
    map - list[[]] 二维列表,三子棋盘状态
    val - int  该棋盘状态对执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
    deepID - int 博弈树的层次深度,根节点deepID=0
    parent - GameNode,父结点
    children - list[GameNode] 子结点列表
    '''
    def __init__(self, map, val=0, deepID=0, parent=None, children=[]):
        self.map = map
        self.val = val
        self.deepID = deepID
        self.parent = parent
        self.children = children
class GameTree:
    '''博弈树结点数据结构
    成员变量:
    root - GameNode 博弈树根结点
    成员函数:
    buildTree - 创建博弈树
    '''
    def __init__(self, root):
        self.root = root                # GameNode 博弈树根结点
    def buildTree(self, root):
        '''递归法创建博弈树
        参数:
        root - GameNode 初始为博弈树根结点
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        posList = []
        for i in range(3):
            for j in range(3):
                if root.map[i][j]=='_':
                    posList.append((i,j))

        for (x, y) in posList:
            childNode = GameNode(map=copy.deepcopy(root.map),
                                 val=0, deepID=root.deepID+1, parent=root, children=[])
            if root.deepID%2==0:
                childNode.map[x][y]='x'
            else :
                childNode.map[x][y]='o'
            root.children.append(childNode)

        for childNode in root.children:
            self.buildTree(childNode)
        #********** End **********#
class MinMax:
    '''博弈树结点数据结构
    成员变量:
    game_tree - GameTree 博弈树
    成员函数:
    minmax - 极大极小值算法,计算最优行动
    max_val - 计算最大值
    min_val - 计算最小值
    get_val - 计算某棋盘状态中:执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
    isTerminal - 判断某状态是否为最终状态:无空闲棋可走
    '''
    def __init__(self, game_tree):
        self.game_tree = game_tree      # GameTree 博弈树
    def minmax(self, node):
        '''极大极小值算法,计算最优行动
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - list[map] 最优行动,即x棋子的下一个棋盘状态GameNode.map
              其中,map - list[[]] 二维列表,三子棋盘状态
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        best_val = self.max_value(node)
        best_move = []
        for childNode in node.children:
            if childNode.val == best_val and best_val==1:
                best_move.append(childNode.map)
        return best_move
        #********** End **********#
    def max_value(self, node):
        '''计算最大值
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - int 子结点中的最大的评估值
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if self.isTerminal(node):
            val = self.get_value(node)
            node.val = val
            return val
        inf_val = float('inf')
        max_val = -inf_val
        for childNode in node.children:
            max_val = max(max_val, self.min_value(childNode))
        node.val = max_val
        return max_val
        #********** End **********#
    def min_value(self, node):
        '''计算最小值
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - int 子结点中的最小的评估值
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if self.isTerminal(node):
            val = self.get_value(node)
            node.val = val
            return val
        inf_val = float('inf')
        min_val = inf_val
        for childNode in node.children:
            min_val = min(min_val, self.max_value(childNode))
        node.val = min_val
        return min_val
        #********** End **********#
    def get_value(self, node):
        '''计算某棋盘状态中:执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - int 执x棋子的评估值,1表示胜利,-1表示失败,0表示平局
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        for i in range(3):
            if node.map[i][0]=='o' and node.map[i][0]==node.map[i][1] and node.map[i][1]==node.map[i][2]:
                return -1
            if node.map[0][i]=='o' and node.map[0][i]==node.map[1][i] and node.map[1][i]==node.map[2][i]:
                return -1
        if node.map[0][0]=='o' and node.map[0][0]==node.map[1][1] and node.map[1][1]==node.map[2][2]:
            return -1
        if node.map[0][2]=='o' and node.map[0][2]==node.map[1][1] and node.map[1][1]==node.map[2][0]:
            return -1
        for i in range(3):
            if node.map[i][0]=='x' and node.map[i][0]==node.map[i][1] and node.map[i][1]==node.map[i][2]:
                return 1
            if node.map[0][i]=='x' and node.map[0][i]==node.map[1][i] and node.map[1][i]==node.map[2][i]:
                return 1
        if node.map[0][0]=='x' and node.map[0][0]==node.map[1][1] and node.map[1][1]==node.map[2][2]:
            return 1
        if node.map[0][2]=='x' and node.map[0][2]==node.map[1][1] and node.map[1][1]==node.map[2][0]:
            return 1
        return 0
        #********** End **********#
    def isTerminal(self, node):
        '''判断某状态是否为最终状态:无空闲棋可走(无子结点)
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - bool 是最终状态,返回True,否则返回False
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        assert node is not None
        return len(node.children)==0
        #********** End **********#

第三关 α-β剪枝算法

# -*- coding:utf-8 -*-
import copy     # 注意对象的深拷贝和浅拷贝的使用!!!
class GameNode:
    '''博弈树结点数据结构
    成员变量:
    name - string 结点名字
    val - int  结点值
    children - list[GameNode] 子结点列表
    '''
    def __init__(self, name='', val=0):
        self.name = name        # char
        self.val = val          # int
        self.children = []      # list of nodes
class GameTree:
    '''博弈树结点数据结构
    成员变量:
    root - GameNode 博弈树根结点
    成员函数:
    buildTree - 创建博弈树
    '''
    def __init__(self):
        self.root = None                # GameNode 博弈树根结点
    def buildTree(self, data_list, root):
        '''递归法创建博弈树
        参数:
        data_list - list[] like this ['A', ['B', ('E', 3), ('F', 12)], ['C', ('H', 2)], ['D', ('K', 14)]]
        root - GameNode
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        for i in range(1,len(data_list)):
            if type(data_list[i]) == list:
                root.children.append(GameNode(data_list[i][0]))
                self.buildTree(data_list[i],root.children[i-1])
            else:
                root.children.append(GameNode(data_list[i][0],data_list[i][1]))

        #********** End **********#
class AlphaBeta:
    '''博弈树结点数据结构
    成员变量:
    game_tree - GameTree 博弈树
    成员函数:
    minmax_with_alphabeta - 带AlphaBeta剪枝的极大极小值算法,计算最优行动
    max_value - 计算最大值
    min_value - 计算最小值
    get_value - 返回结点的值
    isTerminal - 判断某结点是否为最终结点
    '''
    def __init__(self, game_tree):
        self.game_tree = game_tree      # GameTree 博弈树
    def minmax_with_alphabeta(self, node):
        '''带AlphaBeta剪枝的极大极小值算法,计算最优行动
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - GameNode 最优行动的结点
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        clf = self.max_value(node,-10000,10000)
        for child in node.children:
            if child.val == clf:
                return child;
        #********** End **********#
    def max_value(self, node, alpha, beta):
        '''计算最大值
        参数:
        node - GameNode 博弈树结点
        alpha - int 剪枝区间下限值
        beta - int 剪枝区间上限值
        返回值:
        clf - int 子结点中的最大的评估值
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if self.isTerminal(node):
            return self.get_value(node)
        clf = -10000
        for child in node.children:
            clf = max(clf,self.min_value(child,alpha,beta))
            if clf >= beta:
                return clf
            alpha = max(alpha,clf)
        node.val = clf;
        return clf
        #********** End **********#
    def min_value(self, node, alpha, beta):
        '''计算最小值
        参数:
        node - GameNode 博弈树结点
        alpha - int 剪枝区间下限值
        beta - int 剪枝区间上限值
        返回值:
        clf - int 子结点中的最小的评估值
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if self.isTerminal(node):
            return self.get_value(node)
        clf = 10000
        for child in node.children:
            clf = min(clf,self.max_value(child,alpha,beta))
            if clf <= alpha:
                return clf
            beta = min(clf,beta)
        node.val = clf;
        return clf;

        #********** End **********#
    def get_value(self, node):
        '''返回结点的值
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - int 结点的值,即 node.val
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        return node.val;
        #********** End **********#
    def isTerminal(self, node):
        '''判断某结点是否为最终结点(无子结点)
        参数:
        node - GameNode 博弈树结点
        返回值:
        clf - bool 是最终状态,返回True,否则返回False
        '''
        #请在这里补充代码,完成本关任务
        #********** Begin **********#
        if node.val == 0:
            return False
        else:
            return True
        #********** End **********#

人工智能概述

第一关 什么是人工智能?

D
ABCD

第二关 人工智能的历史

C
B

第三关 人工智能研究途径与目标

D
B

第四关 人工智能研究领域

ABCD
A
Last modification:January 18th, 2022 at 04:30 pm

Leave a Comment