传教士与野人过河问题:

任意时刻,左岸、右岸、船上如果传教士人数少于野人人数,传教士就会被野人吃掉。当然野人会划船。传教士人数为0也是可以的。

启发函数 f=g+h.  g当前结点所在解空间树的深度。h=m+c-2*b. m,c分别是当前状态下左岸传教士和野人的数目。b=1表示当前船在左岸停靠。b=0表示当前状态船在右岸。

#include<vector>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define MAXM 5
#define MAXC 5
typedef struct Node { int M, C, B; int g, h, f; int parent;//记录父节点在tree中的下标 }Node; vector<Node> open; vector<Node> close; vector<Node> tree; Node boat[8] = { { 0,1,1,0,0,0,-1 }, { 0,2,1,0,0,0,-1 }, { 0,3,1,0,0,0,-1 }, { 1,0,1,0,0,0,-1 }, { 1,1,1,0,0,0,-1 }, { 2,0,1,0,0,0,-1 }, { 2,1,1,0,0,0,-1 }, { 3,0,1,0,0,0,-1 } }; void show_open() {//显示open表 vector<Node>::iterator ite; ite = open.end()-1; for (; ite >=open.begin(); ite--) { printf("(%d,%d,%d,%d,%d,%d)\n", (*ite).M, (*ite).C, (*ite).B, (*ite).g, (*ite).h, (*ite).f); if (ite == open.begin()) break; } } void show_close() {//显示close表 vector<Node>::iterator ite; ite = close.begin(); for (; ite < close.end(); ite++) { printf("(%d,%d,%d,%d,%d,%d)\n", (*ite).M, (*ite).C, (*ite).B, (*ite).g, (*ite).h, (*ite).f); } } bool operator ==(Node a, Node b) { return(a.M == b.M&&a.C == b.C&&a.B == b.B); } bool exit_open(Node p) {//判断节点是否存在open表中 if(find(open.begin(), open.end(), p)==open.end()) return false; else return true; } bool exit_close(Node p) {//判断节点是否存在close表中 if (find(close.begin(), close.end(), p) == close.end()) return false; else return true; } bool comp(Node a, Node b) { return a.f > b.f;//根据估价函数值降序排列 } void add_open(Node p) {//open表添加  open.push_back(p); sort(open.begin(), open.end(), comp);//默认升序排列,这里comp按降序排列 } void add_close(Node p) {//close表添加  close.push_back(p); } void out_open() {//open表删除  open.pop_back(); } bool judge_Node(Node p) {//判断状态p是否合法 if (p.M > MAXM || p.C > MAXC || p.M < 0 || p.C < 0)//不在范围内。不合法 return false; /*if (((p.M >= p.C) && (MAXM - p.M >= MAXC - p.C)) || (p.M == MAXM) || (p.M == 0)) return true; return false;*/ else if (p.M != 0 && p.M < p.C)//左岸传教士人数不为0 并且小于野人数 return false; else if (MAXM - p.M != 0 && MAXM - p.M < MAXC - p.C)//右岸传教士人数不为0就算了 居然比野人数少!!当然不行 return false; else return true; } void expand(Node p) {//对节点p进行扩展  Node q; printf("------------------------------------------------------------------------------------\n"); printf("\t\t\t对结点: "); printf("( %d %d %d )进行扩展\n", p.M, p.C, p.B); for (int i = 0; i < 8; i++) { if (p.B == 1) {//p船在左岸 q.M = p.M - boat[i].M; q.C = p.C - boat[i].C; q.B = p.B - boat[i].B; } else {//p船在右岸 q.M = p.M + boat[i].M; q.C = p.C + boat[i].C; q.B = p.B + boat[i].B; } if (judge_Node(q) && !exit_open(q) && !exit_close(q)) {//避免死循环 已经扩展过的结点不再扩展 q.g = p.g + 1; q.h = q.M + q.C - 2 * q.B; q.f = q.g + q.h; int pos = find(tree.begin(), tree.end(), p)-tree.begin(); q.parent = pos; printf("扩展出新的子结点:"); printf("(%d,%d,%d,%d,%d,%d)\n",q.M,q.C,q.B,q.g,q.h,q.f); add_open(q); tree.push_back(q); } else { printf("\t------节点(%d,%d,%d)不满足条件,扩展失败------\n", q.M, q.C, q.B); } } printf("\t\t=======================================================\n"); add_close(p); printf("\t\t\t\t******open表状态******\n"); show_open(); printf("\t\t\t\t******close表状态******\n"); show_close(); printf("------------------------------------------------------------------------------------\n"); } bool destination(Node p) {//判断p是否为目标节点 if (p.M == 0 && p.C == 0 && p.B == 0) return true; else return false; } Node solve() { Node p{ 5, 5, 1, 0, 10, 10,-1 }; open.push_back(p); tree.push_back(p); char c; Node x; while (open.size() != 0) { x = *(open.end() - 1);//从open表中取出一个进行扩展 if (destination(x)) return x;//如果是目标状态 则结束 out_open();//从open中删除 expand(x);//扩展该结点 //getchar();  } //return NULL; } void path(Node p) { vector<Node> temp; while (p.parent!=-1) { temp.push_back(p); p = tree[p.parent]; } temp.push_back(p); vector<Node>::iterator ite1 = temp.end() - 1; for (; ite1 >= temp.begin(); ite1--) { printf("(%d,%d,%d,%d,%d,%d)\n", (*ite1).M, (*ite1).C, (*ite1).B, (*ite1).g, (*ite1).h, (*ite1).f); if (ite1 == temp.begin()) break; } } int main() { Node goal=solve(); printf("求得传教士与野人过河问题状态空间的一个解为:\n"); path(goal); }

转载于:https://www.cnblogs.com/Elaine-DWL/p/6618307.html

传教士与野人过河问题(A*搜索 C++)相关推荐

  1. 传教士与野人过河问题 人工智能实验算法

    问题描述 有 N 个传教士和 N 个野人来到河边渡河,河岸有一条船,每次至多可供 k 人乘渡.问:传教士为了安全起见,应如何规划摆渡方案,使得任何时刻, 河两岸以及船上的野人数目总是不超过传教士的数目 ...

  2. 野人与传教士过河java_传教士和野人过河(经典MC问题)

    这个问题本来是<人工智能技术导论>第三章的课后题,今天上午考试正巧考到了这道题,要我们画状态转换图,我之前思考过一点,所以写出的状态表示应该没有问题,但这些状态太多了.......,十来种 ...

  3. JAVA野人_Java实现传教士与野人过河问题

    1  问题定义 河的两岸有三个传教士和三个野人需要过河,目前只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于传教士的人数,那么传教士就会被野人攻击,怎么找出一种安全的渡河方案呢? ...

  4. 传教士与野人问题的C++搜索实现

      人工智能引论课第一次作业:使用搜索解决传教士与野人问题. 题目要求   河岸的一侧有野人与传教士各 m m m个,有一条能容纳 n n n个人的船.传教士与野人都会划船,现在要求任何情况下,野人数 ...

  5. 人工智能:传教士与野人过河(BFS-基于对列和链表的实现)c++

    传教士(牧师)与野人问题 问题描述: 有n个牧师和n个野人准备渡河,但只有一条能容纳c个人的小船,为了防止野人侵犯牧师,要求无论在何处,牧师的人数不得少于野人的人数(除非牧师人数为0),且假定野人与牧 ...

  6. python深度优先搜索传教士和野人_ai1 带回溯的深度优先策略:解决经典野人传教士过河问题的求解:三个修道士和三个野人过河 - 下载 - 搜珍网...

    带回溯的深度优先策略:解决经典野人传教士过河问题的求解:三个修道士和三个野人过河,船一次最多只能载两个人,在任何时候修道士的人数不能少于野人人数,否则野人会吃掉修道士.找出六个人顺利过河的所有方案. ...

  7. python深度优先搜索传教士和野人_传教士和野人问题解题思路

    传教士和野人渡河问题 刘宪国050422023 野人过河问题描述如下:有三个传教士和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于传教士的人数,那么传教士就会有危险 ...

  8. 过河问题(牛虎过河、商人仆人过河、农夫妖怪过河、传教士野人过河)(第2届第2题)

    ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ 最新链接 题目要求 问题描述:三只牛三只虎过河,船最多只能容纳两只动物,且船在往返途中不能为空. ...

  9. 人工智能--野人过河

    课程简介 人工智能(Artificial Intelligence),英文缩写为AI.它是研究.开发用于模拟.延伸和扩展人的智能的理论.方法.技术及应用系统的一门新的技术科学.人工智能的定义可以分为两 ...

最新文章

  1. LeetCode简单题之数字转换为十六进制数
  2. CSS将长文字换行的方法 (转)
  3. RHCE 学习笔记(20) ACL
  4. 【机器学习】理解机器学习
  5. 【知识索引】【汇编语言】
  6. Atitit 可读性的艺术 目录 1. 原则类 1 2. 方法类 2 2.1. 1.8. 选择选择表格化 3 2 2.2. 体现了“声明式编程”的风格,即只要说明意图,而不需要写出处理细节。 2 2
  7. java接口自动化测试
  8. usb调试软件_想防止软件后台偷偷运行,那就把它们冻结起来
  9. 零基础自学计算机方法大全
  10. axture工具栏使用
  11. c++多线程detach函数用法的实例
  12. 远程桌面不能复制粘贴
  13. 简单实用计划提醒便签软件 界面简洁功能一目了然
  14. 月份和星期的英语(请不要再弄错了)
  15. CJSON 使用介绍
  16. 2020-08-22
  17. [Unity多人游戏插件]Playfab 的下载 安装以及简单的说明
  18. python非参数检验的区别_python KS-检验(Kolmogorov-Smirnov test) -- 检验数据是否符合某种分布...
  19. 二级计算机哪种最简单,计算机二级考什么好 哪个最实用
  20. 电视猫(TVMAO.COM)网络电视频道被百度封杀与解封过程

热门文章

  1. JavaScript常用输入输出语句
  2. # 2017年蓝桥杯省赛cc++本科B组试题
  3. 智能图书管理系统V2.0-完整版
  4. oracle access advisor,oracle11g新特性-SQL Access Advisor
  5. 数据挖掘思维和实战12 支持向量机(SVM):用一条线分开红豆与绿豆
  6. MATLAB笔记5:矩阵的转置、求逆、旋转、翻转;矩阵的行列式、秩、迹;矩阵的特征值、特征向量
  7. 基于php的汉服网站
  8. java版微信小程序登录商城源码Spring Cloud+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码
  9. 熵相似_高熵合金领域高被引的11篇文章,给过你那些启示?
  10. PS文字蒙版的应用·让文字变化多端