LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: sipingal

农夫过河问题?

[复制链接]
发表于 2004-9-23 22:24:30 | 显示全部楼层
我觉得用 scheme 的 amb 表达式做的话,会简单一些。
主要就是用回溯来试探,最后比较出一个最优解。
 楼主| 发表于 2004-9-24 10:43:24 | 显示全部楼层

这里有个C的范例(用队列算法)

哪位能否稍加说明

  1. /* 用队列解决农夫过河问题的算法*/


  2. #include<stdio.h>
  3. #include<stdlib.h>

  4. #define  MAXNUM   20

  5. typedef int DataType;
  6. struct  SeqQueue {              /* 顺序队列类型定义 */
  7.     int  f, r;
  8.     DataType q[MAXNUM];
  9. };

  10. typedef struct SeqQueue *PSeqQueue;     /* 顺序队列类型的指针类型 */

  11. PSeqQueue createEmptyQueue_seq( void ) {
  12.     PSeqQueue paqu = (PSeqQueue)malloc(sizeof(struct SeqQueue));
  13.     if (paqu == NULL)
  14.         printf("Out of space!! \n");
  15.     else
  16.         paqu->f = paqu->r = 0;
  17.     return (paqu);
  18. }

  19. int isEmptyQueue_seq( PSeqQueue paqu ) {
  20.     return paqu->f == paqu->r;
  21. }
  22. /* 在队列中插入一元素x */
  23. void  enQueue_seq( PSeqQueue paqu, DataType x ) {
  24.     if ( (paqu->r + 1) % MAXNUM == paqu->f  )
  25.         printf( "Full queue.\n" );
  26.     else {
  27.         paqu->q[paqu->r] = x;
  28.         paqu->r = (paqu->r + 1) % MAXNUM;
  29.     }
  30. }

  31. /* 删除队列头部元素 */
  32. void  deQueue_seq( PSeqQueue paqu ) {
  33.     if( paqu->f == paqu->r )
  34.         printf( "Empty Queue.\n" );
  35.     else
  36.         paqu->f = (paqu->f + 1) % MAXNUM;
  37. }

  38. /* 对非空队列,求队列头部元素 */
  39. DataType  frontQueue_seq( PSeqQueue paqu ) {
  40.     return (paqu->q[paqu->f]);
  41. }

  42. int farmer(int location) {
  43.     return 0 != (location & 0x08);
  44. }

  45. int wolf(int location) {
  46.     return 0 != (location & 0x04);
  47. }

  48. int cabbage(int location) {
  49.     return 0 != (location & 0x02);
  50. }

  51. int goat(int location) {
  52.     return 0 !=(location & 0x01);
  53. }

  54. /* 若状态安全则返回true */
  55. int safe(int location) {
  56.     /* 羊吃白菜 */
  57.     if ((goat(location) == cabbage(location)) &&
  58.           (goat(location) != farmer(location)) )
  59.         return 0;
  60.     /* 狼吃羊 */
  61.     if ((goat(location) == wolf(location)) &&
  62.           (goat(location) != farmer(location)))
  63.         return 0;
  64.     return 1;    /* 其他状态是安全的 */
  65. }


  66. void farmerProblem( ) {
  67.     int movers, i, location, newlocation;
  68.     int route[16];        /*记录已考虑的状态路径*/
  69.     PSeqQueue moveTo;
  70.     /*准备初值*/
  71.     moveTo = createEmptyQueue_seq( );
  72.     enQueue_seq(moveTo, 0x00);
  73.     for (i = 0; i < 16; i++) route[i] = -1;
  74.     route[0]=0;

  75.     /*开始移动*/
  76.     while (!isEmptyQueue_seq(moveTo)&&(route[15] == -1)) {
  77.         /*得到现在的状态*/
  78.         location = frontQueue_seq(moveTo);
  79.         deQueue_seq(moveTo);
  80.         for (movers = 1; movers <= 8; movers <<= 1) {
  81.             /* 农夫总是在移动,随农夫移动的也只能是在农夫同侧的东西 */
  82.             if ((0 != (location & 0x08)) == (0 != (location & movers))) {
  83.                 newlocation = location^(0x08|movers);
  84.                 if (safe(newlocation) && (route[newlocation] == -1)) {
  85.                     route[newlocation] = location;
  86.                     enQueue_seq(moveTo, newlocation);
  87.                 }
  88.             }
  89.         }
  90.     }

  91.     /* 打印出路径 */
  92.     if(route[15] != -1) {
  93.         printf("The reverse path is : \n");
  94.         for(location = 15; location >= 0; location = route[location]) {
  95.             printf("The location is : %d\n",location);
  96.             if (location == 0) return;
  97.         }
  98.     }
  99.     else
  100.         printf("No solution.\n");
  101. }


  102. int main() {
  103.     farmerProblem( );
  104.     return 0;
  105. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表