新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> We choose to study algorithmic problems,  not because they are easy,  but because they are hard.
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机理论与工程『 算法理论与分析 』 → 过河问题[讨论] 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 27327 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 过河问题[讨论] 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     binaryluo 帅哥哟,离线,有人找我吗?
      
      
      威望:6
      等级:研二(Pi-Calculus看得一头雾水)(版主)
      文章:679
      积分:5543
      门派:IEEE.ORG.CN
      注册:2005/2/19

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给binaryluo发送一个短消息 把binaryluo加入好友 查看binaryluo的个人资料 搜索binaryluo在『 算法理论与分析 』的所有贴子 引用回复这个贴子 回复这个贴子 查看binaryluo的博客21
    发贴心情 

    终于可以了:)
    原来是判断递归结束的四个if语句中,有一句的一个变量名写错了。


    typedef struct _stNode {
     int hl, bl, hr, br;
     pos bp;     /* boat position */
     struct _stNode *parent;
    } stNode;

    bool humbst(stNode st, FILE *fp, void (*opt)(stNode sm, void *fp))
    {
     bool rev = false;

     do
     {
      /* 该状态与初始状态相同的情况不操作 */
      if (st.hl == N && st.bl == N && st.hr == 0 &&
       st.br == 0 && st.bp == left && st.parent != NULL)
       break;

      /* 该状态与祖父状态相同的情况不操作 */
      if (st.parent != NULL && st.parent->parent != NULL)
      {
       if ((st.hl == st.parent->parent->hl)
        && (st.bl == st.parent->parent->bl)
        && (st.hr == st.parent->parent->hr)
        && (st.br == st.parent->parent->br)
        && (st.bp == st.parent->parent->bp))
        break;
      }

      /* 人数小于兽数的时候不满足 */
      if ((st.hl != 0 && st.hr != 0 && (st.hl < st.bl || st.hr < st.br))
       || (st.hl != 0 && st.hr == 0 && st.hl < st.bl)
       || (st.hl == 0 && st.hr != 0 && st.hr < st.br))
       break;

      /* 中止状态 */
      if (st.hl == 0 && st.bl == 0 && st.hr == N &&
       st.br == N && st.bp == right)
      {
       opt(st, fp);
       rev = true;
       break;
      }

      /* 正常情况 */
      opt(st, fp);
      switch (st.bp)
      {
      case left:
       rev = humbst_left(st, fp, stDisp);
       break;

      case right:
       rev = humbst_right(st, fp, stDisp);
       break;
      }
     } while (false);

     return rev;
    }

    bool humbst_left(stNode st, FILE *fp, void (*opt)(stNode sm, FILE *fp))
    {
     bool rev = false;
     stNode st1, st2, st3, st4, st5;

     if (st.hl >= 1) /* 将左边的一个人运到右边 */
     {
      st1.hl = st.hl - 1;
      st1.bl = st.bl;
      st1.hr = st.hr + 1;
      st1.br = st.br;
      st1.bp = right;
      st1.parent = &st;
      rev = humbst(st1, fp, opt);
     }

     if (st.hl >= 2) /* 将左边的两个人运到右边 */
     {
      st2.hl = st.hl - 2;
      st2.bl = st.bl;
      st2.hr = st.hr + 2;
      st2.br = st.br;
      st2.bp = right;
      st2.parent = &st;
      rev = humbst(st2, fp, opt);
     }

     if (st.bl >= 1) /* 将左边的一个兽运到右边 */
     {
      st3.hl = st.hl;
      st3.bl = st.bl - 1;
      st3.hr = st.hr;
      st3.br = st.br + 1;
      st3.bp = right;
      st3.parent = &st;
      rev = humbst(st3, fp, opt);
     }

     if (st.bl >= 2) /* 将左边的两个兽运到右边 */
     {
      st4.hl = st.hl;
      st4.bl = st.bl - 2;
      st4.hr = st.hr;
      st4.br = st.br + 2;
      st4.bp = right;
      st4.parent = &st;
      rev = humbst(st4, fp, opt);
     }

     if (st.hl >= 1 && st.bl >= 1) /* 将左边的一个人一个兽运到右边 */
     {
      st5.hl = st.hl - 1;
      st5.bl = st.bl - 1;
      st5.hr = st.hr + 1;
      st5.br = st.br + 1;
      st5.bp = right;
      st5.parent = &st;
      rev = humbst(st5, fp, opt);
     }

     return rev;
    }

    bool humbst_right(stNode st, FILE *fp, void (*opt)(stNode sm, FILE *fp))
    {
     bool rev = false;
     stNode st1, st2, st3, st4, st5;

     if (st.hr >= 1) /* 将右边的一个人运到左边 */
     {
      st1.hl = st.hl + 1;
      st1.bl = st.bl;
      st1.hr = st.hr - 1;
      st1.br = st.br;
      st1.bp = left;
      st1.parent = &st;
      rev = humbst(st1, fp, opt);
     }

     if (st.hr >= 2) /* 将右边的两个人运到左边 */
     {
      st2.hl = st.hl + 2;
      st2.bl = st.bl;
      st2.hr = st.hr - 2;
      st2.br = st.br;
      st2.bp = left;
      st2.parent = &st;
      rev = humbst(st2, fp, opt);
     }

     if (st.br >= 1) /* 将右边的一个兽运到左边 */
     {
      st3.hl = st.hl;
      st3.bl = st.bl + 1;
      st3.hr = st.hr;
      st3.br = st.br - 1;
      st3.bp = left;
      st3.parent = &st;
      rev = humbst(st3, fp, opt);
     }

     if (st.br >= 2) /* 将右边的两个兽运到左边 */
     {
      st4.hl = st.hl;
      st4.bl = st.bl + 2;
      st4.hr = st.hr;
      st4.br = st.br - 2;
      st4.bp = left;
      st4.parent = &st;
      rev = humbst(st4, fp, opt);
     }

     if (st.hr >= 1 && st.br >= 1) /* 将右边的一个人一个兽运到左边 */
     {
      st5.hl = st.hl + 1;
      st5.bl = st.bl + 1;
      st5.hr = st.hr - 1;
      st5.br = st.br - 1;
      st5.bp = left;
      st5.parent = &st;
      rev = humbst(st5, fp, opt);
     }

     return rev;
    }


    humbest函数其实就是构造一个状态变迁图(树),然后用opt函数来对该图进行操作(比如说dfs)。在此衷心感谢Logician和phoenixinter热心参与讨论,你们的想法给了我很多提示。^_^

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/6/3 8:29:00
     
     binaryluo 帅哥哟,离线,有人找我吗?
      
      
      威望:6
      等级:研二(Pi-Calculus看得一头雾水)(版主)
      文章:679
      积分:5543
      门派:IEEE.ORG.CN
      注册:2005/2/19

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给binaryluo发送一个短消息 把binaryluo加入好友 查看binaryluo的个人资料 搜索binaryluo在『 算法理论与分析 』的所有贴子 引用回复这个贴子 回复这个贴子 查看binaryluo的博客22
    发贴心情 
    以下是引用Logician在2006-6-2 17:32:00的发言:
    “状态变迁图”并不用显式的给出呀,从当前状态动态生成就可以了。
    你以前用没有试过用BFS/DFS求解问题吗?
    比如现在的状态是(X,Y,1),你可以算出,从它能直接到达哪些状态(即,那些Z'=0,min(0,X-2)<=X'<=X,min(0,Y-2)<=Y'<=Y,min(0,X+Y-2)<=X'+Y'<X+Y的状态(X',Y',Z'),同理可以算出若当前状态是(X,Y,0),下一步有哪些可行的状态。对每一个可以到达的状态,作两种检查:一是它是否是合法状态(人不少于兽),二是它是否以前检查过(检查过就不在检查了,以免死循环)。
    这实际上就是BFS/DFS的基本思想,也是大多数此类求解问题算法的基本思路。
    你的方法本质上也是生成了这样的一个“状态变迁图”,只不过因为你没有区分船的问题,所以把两种不同的状态看成了一种,同时,没有使用BFS/DFS的思路,所以难以避免出现死循环(比如程序可能会不断地循环搜索(3,3,1)->(2,2,0)->(3,3,1)->(2,2,0)->....这样的路线)。


    我以前只是实现过DFS和BFS,并没有用图的DFS和BFS解决过实际问题。谢谢你的详细讲解:)
    我看了你说的才发觉其实我想的跟你说的也就是一个意思,只是原先我没有意识到我想的跟你说的也就是一个意思。
    真的很高兴能够在这个论坛上认识你们。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/6/3 8:39:00
     
     Logician 帅哥哟,离线,有人找我吗?天蝎座1984-10-28
      
      
      威望:9
      头衔:逻辑爱好者
      等级:研三(收到IBM CRL的Offer了)(版主)
      文章:1219
      积分:10357
      门派:IEEE.ORG.CN
      注册:2005/3/12

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给Logician发送一个短消息 把Logician加入好友 查看Logician的个人资料 搜索Logician在『 算法理论与分析 』的所有贴子 点击这里发送电邮给Logician  访问Logician的主页 引用回复这个贴子 回复这个贴子 查看Logician的博客23
    发贴心情 
    呵呵。:)

    ----------------------------------------------
    Three passions, simple but overwhelmingly strong, 
    have governed my life: the longing for love, the
    search for knowledge, and unbearable pity for the
    suffering of mankind.
                                - Bertrand Russell

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/6/3 12:09:00
     
     doubleman 帅哥哟,离线,有人找我吗?
      
      
      等级:大二(研究C++)
      文章:27
      积分:227
      门派:XML.ORG.CN
      注册:2006/4/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给doubleman发送一个短消息 把doubleman加入好友 查看doubleman的个人资料 搜索doubleman在『 算法理论与分析 』的所有贴子 引用回复这个贴子 回复这个贴子 查看doubleman的博客24
    发贴心情 
    用(L,LH,LB)表示河左岸人的数数目为LH,兽的数目为LB,,用(R,RH,RB)表示河右岸人的数数目为RH,兽的数目为RB。约束条件是:LH>=LB并且RH>=RB。定义下面的一些算符:A1(表示一个人和一只兽从河的左岸到右岸),A2(表示一个人和一只兽从河的右岸到左岸),A3(表示两个人从河的左岸到右岸),A4(表示两只兽从河的左岸到右岸)。这样初始状态为(L,3,3),(R,0,0),目标状态为(L,0,0),(R,3,3)。运用广度优先或者深度优先搜索算法就可以搞定啦。具体实现可以用PROLOG语言来做到。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/6/5 1:05:00
     
     wanghuicn2008 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:1
      积分:59
      门派:XML.ORG.CN
      注册:2006/6/24

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给wanghuicn2008发送一个短消息 把wanghuicn2008加入好友 查看wanghuicn2008的个人资料 搜索wanghuicn2008在『 算法理论与分析 』的所有贴子 引用回复这个贴子 回复这个贴子 查看wanghuicn2008的博客25
    发贴心情 
    我觉得也是图的遍历,考虑船在哪一侧,主要是状态之间的转换,题目没仔细看,主要是若两个都可行,那么就要考虑这两个状态之间转换可能性的问题了,具体来说就是连边的可能性
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/7/1 16:51:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 算法理论与分析 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/6/1 23:21:32

    本主题贴数25,分页: [1] [2] [3]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms