人工智能实验

产生式系统(Production system)首先由波斯特(Post)于1943年提出的产生式规则(Production rule)而得名,他们用这种规则对符号串进行置换运算,后来,美国的纽厄尔和西蒙利用这个原理建立了一个人类的认知模型(1965年),同年,斯坦福大学利用产生式系统结构设计出第一个专家系统DENDRAL。

产生式系统用来描述若干个不同的以一个基本概念为基础的系统。这个基本概念就是产生式规则或产生式条件和操作对象的概念。

问题描述:用基于产生式系统的方法求解传教士和野人问题

有N个传教士和N个野人来到河边准备渡河,河岸有一条船,每次至多可供K个乘渡,问传教士为了安全起见,应如何规划摆渡方案,使得任何时刻,河岸两边以及船上的野人数目总是不超过传教土的数目,即求解传教士和野人从左岸全部摆渡到右岸的过程中,任何时刻满足M(传教士数)≥C(野人数)和M+C≤K的摆渡方案。

(1) 问题状态的表示

struct status{intshipSite=0;  //0 stand left, 1 standright ,aim is rightint missionary[2];intsavage[2];int step;};

shipSite代表河岸,0代表左岸,1代表目的地右岸。

两个数组missionary和savage分别代表左岸和右岸的传教士或野人人数。

step代表到此状态的步数。

(2) 数据库描述

vector<status>close;

用一个向量close代表已搜索过的状态,配合这结构体中的step成员,避免在搜索过程中走回头路或这多余搜索。当搜索到的一个新状态存在于close中,则判断当前状态的步数是否小于close中相同状态的步数,若小于,说明该搜索有意义,若不小于,说明该搜索是走了回头路或者无意义的。另外,若新状态不存在于close中,则是新状态,无需判断及进行下一步。

(3) 规则库的描述

bool numberCheck(int &missionary,int&savage){if(savage>missionary &&missionary!=0 ){return false;}else{return true;}}

规则为,野人数目总是不超过传教土的数目,但同时未明说的还有一条,若传教士在该岸边或者船上的人数为0,则野人的数目在该位置不受影响,用代码表示如上。

(4) 控制机制

bool move(int missionary,int savage,status&nowStatus){nowStatus.missionary[nowStatus.shipSite]-=missionary;nowStatus.savage[nowStatus.shipSite]-=savage;nowStatus.shipSite=1-nowStatus.shipSite;nowStatus.missionary[nowStatus.shipSite]+=missionary;nowStatus.savage[nowStatus.shipSite]+=savage;nowStatus.step++;vector<status>::iterator iter;iter=find(close.begin(),close.end(),nowStatus);boolresult1=numberCheck(missionary,savage)&&numberCheck(nowStatus.missionary[0],nowStatus.savage[0])&&numberCheck(nowStatus.missionary[1],nowStatus.savage[1]);boolresult2=false;if(iter==close.end())result2=true;elseif(iter!=close.end()&&iter->step>nowStatus.step){iter->step=nowStatus.step;result2=true;}returnresult1&&result2;}

该函数即为程序中的状态生成函数和控制函数,先是计算出新节点的两岸人数,再对新节点两岸人数和生成该新节点的船上人数进行规则检验,结果与运算存到result1中。

其次对搜索状态进行close数据库检验,如上文所说,若是一个新的有意义节点则为真,结果存到result2中,最终函数返回result1与运算result2。

(5) 状态空间图

# 补充 : 此图在制作时有差错, 船上载2人-野人上传0人 -> 传教士应该是2人而非0人

程序清单

#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;struct status
{int shipSite=0;  //0 stand left, 1 stand right ,aim is rightint missionary[2];int savage[2];int step;
};
int shipMax;
vector<status> close;
bool operator == (const status& obj1,const status& obj2)
{return  obj1.shipSite==obj2.shipSite&&obj1.missionary[0]==obj2.missionary[0]&&obj1.missionary[1]==obj2.missionary[1]&&obj1.savage[0]==obj2.savage[0]&&obj1.savage[1]==obj2.savage[1];
}
bool numberCheck(int &missionary,int &savage)
{if( savage>missionary &&missionary!=0 ){return false;}else{return true;}
}
bool move(int missionary,int savage,status &nowStatus)
{nowStatus.missionary[nowStatus.shipSite]-=missionary;nowStatus.savage[nowStatus.shipSite]-=savage;nowStatus.shipSite=1-nowStatus.shipSite;nowStatus.missionary[nowStatus.shipSite]+=missionary;nowStatus.savage[nowStatus.shipSite]+=savage;nowStatus.step++;vector<status>::iterator iter;iter=find(close.begin(),close.end(),nowStatus);bool result1=numberCheck(missionary,savage)&&numberCheck(nowStatus.missionary[0],nowStatus.savage[0])&&numberCheck(nowStatus.missionary[1],nowStatus.savage[1]);bool result2=false;if(iter==close.end())result2=true;else if(iter!=close.end()&&iter->step>nowStatus.step){iter->step=nowStatus.step;result2=true;}return result1&&result2;
}int PruductionSystem(status nowStatus,vector<status> &stepv)
{if(nowStatus.missionary[0]==0&&nowStatus.savage[0]==0){return nowStatus.step;}close.push_back(nowStatus);int minstep=99999;vector<status> bufferInsert;for(int k = 1; k <= shipMax; k++){int shipSavage,shipMissionary;for(shipSavage = 0; shipSavage <=k,shipSavage<=nowStatus.savage[nowStatus.shipSite]; shipSavage++){//cout<<step;shipMissionary=min(k-shipSavage,nowStatus.missionary[nowStatus.shipSite]);//cout<<"smissionary:"<<nowStatus.missionary[nowStatus.shipSite]<<" s savage:"<<nowStatus.savage[nowStatus.shipSite];//cout<<"missionary:"<<shipMissionary<<"  savage:"<<shipSavage;if(shipSavage==0&&shipMissionary==0){//    cout<<endl;continue;}status nextStatus=nowStatus;    int reStep=minstep;vector<status> nextStepv;if(move(shipMissionary,shipSavage,nextStatus)){//    cout<<"next"<<endl;nextStepv.push_back(nextStatus);reStep=PruductionSystem(nextStatus,nextStepv);//cout<<step<<"re:"<<reStep<<endl;}//else cout<<"false"<<endl;if(reStep<minstep){minstep=reStep;bufferInsert.clear();bufferInsert.insert(bufferInsert.begin(),nextStepv.begin(),nextStepv.end());}}}stepv.insert(stepv.end(),bufferInsert.begin(),bufferInsert.end());return minstep;
}
int main(int argc, char const *argv[])
{int missionary,savage;//cout<<"input missionary and savage number,ship number"<<endl;// cin>>missionary>>ship;// savage=missionary;missionary=3;savage=3;shipMax=2; // if(2*missionary<=shipMax||shipMax<2)if( shipMax<2){cout<<"This input illegal"<<endl;}else{status start;start.shipSite=0;start.missionary[0]=missionary;start.missionary[1]=0;start.savage[0]=savage;start.savage[1]=0;start.step=0;vector<status> resultv;resultv.push_back(start);int resStep=PruductionSystem(start,resultv);int i=0;for(vector<status>::iterator iter=resultv.begin();iter!=resultv.end();iter++){cout<<"Step"<<i++<<"\t"<<" lm:"<<iter->missionary[0]<<" ls"<<iter->savage[0]<<" rm:"<<iter->missionary[1]<<" rs"<<iter->savage[1]<<endl;}cout<<"final minstep"<<resStep<<endl;}return 0;
}

主算法采用递归程序设计,每次向子递归传递当前分支探测,并返回是否是可行性结果,用一个close表,来避免探测中的循环以及更新最优路径。

基于产生式系统的野人渡河问题求解相关推荐

  1. 人工智能实验二——prolog语言求解渡河问题(传教士和野人渡河,农夫渡河问题)实现详解

    农夫渡河问题求解 这两个问题都是渡河问题,思路和方式是一样的:给出求解Prolog代码: 问题描述 一个农夫带着一匹狼.一只羊.一颗白菜要过河, 只有一条船而且 农夫每次最多只能带一个动物或物品过河, ...

  2. 人工智能导论实验2——野人渡河黑白棋问题

    人工智能导论实验2--野人渡河&黑白棋问题 实验目的及要求: 本项目要求能够理解人工智能的基本原理,理解状态空间的概念.原理和方法,掌握用状态空间表示问题的步骤,掌握搜索方法的基本原理,并能够 ...

  3. AI A_star算法野人渡河-实验报告

    1. 问题描述及实验要求 请用A*算法实现野人过河问题,(1)分析设计估价函数f(2)采用C语言或Python编程实现(代码中适当加注释,输出具有可读性).        问题描述:设有m个传教士和n ...

  4. C语言版,传教士与野人渡河问题,使用深度优先搜索法求解(DFS),变态版,随便输入人数和船的最大载人数,人工智能经典题目,简单易懂,注释到位,没有bug

    目录 一.问题描述 二.迟来的代码 运行截图 三.简单分析 一.问题描述 有n个传教士和n个野人准备渡河,但只有一条能容纳c个人的小船,为了防止野人侵犯传教士,要求无论在何处,传教士的人数不得少于野人 ...

  5. 人工智能实验报告 牧师与野人渡河 知识表示方法

    牧师与野人渡河问题 编译环境 Dev C++ 5.6.1 windows 10 实验要求 实验代码 #include<cstdio> #include<queue> #incl ...

  6. 基于变色龙算法的线性规划问题求解matlab程序

    基于变色龙算法的线性规划问题求解matlab程序 1 变色龙算法 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为.避役的体长约15-25厘米,身体侧扁,背部有脊椎,头上的枕部有钝 ...

  7. 基于鲸鱼算法的线性规划问题求解matlab程序

    基于鲸鱼算法的线性规划问题求解matlab程序 1 鲸鱼算法 座头鲸有特殊的捕猎方法,这种觅食行为被称为泡泡网觅食法:标准 WOA 模拟了座头鲸特有的搜索方法和围捕机制,主要包括:围捕猎物.气泡网捕食 ...

  8. AI传教士和野人渡河问题-实验报告

    一 题目要求: 设有m个传教士和n个野人来到河边,打算乘一只船从左岸渡到右岸去,该船每次最多载3人.在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉.他们怎样才能用这条船安全地把所有人 ...

  9. DFS实现传教士野人渡河问题

    请将下面这个例子设计成一个状态搜索系统,(1)分析采用宽度优先和深度优先方法分别进行搜索,写出搜索的过程及搜索路径(可以画图来分析)(2)采用C语言或Python编程实现(代码中适当加注释,输出具有可 ...

  10. 基于产生式系统的小型专家系统--动物识别

    一.产生式系统 产生式系统简介 产生式系统是指一组产生式相互配合,协同作用,以求得问题的解.产生式系统一般由3个基本部分组成,分别为规则库.综合数据库和推理机. 规则库又称之为知识库,是某领域知识用规 ...

最新文章

  1. c# 传递Null的string值导致的调用C++的dll报错 Attempted to read or write protected memory.
  2. 检查 linux guest vm 使用的什么 虚拟化技术
  3. linux c openssl rsa 加解密
  4. java字符串类型常量拼接与变量拼接的区别
  5. 【错误记录】Visual Studio 中编译 NDK 报错 ( no matching function for call to ‘cacheflush‘ cacheflush(); )
  6. Python-OpenCV 笔记5 -- 几何变换(Geometric Transformations)
  7. java注释模板_Java注释模板设置
  8. 前端学习(576):margin无效情形之内联特性导致无效
  9. 软通动力华为java机考题库_华为机考笔试刷题-java-1
  10. java outer关键字_java中的关键字
  11. HDU_2156 分数矩阵
  12. 「leetcode」15. 三数之和:双指针法
  13. cdn 阿里cdn请求原理以及缓存机制
  14. matlab在化学中的应用举例,MATLAB在化学中的应用
  15. WIN10 未安装音频设备输出设备 喇叭红叉
  16. 电脑键盘equals在哪个位置_常用标点符号和电脑键盘符号英语表示 -
  17. Unhandled exception occurred whilst decorating page java.lang.ArrayIndexOutOfBoundsException: -1
  18. NNI speedup_model()代码笔记
  19. 北京首都国际机场1号航站楼、2号航站楼、3号航站楼航空公司名单
  20. 输入出租车类型和里程,计算打车的费用。

热门文章

  1. 数论基础——扩展欧几里得【详细】
  2. 论文笔记(1) B4: Experience with a Globally-Deployed Software Defined WAN
  3. 【命令】截屏命令---screencap
  4. js获取ip本机地址
  5. 华为交换机初始化_华为交换机启动配置命令详解大全
  6. 笔记——力学导论(下)
  7. java.lang.NoClassDefFoundError: org/jaxen/JaxenException
  8. 关于PLC的“源型”和“漏型”
  9. fastdfs原理及过程
  10. 尔雅 2017大学计算机基础答案,2018超星尔雅大学计算机基础答案.docx