数学建模社区-数学中国

标题: 渡河问题 [打印本页]

作者: sally    时间: 2004-6-5 11:57
标题: 渡河问题

渡河问题

8 t6 g/ W1 a0 W

A wolf, a goat and a cabbage are on one bank of a river. A ferryman wants to take them across, but since his boat is small, he can take only one of them at a time. For obvious reasons, neither the wolf and the goat nor the goat and the cabbage can be left unguarded. How is the ferryman going to get them across the river?

0 h* Y$ v' P8 ^8 h& _

' s0 J% L* S& _+ r) y

程序代码:

/ [; h- a' B( K9 L4 y) X

//以下程序在Win98+vc6.0运行通过

0 I6 d! W0 d- m3 |& f

#include <stdio.h> 7 M/ f0 k* M; `( a0 u* f( M2 @#include <stdlib.h> 5 h" s# y( L- F" h- r) C#define MAX 50 K% k" R% ^6 _3 F: ]: o struct state+ f& e2 ^( l* K7 [( U/ R3 b; r: K {: I, D- j p' a& B. N! t; A$ Z/ l int man,sheep,wolf,cabbage;//0:在起始岸;1:在目的岸 O% [: j/ }9 A# Z int m;//所采取的过河方法,(1--4)8 U: U. P9 o; `% |7 ]5 _ }s[MAX];# x+ |! N1 p; l int count=0; : @% b# Z$ U: P+ c3 S9 T% oFILE *fp=fopen("c:\\2.txt","w+");

6 H. d! ~$ Z! J5 N7 V5 {4 G2 Q

void main() # ^8 J$ | x; l{ * L* g7 p4 C K void f1(int ),f2();//f1试探递归7 f& K* D: t& E* l C7 p s[0].man=s[0].sheep=s[0].wolf=s[0].cabbage=0; ) x0 Y0 X2 S0 V s[0].m=4; \4 Q2 v. D, _6 x" _4 M s[1].man=s[1].sheep=s[1].wolf=s[1].cabbage=0;4 e/ ^2 N( Z8 e: I4 g( q f1(1); # M+ R- [1 `) b% p5 B- H //f2();7 B5 O- ^6 C; M: t' _1 m2 W fclose(fp);/ z$ ~: J. u! P. Q9 C) l2 E4 ~ printf("\n");

2 L0 m% m4 d- }8 ]; @+ z% ~' D. x

}: Q/ E( O1 ^2 Q1 E2 l! m$ f //用m值决定的方法渡河,成功返回1,否则返回0, ?$ \! q- i/ Y2 {. X- x int move(int top,int m) ; a2 i- M7 {- y9 v2 t# P{ % w$ d1 Z9 f' B* T' d switch(m)9 ~1 ? w. Y. D4 j7 V4 N+ W { ) c2 _4 r# _# z; I //人带羊过河! z: k6 D" y! ?2 t case 1: 8 B( ^: g ]. H8 [3 a9 P+ Z. x //判断人羊是否在同岸 n T4 p1 R# b if(s[top].man!=s[top].sheep) 6 h/ | h8 t" t, u, `( V return 0;5 b4 b& \0 a6 A6 } s[top].sheep=s[top].man=(s[top].man==1)?0:1; " \, P- e, w G9 u s[top].m=m;//存储过河方法 ( B( y" G' l. I5 w4 u7 | break; , y0 I4 ]" h$ b% I case 2:( n( G' ` t( |( E& p# J if(s[top].man!=s[top].wolf) 2 \8 Z9 R, j/ p return 0;9 X/ o& u4 {% H- p" C5 ?+ A s[top].wolf=s[top].man=(s[top].man==1)?0:1; - g3 A4 A+ c- S2 a s[top].m=m;//存储过河方法 3 k( P, g) @( A3 ~# R1 j break; 8 ^% A( e# y4 w8 }- \1 H case 3:2 }, q" W* ]4 w. J( J; m if(s[top].man!=s[top].cabbage)$ Y9 |( w* j# ^! B. Q: J2 l return 0;. i4 q+ M2 ^/ i s[top].cabbage=s[top].man=(s[top].man==1)?0:1; 7 G* S+ i# R; C7 Z8 W7 M s[top].m=m;//存储过河方法 ' K# l6 f% z3 |% V& Y6 E0 W break;/ j" V3 W, V" E" A //人单独过河 ; t( M8 k4 P) B case 4: N' [( V& e1 I! _ s[top].man=(s[top].man==1)?0:1; ! n( a3 I' A2 F! c- g# E s[top].m=m;//存储过河方法 2 Z) q- H& b" i5 Q break; " l- f; o$ S/ q6 x; o" A }//switch( H7 m& b$ y- W: t: [ return 1;# I+ x2 B! ?8 H4 m. l! s }//move ( Q: k& Y5 B8 [//打印过河步骤 1 j/ n. p& F4 U# Y5 bvoid display(int top). U$ {3 g8 v7 \# `' ~9 I { 5 P C( t* F) o- \: W2 {/ Y int i=0;' V+ @2 E0 O' f$ S fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage); 4 v/ G0 p, z0 o- g) I/ M for(i=1;i<=top;i++)6 ?! B: D' [* d; F { / f( l+ i+ m3 O1 o, o switch(s.m) 2 r1 M# w6 V! o7 L { , E1 ?6 A5 L$ h. i3 s7 P! e! E( m case 1: : x" k* d8 G+ ^1 C! m2 D if(s.man==1&&s[i-1].man==0)7 B; X' v) N/ P fprintf(fp,"人带羊从起始岸过河到目的岸\n"); 7 N8 l! P0 g7 J! q else 1 g- ^/ k9 N( {# q fprintf(fp,"人带羊从目的岸过河到起始岸\n"); 0 T- ~5 O0 c: W. _7 z2 W. _ break; ! c* U- O3 }- a [ l& E6 M7 \ case 2: 3 I. [( g5 D) T9 X# d! q if(s.man==1&&s[i-1].man==0)/ ~, c. W e& a$ o fprintf(fp,"人带狼从起始岸过河到目的岸\n"); 9 T- o9 E) N2 ~1 E* P ? else 2 V% _6 ~$ j% g& G' a fprintf(fp,"人带狼从目的岸过河到起始岸\n"); " Q' a) P1 h! S0 T/ ^$ }3 T f break; " r8 O. T3 N$ V/ g9 {# {" \ case 3: ' ]+ R& w% K7 A% s) ?' @! F if(s.man==1&&s[i-1].man==0) I2 e* e& p1 X* J- J9 I# ?0 F fprintf(fp,"人带菜从起始岸过河到目的岸\n"); & R1 S" @7 Y1 z% @: x4 N* { else& L: z) }( U% i; M fprintf(fp,"人带菜从目的岸过河到起始岸\n");3 h* h. I! _/ r$ `$ l break; 6 W/ h$ O$ {/ y0 _+ C case 4: # @2 v7 E# H# r0 A( H8 r, s if(s.man==1&&s[i-1].man==0)! f: R( g# s) ^6 G6 d' b fprintf(fp,"人单独从起始岸过河到目的岸\n");3 V" ?3 E7 P! c: _ else . @+ y" y) Q3 i" N fprintf(fp,"人单独从目的岸过河到起始岸\n");9 O$ d* H/ ], v; t7 X6 H break;. w6 q$ m" k$ k6 t5 d# D/ y }//switch& L: I6 E D, d) n; j fprintf(fp,"state%d: man: %d, sheep: %d,wolf: %d,cabbage: %d\n",i,s.man,s.sheep,s.wolf,s.cabbage); % e5 D6 e6 e4 S ; {/ F& Y2 F* e' K. y9 u! N }//for/ F: X# V; a; w' b: r; L6 X! K fprintf(fp,"All ferried successfully!\n"); & W, d7 b/ N* f5 d% B$ G}//display

6 H% h* N0 k' v% R0 c. F* J

//检查两岸合法性已经有无状态与历史重复性 ( \+ j0 _0 r6 N; y9 [( M9 k% Pint check(int top) / @3 g( z3 u, R( P/ N6 [! [; k{ : U4 H4 d" N% V& l% a8 I% l! X int i; ' F+ K4 j* K3 L; o. m//检查两岸合法性" L& o+ ~9 P- t, }0 W2 P; G if((s[top].sheep!=s[top].man&&s[top].cabbage!=s[top].man)||2 N) S4 ]/ `; F! X6 ]# q9 V (s[top].wolf!=s[top].man&&s[top].sheep!=s[top].man))# x4 |* a/ z' T9 F- H- K9 S" ]7 q2 @ return 0; 3 ]# i; X% R/ O/ g6 h //检查历史重复性 7 \0 W8 I: B6 b! ~" a( ~% M for(i=0;i<top;i++). M7 w4 b; g- K! E/ k if(s.man==s[top].man&&s.sheep==s[top].sheep&&s.cabbage==s[top].cabbage&&s.wolf==s[top].wolf) 2 R' x; ?4 t7 d* @' |/ R. \/ ~ return 0; - [. j1 a$ P2 U+ Z //ok 3 I$ {3 X$ R& S& ?$ ~0 F Q return 1;7 b9 F' _7 h$ U+ i- t }& y( R) \; z+ Y* h* }4 K! o" a: n void f1(int top)0 Z d* n: C0 G9 {) P" Q {+ _8 G3 N2 {% {9 e9 [* o$ R int m;, \( n; q+ d0 l9 c6 \% c8 N if(top>0)//0状态(初试状态应该是预先设置好的,所以要做状态1,故,初试top进来应该是1( F4 k4 ~) y* E" |5 U% m { //对每次状态分别试探4中方案 7 h6 P5 h* N5 c1 m4 |* ~4 C ` for(m=1;m<5;m++)/ c3 S& z' z0 e { " R8 v- Z3 b+ i& {& U/ T //每次方案的实施是在上次结果状态上做的( Q' o/ ?, F1 ^- S+ r4 ]! ? s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;+ G! J, C, J& |4 F+ j" K) B s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; + d0 \' Z7 Z% s8 O; h& F# l //用方案m移动,同时检查结果 + K1 @ b( @6 @ if(move(top,m)&&check(top)) # ~. F$ ^6 F% O {7 L, t" _' d9 i( W. ^ if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf )4 Z8 G+ ?! a+ r1 [* _7 y* Z- w {) @( t' e9 w7 X3 i) @ //打印渡河步骤/ W a G& @ ?& D' b! A, R4 ] display(top); 9 X% o0 f' K' I x$ @* Y //统计方案个数9 n G& t U, M: E count++; ! X2 Z P, [# b5 Z* _1 V fprintf(fp,"count=%d----------------------------\n\n",count);8 n$ f# \4 v) u) `8 ^, [# x if(count>1000) exit(1); ! V; q; }2 \7 x; q }* F8 X1 K4 k2 ~2 E else 1 L) E8 H( L' `/ ^4 B f1(top+1); 5 @5 Z+ F8 i" k& `8 d4 n' n! p }; u% R' w/ ^. G: u) E* d6 A }//for ' C o! y. }; a, O }//if(top>=0) ) c1 ]5 X9 g, G- I}//f1

9 u1 T1 ~8 z0 C! P+ p3 g( |

) F% W$ q0 I- Y `

/ ?6 u4 F5 F+ \: d& c. K

% z- w0 y. z3 i void f2()2 n! w6 z9 @4 [- g n { 6 N* i; l( k& ] int top=0,i; ) Y d0 H4 ^/ I% ? //开始时都在起始岸/ Q4 B* n4 d' B( L, V s[top].man=s[top].sheep=s[top].wolf=s[top].cabbage=0;" \1 ^0 y1 D5 x, V' P' y //未开始渡河 " ^3 R! D5 @/ x# y1 j0 Y& E E s[top].m=4;- v+ k; I& h; X$ K: l; j! y6 T while(top>=0) & G6 ~1 W) N! j2 _" d { ) `' q) o6 U% ^ O! a$ } if(check(top)) : y8 v' [( H+ h8 L { : a }4 C$ F! l4 K% o9 y if(s[top].man&&s[top].sheep&&s[top].cabbage&&s[top].wolf ) " V, N. `: K" x. p; \- E; d0 K {4 j$ ?* A' W3 z) e //打印渡河步骤 1 {/ T" ^- X, n9 ^$ Y T display(top); 1 F% R% D! L+ t //统计方案个数 - T& K3 t+ L7 M x% I. d3 \& b( S count++; 4 u" m- s3 X% A: N fprintf(fp,"count=%d----------------------------\n\n",count);! f* U$ H x r) p- {3 m" Y if(count>1000) exit(1); 0 `, u- W! I/ y //回溯% h o; x; W# S0 p z while(top>=0&&s[top].m>=4) + k. P0 {/ ~$ V9 W2 d2 u6 F3 t, ?' @ top--; : f' |5 `( C. } R7 z; O$ ` if(top>=0) 2 U. k$ M/ y; `9 ~# K5 e { - @6 ~, y' z9 V3 m5 v //在上次状态基础上准备做move* O2 v0 Q* R- g' \ s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep;4 Q. \, f; o4 S) }5 ?5 N- C s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; 0 D1 @3 \" @9 o8 L' { h, C8 a* P i=1;/ A$ j9 s ^6 A# W0 I9 [$ C while(s[top].m+i<5&&!move(top,s[top].m+i)) 2 B- Z' s( ^: e- x i++; K0 `( G- g& n( c9 Y* L }

" s' a! N% x5 ]# n

} ; d" _: X" C9 x9 w# Q/ d else7 K' W* m1 [- [( a {6 z0 q7 N7 R6 n. d8 g2 |6 Z6 X top++; + P2 y l- Z$ }5 |3 g6 v //在上次状态基础上准备做move2 y; e/ i% U7 O' A; N8 p2 `% d' f s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep; # p! S9 }; l" l- \! _: g s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; ^! u# @& l& y7 h, n" b1 Y i=1;) l% F. o, }8 w: i while(i<5&&!move(top,i)) * l5 z& E% ~% j' ?# N$ |4 P i++;' J4 Y+ N6 m$ j4 m2 h }

& L& V* v, O4 m' g; [% z

} " t/ a3 E7 ]. u1 T! g# x% E& x else 5 a$ _0 v; g. m- R& T {2 U- u8 s/ _3 p J* Z' ` //回溯' p- l# s9 w" q* q( T( B/ P while(top>=0&&s[top].m>=4) ' S! D& d4 Y+ O. q top--; 2 u* z; Z8 e& f/ ]" K( a if(top>=0), }1 E4 V8 T8 ^9 T! g6 I$ o { 1 ?0 Y7 l! j( c u2 F/ O% M9 V //在上次状态基础上准备做move 4 t- K* {6 B: b- ^# Y1 y s[top].man=s[top-1].man;s[top].sheep=s[top-1].sheep; 7 `5 }- X O, e0 T' o# I s[top].cabbage=s[top-1].cabbage;s[top].wolf=s[top-1].wolf; ' G* q3 q4 L( P! g6 \' a i=1; 4 ^3 ~* t1 u. H while(!move(top,s[top].m+i)) d! j0 M, a; q# t j i++;. M1 A3 _0 u: {) z4 C9 x }3 C4 R* a9 l. J& T: m }/ D6 P. |5 f+ }" t* O& ?0 y: w }//while4 a' R7 C3 k4 t! a& b& c. ? }//f2 6 b5 D5 p( y! k8 m \! s//--------------------------------- # E, t; p9 ?, U- E& d* x5 |


作者: sally    时间: 2004-6-5 12:07
也可以转化为图的遍历问题
作者: huashi3483    时间: 2004-6-6 18:58
呵呵,好搭档
作者: lynn324    时间: 2004-12-4 16:19
是用c编的吗?
作者: mnpfc    时间: 2009-8-15 06:56
呵呵,看过了




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5