人工智能导论实验1——机器人搬盒子爱因斯坦斑马问题

本文主要是介绍人工智能导论实验1——机器人搬盒子爱因斯坦斑马问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

人工智能导论实验1——机器人搬盒子&爱因斯坦斑马问题

实验目的及要求
理解谓词逻辑知识表示的方法,掌握一阶谓词逻辑知识表示的基本原理,能够利用归结原理求解简单问题。掌握Prolog编程环境,熟悉逻辑推理编写过程。
主要知识点:谓词、原子公式、谓词公式、子句、子句集、空子句、归结原理。
重点:谓词公式、子句集和归结原理的实现。
难点:归结原理的实现。

实验内容:
实验项目1:
机器人搬盒子问题:设在一个房间里,有一个机器人ROBOT ,一个壁橱ALCOVE,一个积木块BOX,两个桌子A和B。开始时,机器人ROBOT在壁橱ALCOVE旁边,且两手空空,桌子A放着积木块BOX,桌子B是空的。机器人可把积木块BOX从一种状态桌子A上变换成另一种状态桌子B上,然后回到壁橱。用归结原理方法求解该问题?

实验要求:
1.用谓词公式表示问题的初始状态、目标状态以及机器人操作;
2.将谓词公式转换为子句集;
3. 利用归结原理对子句集中的子句进行归结。
4. 用Prolog实现机器人搬盒子的谓词逻辑。
5. 用Python或其他编程语言实现该问题的求解。

实验项目2:
爱因斯坦逻辑难题(斑马问题):5个不同国家且工作各不相同的人分别住在一条街上的5所房子里,每所房子的颜色不同,每个人都有自己养的不同宠物,喜欢喝不同的饮料。根据以下信息,你能告诉我哪所房子里的人养斑马,哪所房子里的人喜欢喝矿泉水吗?
6. 英国人住在红色的房子里
7. 西班牙人养了一条狗
8. 日本人是一个油漆工
9. 意大利人喜欢喝茶
10. 挪威人住在左边的第一个房子里
11. 绿房子在白房子的右边
12. 摄影师养了一只蜗牛
13. 外交官住在黄房子里
14. 中间那个房子的人喜欢喝牛奶
15. 喜欢喝咖啡的人住在绿房子里
16. 挪威人住在蓝色的房子旁边
17. 小提琴家喜欢喝橘子汁
18. 养狐狸的人所住的房子与医生的房子相邻
19. 养马的人所住的房子与外交官的房子相邻

实验要求:
20. 用Prolog实现斑马问题的逻辑推理。
21. 在华为云的ModelArts中用Python实现该问题的求解。

思考题:
22. 如何将谓词公式转换为子句集?
23. 谓词公式与子句集等值吗?

实验步骤:

项目试验1:

1.相关谓词定义:

table (x):x 是桌子
empty (y):y 手中是空的
at( y,z): y 在 z 附近
holds (y,w):y 拿着 w
on(w,x):w 在 x 上面

问题初始状态
table (a)
table (b)
empty (robot)
at( robot,alcove)
on(box,a)

问题目标状态
table (a)
table (b)
empty (robot)
at( y,z)
on(box,a)

机器人操作:
goto(x,y):
条件:at( robot,x)
动作:删除:at( robot,x)
增加:at( robot,y)
pickup(x):
条件:on(box,x) ^ table(x) ^ empty(robot)
动作:删除: on(box,x) ^ empty(robot)
增加:hold(robot,box)
setdown(x):
条件:hold(robot,box) ^ table(x)
动作:
删除:hold(robot,box)
增加:empty(robot) ^ on(box,x)

2.将谓词公式转换为子句集

机器人x在c处手里没有盒子,盒子y在a处,那么机器人去a拿起盒子y:
(∀ x) (∀y) empty (x) ⋀ at( x,alcove)⋀ on(y,a)→go(a)⋀ pick(y)
转化为子句集为
{ empty (x,f(x)) ⋀ at( y,g(y)⋀ on(y,g(y) ,go(x,f(x))⋀ pick(y,g(y))

机器人x在a手中有盒子y,那么机器人x走到b放下盒子y:
(∀ x) (∀y) ┐ empty (x) ⋀ at( x,a)⋀ holds (x,y)→go(b)⋀ set-down(y)
转化为子句集为
{┐ empty (x,f(x)) ⋀ at( x,g(x))⋀ holds (x,z(x)),go(y,f(y))⋀ set-down(y,g(y))}

机器人x在b手中没有盒子,盒子y在b处,那么机器人走到c处:
(∀ x) (∀y) empty (x) ⋀ at( x,b)⋀ on(y,b)→go(alcove)
转化为子句集为
{empty (x,f(x)) ⋀ at( x,g(x))⋀ on(y,f(y)),go(x,z(x))}

3.利用归结原理对子句集中的子句进行归结

(1)at(robot,c)
(2)at(box,a)
(3)empty(robot)
(4) at(robot,c) ⋀at(box,a) ⋀empty(robot)
(5) ┐ empty (x) ⋀ at( x,a)⋀ holds (x,y)
(6) go(b)⋀ set-down(y)
(7) empty (x) ⋀ at( x,b)⋀ on(y,c)→go(c)

4.用Prolog实现机器人搬盒子的谓词逻辑
table(a). 
table(b).
empty(robot).
at(robot,c). 
on(box,a).
goto(robot,a):-at(robot,c).at(robot,a).
pick(a):-empty(robot),on(box,a),table(a).on(box,robot).
empty(a).
goto(robot,b):-at(robot,a),empty(a),on(box,robot).at(robot,b).
set-down(b):-table(b),on(box,robot),at(robot,b).empty(robot).
on(box,b).
at(robot,b).
goto(robot,c):-on(box,b),at(robot,b).at(robot,c).
empty(robot).
on(box,b).
finish(box):-on(box,b),at(robot,c),empty(robot).
5. C语言实现
#include <stdio.h>
#include <stdlib.h>
/**
* @author 
*/
// 描述系统状态
typedef struct Problem {char robot_site; // 描述机器人的位置char is_robot_block; // 机器人手中是否拿着箱子char block_site; // 箱子所在位置
}SProblem;
// 初始化系统初始状态和目标状态
int init_status(SProblem* obj, SProblem* p, int* status_number) {obj->robot_site = 'c';obj->is_robot_block = 'N';obj->block_site = 'b';p->robot_site = 'c';p->is_robot_block = 'N';p->block_site = 'a';printf(" 状态 %d:\n 机器人当前所在位置 : %c, 机器人是否拿着箱子: %c,箱子所在位置: %c。\n\n", *status_number, p->robot_site, p->is_robot_block, p->block_site);*status_number += 1;
}
// 机器人移动
int robot_move(SProblem* p, char robot_object_site, int* status_number) {char temp_robot_site = p->robot_site;p->robot_site = robot_object_site;printf(" 状态 %d:\n 机器人从 %c 移动到了 %c。\n\n", *status_number, temp_robot_site,p->robot_site);*status_number += 1;
}
// 机器人搬起箱子
int pick_up_block(SProblem* p, char is_robot_block, char block_site, int* status_number) {p->is_robot_block = is_robot_block;p->block_site = block_site;if (p->is_robot_block == 'Y') {printf(" 状态 %d:\n 机器人拿起了箱子。 \n\n", *status_number);}*status_number += 1;
}
// 机器人放下箱子
int set_down_block(SProblem* p, char is_robot_block, char block_site, int* status_number) {p->is_robot_block = is_robot_block;p->block_site = block_site;if (p->is_robot_block == 'N') {printf(" 状态 %d:\n 机 器 人 将 箱 子 放 在 了 %c 。 \n\n", *status_number, p->block_site);}*status_number += 1;
}
// 判断机器人是否完成任务
int judeg_obj(const SProblem obj, const SProblem p) {if (obj.robot_site == p.robot_site && obj.is_robot_block == p.is_robot_block &&obj.block_site == p.block_site) {printf(" 机器人完成任务。 \n");}
}
int main(int argc, char* argv[]) {SProblem sp;SProblem obj;int status_number = 1;char robot_object_site = 'a';char block_site = 'r';char is_robot_block;// 状态 1:机器人位置 c 是否拿着箱子 N 箱子位置 ainit_status(&obj, &sp, &status_number);// 状态 2:机器人位置 a 是否拿着箱子 N 箱子位置 arobot_move(&sp, robot_object_site, &status_number);block_site = 'r';is_robot_block = 'Y';// 状态 3:机器人位置 a 是否拿着箱子 Y 箱子位置 robotpick_up_block(&sp, is_robot_block, block_site, &status_number);robot_object_site = 'b';// 状态 4:机器人位置 b 是否拿着箱子 Y 箱子位置 robotrobot_move(&sp, robot_object_site, &status_number);block_site = 'b';is_robot_block = 'N';// 状态 5:机器人位置 b 是否拿着箱子 N 箱子位置 bset_down_block(&sp, is_robot_block, block_site, &status_number);robot_object_site = 'c';// 状态 5:机器人位置 c 是否拿着箱子 N 箱子位置 brobot_move(&sp, robot_object_site, &status_number);// 判断机器人是否完成任务judeg_obj(obj, sp);return 0;
}

实验项目2:

根据题意,填表可得:
在这里插入图片描述
所以养斑马的人住在5号房子的日本人
喜欢喝矿泉水的是住在1号房子的挪威人

prolog代码如下:

house(A,[A,_,_,_,_]).
house(A,[_,A,_,_,_]).
house(A,[_,_,A,_,_]).
house(A,[_,_,_,A,_]).
house(A,[_,_,_,_,A]).right(A,B,[A,B,_,_,_]).
right(A,B,[_,A,B,_,_]).
right(A,B,[_,_,A,B,_]).
right(A,B,[_,_,_,A,B]).middle(A,[_,_,A,_,_]).first(A,[A,_,_,_,_]).neighbor(A,B,[A,B,_,_,_]).
neighbor(A,B,[_,A,B,_,_]).
neighbor(A,B,[_,_,A,B,_]).
neighbor(A,B,[_,_,_,A,B]).
neighbor(A,B,[B,A,_,_,_]).
neighbor(A,B,[_,B,A,_,_]).
neighbor(A,B,[_,_,B,A,_]).
neighbor(A,B,[_,_,_,B,A]).attr(_Country,_Pet,_Color,_Drink,_Work).all_houses(Houses) :-house(attr(britsh,_,red,_,_), Houses),house(attr(spain,dog,_,_,_), Houses),house(attr(japan,_,_,_,painter), Houses),house(attr(italy,_,_,tea,_), Houses),house(attr(norway,_,_,_,_), Houses),first(attr(norway,_,_,_,_), Houses),right(attr(_,_,white,_,_), attr(_,_,green,_,_), Houses),house(attr(_,snail,_,_,photographer), Houses),house(attr(_,_,yellow,_,diplomat), Houses),middle(attr(_,_,_,milk,_), Houses),house(attr(_,_,green,cafe,_), Houses),neighbor(attr(norway,_,_,_,_), attr(_,_,blue,_,_), Houses),house(attr(_,_,_,orange,violinst), Houses),neighbor(attr(_,fox,_,_,_), attr(_,_,_,_,doctor), Houses),neighbor(attr(_,horse,_,_,_), attr(_,_,_,_,diplomat), Houses),house(attr(_,zebra,_,_,_), Houses),house(attr(_,_,_,water,_), Houses).

最终使用all_houses(A)查询所有的房子及其属性:
在这里插入图片描述
Python实现如下:

from kanren import *             
from kanren.core import lall     # lall 包用于定义规则
import time
#定义 left()函数,用来查找哪个房屋左边
def left(q, p, list):return membero((q,p), zip(list, list[1:]))
#定义 next()函数,用来接近谁的房子
def next(q, p, list):return conde([left(q, p, list)], [left(p, q, list)])
from kanren import *
from kanren.core import lall     # lall 包用于定义规则
import time#定义 left()函数,用来查找哪个房屋左边
def left(q, p, list):return membero((q,p), zip(list, list[1:]))
#定义 next()函数,用来接近谁的房子
def next(q, p, list):return conde([left(q, p, list)], [left(p, q, list)])houses = var()
rules_zebraproblem = lall((eq, (var(), var(), var(), var(), var()), houses),       # 5 个 var()分别代表人、烟、饮料、动物、屋子颜色# 房子里的每个子成员有五个属性: membero(国家,身份,饮料,宠物,房子)(membero,('英国人', var(), var(), var(), '红色'), houses),          # 1. 英国人住在红色的房子里(membero,('西班牙人', var(), var(), '狗', var()), houses),          # 2. 西班牙人养了一条狗(membero,('日本人', '油漆工', var(), var(), var()), houses),        # 3. 日本人是一个油漆工(membero,('意大利人', var(), '茶', var(), var()), houses),          # 4. 意大利人喜欢喝茶# 5. 挪威人住在左边的第一个房子里(eq,(('挪威人', var(), var(), var(), var()), var(), var(), var(), var()), houses),(left,(var(), var(), var(), var(), '白色'),(var(), var(), var(), var(), '绿色'), houses),    # 6. 绿房子在白房子的右边(membero,(var(), '摄影师', var(), '蜗牛', var()), houses),                     # 7. 摄影师养了一只蜗牛(membero,(var(), '外交官', var(), var(), '黄色'), houses),                     # 8. 外交官住在黄房子里(eq,(var(), var(), (var(), var(), '牛奶', var(), var()), var(), var()), houses),      # 9. 中间那个房子的人喜欢喝牛奶(membero,(var(), var(), '咖啡', var(), '绿色'), houses),                  # 10. 喜欢喝咖啡的人住在绿房子里# 11. 挪威人住在蓝色的房子旁边(next,('挪威人', var(), var(), var(), var()),(var(), var(), var(), var(), '蓝色'), houses),(membero,(var(), '小提琴家', '橘子汁', var(), var()), houses),               # 12. 小提琴家喜欢喝橘子汁# 13. 养狐狸的人所住的房子与医生的房子相邻(next,(var(), var(), var(), '狐狸', var()),(var(), '医生', var(), var(), var()), houses),# 14. 养马的人所住的房子与外交官的房子相邻(next,(var(), var(), var(), '马', var()),(var(), '外交官', var(), var(), var()), houses),(membero,(var(), var(), var(), '斑马', var()), houses),                  # 问题 1. 有人养斑马(membero,(var(), var(), '矿泉水', var(), var()), houses),                   # 问题 2. 有人喜欢喝矿泉水)# 使用 rules_zebraproblem 约束运行解算器
solutions = run(0, houses, rules_zebraproblem)
# 提取解算器的输出
output = [house for house in solutions[0] if '斑马' in house][0][4]
print ('\n{}房子里的人养斑马'.format(output))
output = [house for house in solutions[0] if '矿泉水' in house][0][4]
print ('\n{}房子里的人喜欢喝矿泉水\n'.format(output))# 解算器的输出结果展示
print("所有结果如下:")
for i in solutions[0]:print(i)

结果如下:
在这里插入图片描述

思考题:
1、如何将谓词公式转换为子句集?
1)消去蕴含等价式
2)移动否定符号
3)变量标准化
4)消去存在量词
5)化为前束型
6)化为skolem标准型
7)略去全称量词
8)消去合取词,把母式用子句集表示
9)字句变量标准化

2、谓词公式与子句集等值吗?
1)谓语公式与它的子句集不是总等价的。
2)在谓语公式不可满足的情况下是等价的。

这篇关于人工智能导论实验1——机器人搬盒子爱因斯坦斑马问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/208682

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR