实验7 知识表示与推理

实验7 知识表示与推理

一、实验目的

(1)掌握知识和知识表示的基本概念,理解其在AI中的深刻含义与意义;

(2)熟悉AI中常用的知识表示方法的优缺点及其应用场景;

(3)掌握产生式系统知识表示的方法及其构成要素;

(4)掌握状态空间法的基本构成及其特点,能用其表示实际AI问题;

(5)深入理解图的深度、宽度搜索方法,并能应用于实际问题;

(6)根据自身情况,能选择合适的编程语言,解决实际AI问题。

二、实验内容

借助产生式系统和状态空间法,选择一种编程语言(最好为python或java),完成题目要求。

1、八数码难题

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格可用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局,找到一种移动方法,实现从初始布局到目标布局的转变。

import heapq

计算了两个状态(state 和 goal)之间的曼哈顿距离

python 复制代码
def manhattan_distance(state, goal):
    distance = 0
    for i in range(1, 9):
        x1, y1 = divmod(state.index(i), 3)
        x2, y2 = divmod(goal.index(i), 3)
        distance += abs(x1 - x2) + abs(y1 - y2)
    return distance

# 在 A* 算法 中的一个节点。代表了搜索空间中的一个状态

class Node:
    def __init__(self, state, parent=None, move=0, depth=0):
        self.state = state
        self.parent = parent
        self.move = move
        self.depth = depth
        self.cost = 0  # g(n) + h(n)

    def __lt__(self, other):
        return self.cost < other.cost

# A* 算法
# 结合实际成本(g(n))和估计成本(h(n))来选择最有希望的路径
# g(n) 是从起始节点到当前节点的移动次数(或称为深度),
# 而 h(n) 是当前状态与目标状态之间的曼哈顿距离
def a_star(initial, goal):
    open_list = []
    closed_set = set()
    root = Node(initial)
    heapq.heappush(open_list, (manhattan_distance(initial, goal), root))

    while open_list:
        _, current = heapq.heappop(open_list)
        closed_set.add(tuple(current.state))

        if current.state == goal:
            path = []
            while current:
                path.append(current.state)
                current = current.parent
            return path[::-1]

        zero_pos = current.state.index(0)
        x, y = divmod(zero_pos, 3)
        moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]

        for dx, dy in moves:
            new_x, new_y = x + dx, y + dy
            if 0 <= new_x < 3 and 0 <= new_y < 3:
                new_state = current.state[:]
                new_pos = new_x * 3 + new_y
                new_state[zero_pos], new_state[new_pos] = new_state[new_pos], new_state[zero_pos]
                if tuple(new_state) not in closed_set:
                    new_node = Node(new_state, current, move=current.move + 1, depth=current.depth + 1)
                    new_node.cost = new_node.depth + manhattan_distance(new_state, goal)
                    heapq.heappush(open_list, (new_node.cost, new_node))

    return None

# 手动输入初始状态和目标状态
# initial_state = [int(input(f"请输入位置 {i+1} 的数字(0-8): ")) for i in range(9)]
initial_state = [1, 3, 2, 4, 7, 6, 0, 5, 8]
goal_state = [1, 2, 3, 4, 5, 6, 7, 8, 0]
solution = a_star(initial_state, goal_state)


def print_state(state):
    """
    以3x3网格的形式打印状态
    :param state: 包含九个数字的列表,代表拼图的一个状态
    """
    for i in range(0, 9, 3):
        print('\t'.join(map(str, state[i:i + 3])))
    print()  # 每打印完一个状态后添加一个空行

if solution:
    for step in solution:
        print_state(step)
else:
    print("无解")

2、设有3个传教士和3个野人来到河边,打算乘一只船从右岸渡到左岸去。该船每一次只能装载2人。在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉。请你设计一个方案怎样才能用这条船安全地把所有人都渡过河去?编程实现你的方案。

python 复制代码
from collections import deque

def is_valid_state(left_missionaries, left_cannibals):
    if left_missionaries < 0 or left_cannibals < 0:
        return False
    if (3 - left_missionaries) < 0 or (3 - left_cannibals) < 0:
        return False
    if (left_missionaries > 0 and left_cannibals > left_missionaries) or ((3 - left_missionaries) > 0 and (3 - left_cannibals) > (3 - left_missionaries)):
        return False
    return True

def next_states(state):
    left_missionaries, left_cannibals, right_missionaries, right_cannibals, boat_position = state
    next_states_list = []
    if boat_position == 'left':
        for i in range(3):
            for j in range(3):
                if i + j > 0 and i + j <= 2:
                    new_left_missionaries = left_missionaries - i
                    new_left_cannibals = left_cannibals - j
                    new_right_missionaries = right_missionaries + i
                    new_right_cannibals = right_cannibals + j
                    if is_valid_state(new_left_missionaries, new_left_cannibals):
                        next_states_list.append((new_left_missionaries, new_left_cannibals, new_right_missionaries, new_right_cannibals, 'right'))
    else:
        for i in range(3):
            for j in range(3):
                if i + j > 0 and i + j <= 2:
                    new_left_missionaries = left_missionaries + i
                    new_left_cannibals = left_cannibals + j
                    new_right_missionaries = right_missionaries - i
                    new_right_cannibals = right_cannibals - j
                    if is_valid_state(new_left_missionaries, new_left_cannibals):
                        next_states_list.append((new_left_missionaries, new_left_cannibals, new_right_missionaries, new_right_cannibals, 'left'))
    return next_states_list

def bfs():
    initial_state = (3, 3, 0, 0, 'left')
    goal_state = (0, 0, 3, 3, 'right')
    visited = set()
    queue = deque([(initial_state, [])])
    while queue:
        state, path = queue.popleft()
        if state == goal_state:
            return path + [state]
        if state not in visited:
            visited.add(state)
            for next_state in next_states(state):
                queue.append((next_state, path + [state]))
    return None

path = bfs()
if path is None:
    print("未找到解决方案。")
else:
    print("解决方案:")
    for state in path:
        left_missionaries, left_cannibals, right_missionaries, right_cannibals, boat_position = state
        if boat_position == "left":
            print(f"左岸有{left_missionaries}个传教士和{left_cannibals}个野人。右岸有{right_missionaries}个传教士和{right_cannibals}个野人。船在左岸。")
        else:
            print(f"左岸有{left_missionaries}个传教士和{left_cannibals}个野人。右岸有{right_missionaries}个传教士和{right_cannibals}个野人。船在右岸。")

三、实验报告

1、需求分析

2、数据结构、功能模块设计与说明

3、核心代码(不要将全部代码贴在报告上)与测试结果说明

4、实验存在的问题与体会

5、实验指导与源代码、程序运行环境与运行说明等打包,以班级+学号+姓名命名,统一发给课代表或学委。

相关推荐
我还可以再学点2 小时前
C语言常见函数
c语言·开发语言
_YiFei2 小时前
从 “选题卡壳” 到 “PPT 定稿”,AI 如何搞定开题全流程?
人工智能
IT_陈寒2 小时前
SpringBoot 3.0实战:10个高效开发技巧让你的启动时间减少50%
前端·人工智能·后端
写代码的【黑咖啡】2 小时前
深入理解 Python 中的 SQLAlchemy
开发语言·python·oracle
源于花海2 小时前
迁移学习的第二类方法:特征选择
人工智能·机器学习·迁移学习·特征选择
8K超高清2 小时前
2026科技风口:有哪些前沿场景即将落地?
网络·人工智能·科技·数码相机·计算机视觉
未定义.2212 小时前
第1篇:0基础入门!Python+Selenium环境搭建与第一个自动化脚本
python·功能测试·selenium·自动化·jenkins·pytest
特行独立的猫2 小时前
python+Proxifier+mitmproxy实现监听本地网路所有的http请求
开发语言·爬虫·python·http
深蓝电商API2 小时前
Scrapy Spider 参数化:动态传入 start_urls 和自定义设置
爬虫·python·scrapy