加粗样式在这里插入代码片

问题描述:
猎人、狗、男人带着男孩1、男孩2,女人带着女孩1、女孩2,一共8个体。一艘小船,一次只能过两个个体,狗和四个小孩不会划船。
注意:
(1)猎人不在,狗咬任何人;
(2)男人不在,女人打男孩;
(3)女人不在,男人打女孩

代码如下:
**

/*思路:用0表示在此岸,1表示在对岸(0,0,0,0,0,0,0,0,0)分别表示猎人,男人
女人,狗狗,女孩,女孩,男孩,男孩,船在此岸。在满足条件是进行状态转移确定
状态结点信息*/
#include<iostream>
#include<stdlib.h>
#include"A_Def.h"
#include"A_Algo.h"
int main() {system("Color B5");int begin[9] = {0,0,0,0,0,0,0,0,0};int end[9] = {1,1,1,1,1,1,1,1,1};A_Star(begin,end);return 0;
}
using namespace std;
void create(Astar &Head) {//创建一个初始化链表Head = (Astar)(malloc(sizeof(AS)));Head->next = NULL;
}
int Is_Empety(Astar Head) {//判断表是否为空if (Head->next!=NULL) return 1;else return 0;
}
int Is_SomeBefor(Astar Sstar, Astar Head) {//判断新生成的结点是否与其
//上一状态的祖辈有相同的状态int i;while (Head!=NULL) {for (i = 0; i <= 8; i++) {if (Sstar->t[i] != Head->t[i])break;}if (i == 9) return 1;Head = Head->parents;}return 0;
}
int Is_OK(Astar A) {//判断是否满足转移条件int F = 1;//if (A->t[0] != A->t[3]) F = 0;if ((A->t[0] && !A->t[3] && (!A->t[1] || !A->t[2]||!A -> t[4]||!A->t[5]||!A->t[6]||!A->t[7]))||(!A->t[0] && A->t[3] && (A->t[1] || A->t[2] || A->t[4] || A->t[5] || A->t[6] ||A->t[7]))) F=0;if ((A->t[1] && !A->t[2] && (!A->t[6] || !A->t[7]))|| (!A->t[1]&& A->t[2] && (A->t[6] || A->t[7])))F=0;if ((A->t[2] && !A->t[1] && (!A->t[4] || !A->t[5])) || (!A->t[2] && A->t[1] && (A->t[4] || A->t[5])))F=0;return F;
}
void Add_Open(Astar &Open,Astar &Check) {//将f排序加入Astar p, q;p = Open;q = Open->next;//while (q!=NULL&&q->f<Check->f) {p = q;q = q->next;}Check->next = p->next;p->next = Check;
}
int G_value(Astar Sstar, Astar& Head) {//计算初始结点到当前考察的实际代价if (Head==NULL)  Sstar->g = 0;else {Sstar->g = Head->g + 1;}return Sstar->g;
}
int H_value(Astar Sstar) {//计算当前结点到目标结点的yuce值 核心2int sum = 0;if (!Sstar->t[8]) {for (int i = 0; i <= 7; i++) {if (!Sstar->t[i])sum++;}if (sum >= 2) {Sstar->h = (sum - 2) * 2 + 1;return Sstar->h;}else { Sstar->h = 1; return 1; }}else {for (int i = 0; i <= 7; i++) {if (!Sstar->t[i])sum++;}Sstar->h = 2*sum;return Sstar->h;}
}
void Open_EnterFirst(int begin[],int end[]) {//Open表加入第一个结点Astar Open_First=Astar(malloc(sizeof(AS)));Open_First->parents = NULL;Open_First->chilren = NULL;Astar Q = NULL;for (int i = 0; i <= 8; i++) Open_First->t[i] = begin[i];Open_First->next = NULL;Open_First->g = G_value(Open_First, Q); Open_First->h = H_value(Open_First);Open_First->f = Open_First->g + Open_First->h; Add_Open(Open, Open_First);
}
void Out(Astar Head,Astar& H) {//从表中取出结点类似于尾插法取出if (!Is_Empety(Head)) {H = NULL;return;}H = Head->next;Head->next = Head->next->next;H->next = NULL;
}
void Enter_Close(Astar Sstar, Astar& Check_L) {//待考察结点进入Close中或普通结点进普通表Sstar->next = Check_L->next;Check_L->next = Sstar;
}
void Out_Path(Astar A_Check) {//输出最快渡河的方案lujincout << "渡河代价:" << A_Check->f << endl;//Astar A_Check1 = A_Check->next; int i = 0;while (A_Check) {if (A_Check->parents) {//确保运行成功for (i = 0; i <= 8; i++) {cout << A_Check->t[i] << " ";if (i == 8) {int p = 1;if (!A_Check->parents->t[8]) {for (int q = 0; q <= 7; q++) {if (!A_Check->parents->t[q]) {//至少为0才过去if (A_Check->t[q] != A_Check->parents->t[q]) {//与下一个状态不相等才过去if (p == 1) cout << "<----";if (q == 0) cout << "猎人" << "过河" <<" " ;if (q == 1) cout << "男人" << "过河" << " ";if (q == 2) cout << "女人" << "过河" << " ";if (q == 3) cout << "狗狗" << "过河" << " ";if (q == 4) cout << "女孩" << "过河" << " ";if (q == 5) cout << "女孩" << "过河" << " ";if (q == 6) cout << "男孩" << "过河" << " ";if (q == 7) cout << "男孩" << "过河" << " ";p++;}else continue;}else continue;}}else{int r = 1;for (int q = 0; q <= 7; q++) {if (A_Check->parents->t[q]) {//至少为1才过去if (A_Check->t[q] != A_Check->parents->t[q]) {//与下一个状态不相等才过去if (r == 1) cout << "<----";if (q == 0) cout << "猎人" << "回去" << " "; if (q == 1) cout << "男人" << "回去" << " ";if (q == 2) cout << "女人" << "回去" << " ";if (q == 3) cout << "狗狗" << "回去" << " ";r++;}else continue;}else continue;}}}}cout << endl;A_Check = A_Check->parents;}}
}
int Is_In(Astar  A_Check_L_One,Astar Check,Astar &M,Astar &N) {//判断某结点状态在哪个表中int i; N = Check;Check = Check->next;while (Check !=NULL) {for ( i = 0; i <= 8; i++) {  if (A_Check_L_One->t[i] != Check->t[i])break;}if (i == 9) {M = Check;return 1; }N = Check;Check = Check->next;}return 0;
}
int Is_Same(Astar A, Astar Sstar) {//同一层是否重复int i = 0; A = A->next; while (A) {for (i = 0; i <= 8; i++) {//cout << A->t[i] << "==" << Sstar->t[i] ;if (A->t[i] != Sstar->t[i])break;}if (i == 9) return 1;A = A->next;}return 0;
}
void A_Check_LS(Astar A_Check_L, Astar A_Check) {//通过将上一个状态传过来来实现状态转移并且确定状态结点信息(g,h,f),状态转移设置两种方式-->2*2=4//细节较多//Astar Sstar = (Astar)malloc(sizeof(AS));//Astar Sstar1 = (Astar)malloc(sizeof(AS));int t0 ; //for (int i = 0; i <= 8; i++) cout << A_Check->t[i] << "++";; cout << endl;int t1[9], t2[9];for (int i = 0; i <= 8; i++)  t2[i] = A_Check->t[i];if (!A_Check->t[8]) { t0 = 1;for (int i = 0; i <= 2; i++) {for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];//操作之前for (int i = 0; i <= 2; i++) { if (!A_Check->t[i]) t0++;  }if (t0 != 1 ) {//细节 判断是否有大人if (!A_Check->t[i])A_Check->t[i] = 1;else continue;for (int i = 0; i <= 8; i++)  t1[i] = A_Check->t[i];//操作之后for (int j = 0; j <= 7; j++) {for (int i = 0; i <= 8; i++)  A_Check->t[i] = t1[i];//操作之前if (i == j) continue;if (!A_Check->t[j])A_Check->t[j] = 1;else continue;//Astar A_Check_Check;//判断对面的是否也符合 if (Is_OK(A_Check)) {Astar Sstar = (Astar)malloc(sizeof(AS));for (int i = 0; i <= 8; i++) Sstar->t[i] = A_Check->t[i];Sstar->t[8] = 1;//细节必须在IF的上面if (Is_SomeBefor(Sstar, A_Check->parents) || Is_Same(A_Check_L, Sstar)) free(Sstar);else{Sstar->chilren = NULL;Sstar->parents = A_Check; Sstar->next = NULL;Sstar->f = G_value(Sstar, A_Check) + H_value(Sstar);for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];// cout << Sstar->f<<"++"<<Sstar->parents->g<<"++"<<Sstar->h<<" ";Enter_Close(Sstar, A_Check_L); //for (int i = 0; i <= 8; i++) cout << A_Check->t[i] << "<<++<"; cout << endl;}}}}else break;}for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];for (int i = 0; i <= 2; i++) {for (int i = 0; i <= 8; i++)  A_Check->t[i] = t2[i];if (!A_Check->t[i])A_Check->t[i] = 1;else continue;if (Is_OK(A_Check)){Astar Sstar1 = (Astar)malloc(sizeof(AS));for (int i = 0; i <= 8; i++) Sstar1->t[i] = A_Check->t[i];            Sstar1->t[8] = 1;if (Is_SomeBefor(Sstar1, A_Check->parents) || Is_Same(A_Check_L, Sstar1)) free(Sstar1);else {Sstar1->chilren = NULL;Sstar1->parents = A_Check;Sstar1->next = NULL;Sstar1->f = G_value(Sstar1, A_Check) + H_value(Sstar1);for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];// cout << Sstar1->f << "--" << Sstar1->g << "--" << Sstar1->h << " ";Enter_Close(Sstar1, A_Check_L);}}}}else {for (int i = 0; i <= 2; i++) {for (int i = 0; i <= 8; i++) A_Check->t[i]=t2[i];{if (A_Check->t[i])A_Check->t[i] = 0;else continue; }if (Is_OK(A_Check)) {Astar Sstar = (Astar)malloc(sizeof(AS));for (int i = 0; i <= 8; i++) Sstar->t[i] = A_Check->t[i];Sstar->t[8] = 0;if (Is_SomeBefor(Sstar, A_Check->parents) || Is_Same(A_Check_L, Sstar)) free(Sstar);else {Sstar->chilren = NULL;Sstar->parents = A_Check;Sstar->next = NULL;Sstar->f = G_value(Sstar, A_Check) + H_value(Sstar);for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i]; //cout << Sstar->f << "**" << Sstar->g << "**" << Sstar->h << " ";Enter_Close(Sstar, A_Check_L);// for (int i = 0; i <= 8; i++)   //cout<< Sstar->t[i]<<"<<<"; cout << endl;}}//for (int i = 0; i <= 8; i++)  A_Check->t[i]=t2[i];}for (int i = 0; i <= 8; i++) A_Check->t[i]=t2[i] ;A_Check->t[8] = 1;for (int i = 0; i <= 2; i++) {for (int i = 0; i <= 8; i++)  A_Check->t[i]=t2[i];if (!A_Check->t[i]) continue;elseA_Check->t[i] = 0; for (int i = 0; i <= 8; i++)  t1[i] = A_Check->t[i];for (int j = 0; j <= 3; j++) {if (i==j) continue;for (int i = 0; i <= 8; i++)  A_Check->t[i]=t1[i];if (!A_Check->t[j]) continue;elseA_Check->t[j] = 0;if (Is_OK(A_Check)) {Astar Sstar1 = (Astar)malloc(sizeof(AS));for (int i = 0; i <= 8; i++) Sstar1->t[i] = A_Check->t[i]; Sstar1->t[8] = 0; if (Is_SomeBefor(Sstar1, A_Check->parents )|| Is_Same(A_Check_L, Sstar1)) free(Sstar1);else {Sstar1->chilren = NULL;Sstar1->parents = A_Check;Sstar1->next = NULL;Sstar1->f = G_value(Sstar1, A_Check) + H_value(Sstar1); for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];// cout << Sstar1->f << "//" << Sstar1->g << "//" << Sstar1->h << " ";Enter_Close(Sstar1, A_Check_L);// for (int i = 0; i <= 8; i++)  // cout<< Sstar1->t[i]<<"<<<"; cout << endl;}}}}}for (int i = 0; i <= 8; i++) A_Check->t[i] = t2[i];
}
int Is_Over(Astar Over) {int i;for (i = 0; i <= 8; i++)if (!Over->t[i]) {break;}if (i == 9)   return 1; return 0;
}
void A_Star(int begin[],int end[]) {//核心 1Astar A_Check=NULL;Astar Check_A=NULL;Astar A_Check_L;Astar A_Check_L_One;//Astar A_ChuanChuan;//串串儿 一串到底Astar M = NULL;Astar N = NULL;//A_ChuanChuan = NULL;int F=0,f=0;create(Open);create(Close);create(A_Check_L);Open_EnterFirst(begin,end); while (Is_Empety(Open)) {Out(Open, A_Check); Enter_Close(A_Check, Close); if (Is_Over(A_Check)) { F = 1; break; }A_Check_LS(A_Check_L, A_Check);/*  while (Is_Empety(A_Check_L)){Out(A_Check_L, A_Check_L_One);cout<< "++"; //测验}*/while (Is_Empety(A_Check_L)){Out(A_Check_L, A_Check_L_One);if (Is_In(A_Check_L_One, Open, M, N)){if (M->g > A_Check_L_One->g){M->parents = A_Check_L_One->parents;M->g = A_Check_L_One->g;M->f = A_Check_L_One->f;}}else if (Is_In(A_Check_L_One, Close, M, N)){if (M->g > A_Check_L_One->g){Astar Q; M->parents = A_Check_L_One->parents;M->g = A_Check_L_One->g;M->f = A_Check_L_One->f; M->chilren = NULL;Out(Close, Q);Add_Open(Open, Q);}}else {Add_Open(Open, A_Check_L_One); }}} if(F)Out_Path(A_Check);
}
typedef struct A {int t[9];struct A* next;struct A* parents;struct AA* chilren;int f;int g;int h;
} AS, * Astar;
typedef struct AA {struct AA* next;struct A* To_A;;
}AAS,*AAstar;
Astar Open;
Astar Close;

**
运行结果

图片:
第1步:猎人和狗过河
第2步:猎人回来
第3步:猎人带一个女儿过河
第4步:猎人和狗回来
第5步:女人带另外一个女孩过河
第6步:女人回来
第7步:男人和女人过河(还要把船带回来,所以男人得过去)
第8步:男人过来
第9步:猎人和狗过去
第10步:女人回来
第11步:女人和男人过河
第12步:男人回来
第13步:男人带一个男孩过河
第14步:猎人和狗回去
第15步:猎人和男孩过河
第16步:猎人回去
第17步:猎人和狗过来

这个猎人渡河问题本身挺简单的,但要用A*算法实现起来并不太简单,因为细节实在太多。另外这题的转态结点在OPEN表和CLOUED表中的并不多,这使得一些Astar算法中的必须要的操作在这里并没有起到作用,所以这个并不是Astar算法的一个典型问题。那为啥我还要写这个呢?我们小唐老师在讲Astar算法时说谁要是用Astar算法写出这个,谁期末就不用考了。所以我就搞起来了,,。

A*算法实现猎人渡河问题相关推荐

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

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

  2. 快速渡河(贪心算法)

    问题描述 有n的人需要过河,但只有一只船,且一次只能载两个人.每个人都有一个渡河的速度,过河的速度取决于速度最慢的那一个,求所有人过完河的最短时间. 输入一个n,表示有n个人. 接着输入n个整数表示每 ...

  3. 数据结构与算法笔记:计算思维之人鬼渡河问题

    人鬼渡河问题 1 ) 问题描述 目标:将东岸的3人3鬼通过一只小船安全转移到西岸,希望摆渡次数尽可能少 条件 船的容量有限,一次最多只能坐2人(或2鬼或1人1鬼) 无论是在河的东岸还是在河的西岸,一旦 ...

  4. 信息学奥赛第十节 —— 贪心算法(渡河问题POJ 1700 Crossing River + 拦截导弹的系统数量求解)

    复习概念 贪心算法又叫贪婪算法,是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,贪心算法不从整体最优上加以考虑,它所做出的是在某种意义上的局部最优解. 无后效性:贪心算法不是对所有问题都 ...

  5. 猎人抓兔子 - (广度优先算法)

    题目描述: 假设有一只兔子,有4个排成一排的洞,编号为1和4.兔子每天晚上跳到相邻的一个洞里住,2号洞可以跳1号和3号洞,4号洞只能跳3号洞.而猎人每天白天检查其中的一个洞.猎人告诉你每天检查的洞的编 ...

  6. 算法很没:快速渡河问题

    题目描述 N个人希望只乘一条船过河,每条船最多只能载两个人.因此,必须安排谁去与回来,以便所有人最快过河.每个人都有不同的划船速度:两个人速度取决于较慢者.请给出时间最短的策略. 输入值 输入的第一行 ...

  7. 算法学习——贪心算法解渡河问题(C语言版)

    题目一:有A组人,每组有N人,想用一艘船渡河,该船一次只能载两个人.每个人划船的速度不同,当两个人一组时船的速度由最慢的人决定.求一种方法能让所有人过河并且船的往返时间最短. 输入:第一行输入A:第二 ...

  8. 一名宝藏猎人在洛基山脉失踪,几个月后,计算机算法找到了他

    当Randy Bilyeu失踪的时候,他正在寻找Fenn Treasure,据称这个宝藏里装满了黄金.宝石和珠宝,传说这一宝藏藏身于新墨西哥州圣达菲洛基山脉的北部. 在2010年,百万富翁艺术品经销商 ...

  9. EM算法(Expectation Maximization)期望最大化算法

    原文:EM(期望最大化)算法初步认识 - 大数据和AI躺过的坑 - 博客园 https://www.cnblogs.com/zlslch/p/6965374.html 机器学习十大算法之一:EM算法( ...

最新文章

  1. Java 内存模型 与 高效并发
  2. Android移动开发之【Android实战项目】DAY13-MPChart简单的折线图LineChart
  3. 项目部署、配置、查错常用到的Linux命令
  4. c语言不会可以学好java吗_C语言一定要学好吗?
  5. 团队博客第五周 运行与总结
  6. 23种设计模式的有趣见解 .
  7. linux下进程监听端口,linux下查看监听端口对应的进程
  8. 数组tostring方法_数组toString()方法以及JavaScript中的示例
  9. UE4 无法include “filename.generated.h”
  10. java 调用 oracle的function 和 procedure
  11. C++对象数组 —— 学生信息表
  12. 税务计算机类考试题型,2020年税务师考试题型、计算器使用规定及考试难度
  13. 中国移动彩信业务资料集合
  14. java mvc接收json_详解springmvc 接收json对象的两种方式
  15. comms-logging 输出级别设置
  16. RK3588快速上手 | 01-RK3588开发板快速上手
  17. react-native结合react-navigation之TabNavigator
  18. Self-supervised Graph Learning for Recommendation
  19. 凯捷面试(2):JavaWeb、框架
  20. 第四回:matplotlib文字图例尽眉目

热门文章

  1. Create Apps with Material Design
  2. 安卓手机与蓝牙模块联合调试(五)-- 编写自己的蓝牙控制界面控制单片
  3. php中局部变量和全局变量
  4. 【华为机试真题 Python实现】2023年1、2月高频机试题
  5. Redis持久化的两种方式
  6. C语言从零开始——学这一篇文章就够了
  7. 结合GIS与空间大数据的淄博烧烤空间可视化分析
  8. Excel 中自动阅卷的实现
  9. 智慧电子班牌系统源码,家校互联APP源码,SaaS云平台源码
  10. 如何检查自己的笔记本电池是否需要更换(电池自检)