商人过河问题(二)java实现
本文实现的java版商人过河是参考http://wenku.baidu.com/link?url=dpe2AC8mCjpGnclFv6iZy88_vqYm3bED4QDpSkAI4ssgs7BhntuuJTlw6_R1N02efR7CfQB8swuCDpROC3GoAqxcPNMTv7l5d1AHamcwCne实现,有兴趣的可以看原文。
反正我是没跑通。。。自己调了很久。。。。不多说,直接贴代码。运行不通过找我。。。
通用版实现。
package mechants_River;
/**
* m 商人人数
* s 随从 人数
* dual 对象表示商人和随从的组成状态,也就是一次渡河方案。
* add minus 状态变迁的计算
* @author tina
*
*/
public class Dual {
int m, s; public Dual(int m, int s) {
this.m = m;
this.s = s;
} Dual add(Dual e) {
return new Dual(this.m + e.m, this.s + e.s);
} Dual minus(Dual e) {
return new Dual(this.m - e.m, this.s - e.s);
}
public boolean greaterOrEqual(Dual d){
//System.out.println("is Valid"+this.m+" "+this.s+"----"+d.m+" "+d.s);
return (this.m>=d.m&&this.s>=d.s? true:false);
}
}
package mechants_River; import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet; public class Path {
Dual carryingSchema[]; // 小船可提供的载人方案
Dual initStatus; // 初始状态
Dual endStatus; // 终止状态
List<Node> path = new ArrayList<Node>(); // 过河路径
Set<Node> iNode = new TreeSet(); // 孤立结点 public Path(int merchant, int servant, int carrying) {
initStatus = new Dual(merchant, servant);
endStatus = new Dual(0, 0);
buildCarryingSchema(carrying);
findPath();
if (path.isEmpty()) {
System.out.println("Can't solve the problem");
} else {
for (Node e : path) {
System.out.println(e);
}
}
} public static void main(String[] args) {
Path p = new Path(5, 5, 2);
} public boolean isRepeat() {
return path.contains(this);
} /**
* 构建渡河方案 根据小船的最大可载人数且小船不能空 计算可行方案 每个方案表示一个dual 对象 并把保存在carryingSchema中。
* 在Node中,通过数组下标来引用小船的载人方案。 数组既可以正向遍历,也可以反向遍历,所有的载人方案,按总人数进行降序排列
*
* @param carrying
*/
public void buildCarryingSchema(int carrying) {
int size = (2 + carrying + 1) * carrying / 2; // 方案总数
carryingSchema = new Dual[size];
// 小船载人方案;按人数降序排列
for (int i = 0, total = carrying; total > 0; total--) {
for (int m = total; m >= 0; m--) {
carryingSchema[i++] = new Dual(m, total - m);
}
}
} /**
* 使用穷举法,搜索一条即初始状态initStatus至终止状态endStatus的迁移路径 step表示渡河步骤,从0开始,step为偶数,表示前行
* 小船前行时,正向遍历表carrySchema
* 如果无法找到可行的方案,则当前结点为孤立结点,则从path中删除,置入孤立结点集合中,同时step回退一步
* ,继续搜索可行的渡河方案。当step<0时,则表示无法找到可行的渡河方案,path将为空。
*/
public void findPath() {
Dual curStatus = initStatus;
int step = 0;
Node node = null, rnode = null;
while (step >= 0) {
int direction = (step % 2 == 0 ? Node.FORWARD : Node.BACKWAED);
int idx;
if (direction == Node.FORWARD) {
idx = 0;
// mode不空,表示发送路径回退。需要跳过该结点已尝试的方案
if (rnode != null) {
idx = rnode.idx + 1;
rnode = null;
}
} else {
// 方向为backword
idx = carryingSchema.length - 1;
// mode不空,表示发送路径回退.需要跳过结点
if (rnode != null) {
idx = rnode.idx - 1;
rnode = null;
}
}
boolean found = false;
while (!found && idx >= 0 && idx < carryingSchema.length) { node = new Node(curStatus, direction, idx);
if (node.isValid() && // 渡河方案是否有效
node.isSecure() && // 状态是否安全
!node.isRepeat() && // 结点不能重复
!node.isIsolated()) // 非孤立结点
{
found = true;
} else {
if (direction == Node.FORWARD)
idx++; // 顺序搜索
else
idx--; // 逆序搜索
}
} if (!found) { // 未找到可行的渡河方案
step--; // 回退一步, 并删除当前结点
if (step >= 0) {
curStatus = path.get(step).status;
rnode = path.remove(step);
iNode.add(rnode); // 孤立结点 }
continue;
} path.add(node); // 把当前结点加入路径中
if (node.isEnd())
break; // 是否到达终止状态
curStatus = node.nextStatus(); // 当前状态变迁 step++;
System.out
.println(step + " " + node.status.m + " " + node.status.s);
}
}
/**
* status 节点方向
* direction 渡河方向
* idx 索引,指向小船的载人方案 carryingSchema[]
* @author tina
* Node 表示整个渡河方案的每个步骤,每个结点由结点状态(商人和随从的人数)、渡河方向和渡河方案组成
*/
public class Node implements Comparable<Node> {
Dual status;
int direction;
int idx;
public static final int FORWARD = 0; // 前进
public static final int BACKWAED = 1; // 返回 public Node(Dual status, int direction, int idx) {
this.status = status;
this.direction = direction;
this.idx = idx;
} @Override
public int compareTo(Node e) {
return this.toString().compareTo(e.toString());
}
@Override
public String toString() {
return "("+this.status.m+","+this.status.s+")" + (direction == FORWARD ? " ---> " : " <--- ")+"("+carryingSchema[this.idx].m+","+carryingSchema[this.idx].s+")";
} public boolean isIsolated() {
// int direction = this.nextDirection();
Dual status = this.nextStatus();
for (Node e : iNode) {
if (direction == e.direction && status.equals(e.status)) {
return true;
}
}
return false;
} Dual nextStatus() {
return direction == FORWARD ? this.status
.minus(carryingSchema[idx]) : this.status
.add(carryingSchema[idx]);
} public boolean equals(Object e) {
if (this == e)
return true;
if (!(e instanceof Node))
return false;
Node o = (Node) e;
return this.status.equals(o.status)
&& this.direction == o.direction && this.idx == o.idx;
} /**
* 当向前渡河时,要求本岸商人和随从人数分别大于等于渡河方案指定的商人和随从人数;
* 当小船返回时,要求对岸商人和随从人数分别大于等于渡河方案指定的商人和随从人数
*
* @return
*/
public boolean isValid() {
return this.direction == FORWARD ? status
.greaterOrEqual(carryingSchema[idx]) : initStatus.minus(
status).greaterOrEqual(carryingSchema[idx]);
}
/**
* 判断结点的状态是否有效,这是实际问题的一具体约束,即要求结点状态中商人人数或者为0,或者不小于随从人数。
* @return
*/
public boolean isSecure() { Dual next = this.nextStatus(); return (next.m == 0 || next.m >= next.s)
&& (initStatus.m - next.m == 0 || initStatus.m - next.m >= initStatus.s
- next.s);
} public boolean isRepeat() {
return iscontains(path);
} public boolean iscontains(List<Node> p) {
for (int i = 0; i < p.size(); i++) {
Node o = p.get(i);
if (this.status.m == o.status.m
&& (this.status.s == o.status.s)
&& this.direction == o.direction && this.idx == o.idx) {
System.out.println("equal");
return true;
}
}
if(p.size()>=1&&this.idx==p.get(p.size()-1).idx){
return true;
}
return false;
} public boolean isEnd() {
Dual next = this.nextStatus();
return next.m==endStatus.m&&next.s==endStatus.s;
}
} }
商人过河问题(二)java实现的更多相关文章
- 实验二 Java面向对象程序设计
		
实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...
 - 20145213《Java程序设计》实验二Java面向对象程序设计实验报告
		
20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...
 - 20145206《Java程序设计》实验二Java面向对象程序设计实验报告
		
20145206<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...
 - 20145308刘昊阳 《Java程序设计》实验二 Java面向对象程序设计 实验报告
		
20145308刘昊阳 <Java程序设计>实验二 Java面向对象程序设计 实验报告 实验名称 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面相对象三要素:封 ...
 - 20145113 实验二 Java面向对象程序设计
		
20145113 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 1.初 ...
 - JAVA课程实验报告 实验二 Java面向对象程序设计
		
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩: 指导教师:娄嘉 ...
 - 20145225唐振远 实验二 "Java面向对象程序设计"
		
20145225<Java程序设计> 实验二 Java面向对象程序设计 实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S ...
 - 20145208 实验二 Java面向对象程序设计
		
20145208 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...
 - 20162311 实验二  Java面向对象程序设计  实验报告
		
实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...
 
随机推荐
- cf471B MUH and Important Things
			
B. MUH and Important Things time limit per test 1 second memory limit per test 256 megabytes input s ...
 - MassMutual Interview Questions
			
Company MassMutual Date 30/09/15 Location Boston, MA Position Application Developer It's not a codin ...
 - LD1-M(简单图的判定+构造,Havel定理)
			
题目链接 /* *题目大意: *给出一个图的每个点的度的序列,求能否构成一个简单图,如果能构出简单图,则输出图的邻接矩阵; * *算法思想: *Havel定理的应用; *给定一个非负整数序列{dn}, ...
 - 6个理由告诉你为什么要用NAS
			
当电脑硬盘容量满了,多数使用者第一个想法就是买一块几TB的硬盘来扩充,如果是笔电的使用者,第一个想到的是买一个外接式硬盘来备份资料,这样的想法并没有错,那是当你还不知道有「NAS」这个好用的东西,才会 ...
 - EF 事务处理 (InnoDB Engine的MySQL表也可以)
			
备忘 1. 亲测(可以嵌套使用) using (TransactionScope scope = new TransactionScope()) { //操作1 XXEntities.Current. ...
 - 《JavaScript 闯关记》之数组
			
数组是值的有序集合.每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引. JavaScript 数组是无类型的,数组元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类型 ...
 - bootstrap使用中遇到的问题(二)
			
1.ie8不支持carousel组件, 解决方法:将jquery换为jquery1版本,具体原因不清楚~~~~~ 2.ie8不支持background-color:rgba(); 解决方法:这样写代码 ...
 - LAMP介绍及安装
			
LAMP介绍及安装 1. LAMP是什么? LAMP,包含Linux + Apache + PHP + Mysql. LAMP适用环境 适用于追求极致稳定的WEB环境,缺点是需要消耗更多资源. 除了L ...
 - Java内存模型(转载)
			
1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题 ...
 - struts1:(Struts重构)构建一个简单的基于MVC模式的JavaWeb
			
在构建一个简单的基于MVC模式的JavaWeb 中,我们使用了JSP+Servlet+JavaBean构建了一个基于MVC模式的简单登录系统,但在其小结中已经指出,这种模式下的Controller 和 ...