警察囚徒过河问题

来源:互联网 发布:云计算地理区域 编辑:程序博客网 时间:2024/04/28 16:45

过河的方式:

package river;public enum ActionCode {// 一个警察过去one_plice_go("one_plice_back"),// 一个囚徒过去one_prisoner_go("one_prisoner_back"),// 两个警察过去two_plice_go("two_plice_back"),// 两个囚徒过去two_prisoner_go("two_prisoner_back"),// 一个警察一个囚徒过去police_prisoner_go("police_prisoner_back"),// 一个警察回来one_plice_back("one_plice_go"),// 一个囚徒回来one_prisoner_back("one_prisoner_go"),// 两个警察回来two_plice_back("two_plice_go"),// 两个囚徒回来two_prisoner_back("two_prisoner_go"),// 一个警察一个囚徒回来police_prisoner_back("police_prisoner_go"),//未知状态unknown_state("unknown_state");private String ac;private ActionCode(String s){ac=s;}//是否是互斥的public boolean isRepel(ActionCode _ac){if(ActionCode.valueOf(ac).equals(_ac)){return true;}else{return false;}}@Overridepublic String toString() {switch (this) {case one_plice_go:return "一个警察过去";case one_prisoner_go:return "一个囚徒过去";case two_plice_go:return "两个警察过去";case two_prisoner_go:return "两个囚徒过去";case police_prisoner_go:return "一个警察一个囚徒过去";case one_plice_back:return "一个警察回来";case one_prisoner_back:return "一个囚徒回来";case two_plice_back:return "两个警察回来";case two_prisoner_back:return "两个囚徒回来";case police_prisoner_back:return "一个警察一个囚徒回来";default:break;}return null;};}
过河的状态:

package river;public class ActionState implements Cloneable{private int police_count;private int persioner_count;private boolean isHaveship;public ActionState(int police_count, int persioner_count, boolean isHaveship) {this.police_count = police_count;this.persioner_count = persioner_count;this.isHaveship = isHaveship;}public int getPolice_count() {return police_count;}public void police_count_down(int down){police_count-=down;}public void police_count_up(int up){police_count+=up;}public void persioner_count_down(int down){persioner_count-=down;}public void persioner_count_up(int up){persioner_count+=up;}public void setPolice_count(int policeCount) {police_count = policeCount;}public int getPersioner_count() {return persioner_count;}public void setPersioner_count(int persionerCount) {persioner_count = persionerCount;}public boolean isHaveship() {return isHaveship;}public void setHaveship(boolean isHaveship) {this.isHaveship = isHaveship;}public ActionCode[] getActionCodeByState() {if (isHaveship) {isHaveship=false;return new ActionCode[] { ActionCode.police_prisoner_go,ActionCode.one_plice_go,ActionCode.one_prisoner_go, ActionCode.two_plice_go,ActionCode.two_prisoner_go};} else {isHaveship=true;return new ActionCode[] { ActionCode.one_plice_back,ActionCode.one_prisoner_back, ActionCode.two_plice_back,ActionCode.two_prisoner_back,ActionCode.police_prisoner_back };}}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + (isHaveship ? 1231 : 1237);result = prime * result + persioner_count;result = prime * result + police_count;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;ActionState other = (ActionState) obj;//if (isHaveship != other.isHaveship)//return false;if (persioner_count != other.persioner_count)return false;if (police_count != other.police_count)return false;return true;}public void updateByActionCode(ActionCode ac) {switch (ac) {case one_plice_go:break;case one_prisoner_go:break;case two_plice_go:break;case two_prisoner_go:break;case police_prisoner_go:break;case one_plice_back:break;case one_prisoner_back:break;case two_plice_back:break;case two_prisoner_back:break;case police_prisoner_back:break;}}@Overridepublic String toString() {return "ActionState [persioner_count=" + persioner_count+ ", police_count=" + police_count + "]";}@Overridepublic Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubActionState _as=(ActionState) super.clone();return new ActionState(_as.getPolice_count(),_as.getPersioner_count(),_as.isHaveship());}}

主方法:

package river;import java.util.Stack;public class TestJ {public static int police_total = 6;public static int persioner_total = 6;//此岸static ActionState res_as1=new ActionState(0,0,true);//彼岸static ActionState res_as2=new ActionState(3,3,false);/** * 三个警察和三个囚徒共同旅行。一条河挡住了去路,河边有一条船,但是每次只能载2人。 * 存在如下的危险:无论在河的哪边,当囚徒人数多于警察的人数时,将有警察被囚徒杀死。  * 问题:请问如何确定渡河方案,才能保证6人安全无损的过河。 * 回答:警察囚徒过去,警察回来 囚徒囚徒过去,囚徒回来 警察警察过去, *  警察囚徒回来 警察警察过去,囚徒回来 囚徒囚徒过去,囚徒回来 囚徒囚徒过去 *  * @param args */public static void main(String[] args) {MinThroughMethod();}/** *  * @param from as1 * @param to as2 */public static Stack<ActionCode> throughtRiverMethod(Stack<ActionCode> acs,ActionState as1,ActionState as2,ActionCode a,int current_deep,int Max_deep){ActionCode[] _acs=as1.getActionCodeByState();for(ActionCode _a:_acs){if(!a.isRepel(_a)&&isCross(_a,as1.getPolice_count(),as1.getPersioner_count(),as2.getPolice_count(),as2.getPersioner_count())){ActionState _as1=null;ActionState _as2=null;try {_as1=(ActionState)as1.clone();_as2=(ActionState)as2.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}CrossMethod(_as1,_as2,_a);acs.push(_a);if(_as1.equals(res_as1)){System.out.println(acs);System.out.println("最短检索深度:"+Max_deep);System.exit(0);return acs;}else if(current_deep<Max_deep){throughtRiverMethod(acs,_as1,_as2,_a,++current_deep,Max_deep);}acs.pop();}}return null;}public static int MinThroughMethod(){//初始此岸 ActionState src_as1=new ActionState(3,3,true);//初始彼岸 ActionState src_as2=new ActionState(0,0,false);int current_deep=0; int max_deep=0;Stack<ActionCode> acs=new Stack<ActionCode>();while(throughtRiverMethod(acs,src_as1,src_as2,ActionCode.unknown_state,current_deep,max_deep)==null){max_deep++;}return max_deep;}/** * 以出发地点为初始点 是否满足过河的条件 */public static boolean isCross(ActionCode cr, int police_count,int persioner_count,int police_other,int persioner_other) {switch (cr) {case one_plice_go:if (police_count > 0) {if(((police_count-1)>=persioner_count||(police_count-1)==0)&&(police_other+1)>=persioner_other){return true;}}return false;case one_prisoner_go:if (persioner_count > 0) {if((police_count>=(persioner_count-1)||police_count==0)&&(police_other>=(persioner_other+1)||police_other==0)){return true;}}return false;case two_plice_go:if (police_count > 1) {if(((police_count-2)>=persioner_count||(police_count-2)==0)&&(police_other+2)>=persioner_other){return true;}}return false;case two_prisoner_go:if (persioner_count > 1) {if((police_count>=(persioner_count-2)||police_count==0)&&(police_other>=(persioner_other+2)||police_other==0)){return true;}}return false;case police_prisoner_go:if (police_count > 0 && persioner_count > 0) {if(((police_count-1)>=(persioner_count-1)||(police_count-1)==0)&&((police_other+1)>=(persioner_other+1))){return true;}}return false;case one_plice_back:if (police_count < police_total) {if((police_count+1)>=persioner_count&&((police_other-1)>=persioner_other||police_other-1==0)){return true;}}return false;case one_prisoner_back:if (persioner_count < persioner_total) {if((police_count>=(persioner_count+1)||police_count==0)&&(police_other>=(persioner_other-1)||police_other==0)){return true;}}return false;case two_plice_back:if (police_count < police_total - 1) {if((police_count+2)>=persioner_count&&((police_other-2)>=persioner_other||police_other-2==0)){return true;}}return false;case two_prisoner_back:if (persioner_count < persioner_total - 1) {if((police_count>=(persioner_count+2)||police_count==0)&&(police_other>=(persioner_other-2)||police_other==0)){return true;}}return false;case police_prisoner_back:if (persioner_count < persioner_total&& police_count < police_total - 1) {if(((police_count+1)>=(persioner_count+1))&&((police_other-1)>=(persioner_other-1)||police_other-1==0)){return true;}}return false;}return true;}public static void CrossMethod(ActionState as1,ActionState as2,ActionCode cr) {switch (cr) {case one_plice_go://as1.police_count_down(1);//as2.police_count_up(1);as1.setPolice_count(as1.getPolice_count()-1);as2.setPolice_count(as2.getPolice_count()+1);break;case one_prisoner_go://as1.persioner_count_down(1);//as2.persioner_count_up(1);as1.setPersioner_count(as1.getPersioner_count()-1);as2.setPersioner_count(as2.getPersioner_count()+1);break;case two_plice_go://as1.police_count_down(2);//as2.police_count_up(2);as1.setPolice_count(as1.getPolice_count()-2);as2.setPolice_count(as2.getPolice_count()+2);break;case two_prisoner_go://as1.persioner_count_down(2);//as2.persioner_count_up(2);as1.setPersioner_count(as1.getPersioner_count()-2);as2.setPersioner_count(as2.getPersioner_count()+2);break;case police_prisoner_go://as1.police_count_down(1);//as2.police_count_up(1);//as1.persioner_count_down(1);//as2.persioner_count_up(1);as1.setPolice_count(as1.getPolice_count()-1);as2.setPolice_count(as2.getPolice_count()+1);as1.setPersioner_count(as1.getPersioner_count()-1);as2.setPersioner_count(as2.getPersioner_count()+1);break;case one_plice_back://as1.police_count_up(1);//as2.police_count_down(1);as1.setPolice_count(as1.getPolice_count()+1);as2.setPolice_count(as2.getPolice_count()-1);break;case one_prisoner_back://as1.persioner_count_up(1);//as2.persioner_count_down(1);as1.setPersioner_count(as1.getPersioner_count()+1);as2.setPersioner_count(as2.getPersioner_count()-1);break;case two_plice_back://as1.police_count_up(2);//as2.police_count_down(2);as1.setPolice_count(as1.getPolice_count()+2);as2.setPolice_count(as2.getPolice_count()-2);break;case two_prisoner_back://as1.persioner_count_up(2);//as2.persioner_count_down(2);as1.setPolice_count(as1.getPolice_count()+2);as2.setPolice_count(as2.getPolice_count()-2);break;case police_prisoner_back://as1.police_count_up(1);//as2.police_count_down(1);//as1.persioner_count_up(1);//as2.persioner_count_down(1);as1.setPolice_count(as1.getPolice_count()+1);as2.setPolice_count(as2.getPolice_count()-1);as1.setPersioner_count(as1.getPersioner_count()+1);as2.setPersioner_count(as2.getPersioner_count()-1);break;default:break;}}}

运行结果:
[一个警察一个囚徒过去, 一个警察回来, 两个囚徒过去, 一个囚徒回来, 两个警察过去, 一个警察一个囚徒回来, 两个警察过去, 一个囚徒回来, 两个囚徒过去, 一个警察回来, 一个警察一个囚徒过去]
最短检索深度:12