深度优先搜索例题------Java倒油
2016-05-24 13:28
489 查看
深度搜索倒油:
样题描述:有a、b、c三个油桶;a桶的容量为12斤,现有12斤油;b桶容量为8斤,现有0斤;c桶容量5斤,现有0斤。现一次只能由一个桶向另一个同倒油,问怎样才能倒出6斤油。
[java] view
plain copy
package cn.hncu.search.oil.dfs;
import cn.hncu.search.oil.common.Bucket;
import cn.hncu.search.oil.common.DumpCase;
import cn.hncu.search.oil.common.Myset;
public class DumpOilDFS {
public static void main(String[] args) {
Bucket buckets[] = new Bucket[3];
buckets[0] = new Bucket(12, 12);
buckets[1] = new Bucket(8, 0);
buckets[2] = new Bucket(5, 0);
DumpCase u = new DumpCase(buckets);
Myset caseSet = new Myset();
caseSet.add(u);
dfs(u,caseSet);
}
public static void print(DumpCase u,Myset caseSet){
Myset set = new Myset();
set.add(u);
DumpCase d = u.getParent();
while(d!=null){
set.add(d);
d = d.getParent();
}
System.out.println("------------");
Object objs[] = set.getAll();
for(int i=objs.length-1; i>=0; i--){
DumpCase v = (DumpCase) objs[i];
System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);
}
}
public static void dfs(DumpCase u0, Myset caseSet){
//递归鸿沟
for(Bucket bucket: u0.getBuckets()){
if(bucket.now==6){
//System.out.println("find a case");
print(u0,caseSet);
return;
}
}
int n = u0.getBuckets().length;//桶的个数
DumpCase u = new DumpCase(u0);
//用备份节点去搜
//遍历所有的DumpCase: 依次让桶i向j倒
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
//自己不能给自己倒
if(i==j){
continue;
}
//算出桶i给j倒时,能倒多少-->canDump
int canDump = u.getBuckets()[i].canOut();
if(u.getBuckets()[i].canOut()>u.getBuckets()[j].canIn()){
canDump = u.getBuckets()[j].canIn();
}
//倒油
u.getBuckets()[i].out(canDump);
u.getBuckets()[j].in(canDump);
//System.out.println(u.getBuckets()[0].now+","+u.getBuckets()[1].now+","+u.getBuckets()[2].now);
//判断该情况是否已经出现过了//如果存在,要还原(把油倒回去)
if(caseSet.contains(u)){
//把油还回去
u.getBuckets()[i].in(canDump);
u.getBuckets()[j].out(canDump);
continue;
}
//经过上面的哨兵,说明这样倒可以
DumpCase v = new DumpCase(u);
v.setParent(u0);
caseSet.add(v);
//System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);
dfs(v,caseSet);
//再倒回去,以重新进行下一个邻居的遍历
u.getBuckets()[i].in(canDump);
u.getBuckets()[j].out(canDump);
}
}
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
public class Bucket {
public int max;
public int now;
public Bucket(int max, int now) {
this.max = max;
this.now = now;
}
public void in(int a){
now += a;
}
public void out(int a){
now -=a;
}
public int canIn(){
return max-now;
}
public int canOut(){
return now;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + max;
result = prime * result + now;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bucket other = (Bucket) obj;
if (max != other.max)
return false;
if (now != other.now)
return false;
return true;
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
import java.util.Arrays;
public class DumpCase {
Bucket buckets[];
DumpCase parent = null;
public DumpCase() {
}
public DumpCase(Bucket buckets[]) {
this.buckets = buckets;
}
//必须要进行深拷贝
public DumpCase(DumpCase u) {
this.buckets = new Bucket[ u.getBuckets().length ];
for(int i=0; i<u.getBuckets().length;i++){
buckets[i] = new Bucket(0,0);
buckets[i].max = u.getBuckets()[i].max;
buckets[i].now = u.getBuckets()[i].now;
}
}
public Bucket[] getBuckets() {
return buckets;
}
public DumpCase getParent() {
return parent;
}
public void setParent(DumpCase parent) {
this.parent = parent;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(buckets);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DumpCase other = (DumpCase) obj;
if (!Arrays.equals(buckets, other.buckets))
return false;
return true;
}
//※1 用“特征串”来代表整个对象,如果特征串相等,则表示是相等的对象。这样在比较对象时,性能就提高了
public String toString(){
return "A="+buckets[0].now+",B="+buckets[1].now+",C="+buckets[2].now;
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
public class Myset {
private Object[] objs= new Object[0];
public boolean contains(Object obj){
for(Object tmp: objs){
if(tmp.equals(obj)){
return true;
}
}
return false;
}
public boolean add(Object obj){
if(contains(obj)){
return false;
}
Object[] tempObjs = new Object[objs.length+1];
System.arraycopy(objs, 0, tempObjs, 0, objs.length);
tempObjs[objs.length] = obj;
objs = tempObjs;
return true;
}
public Object[] getAll(){
return objs;
}
public int size(){
return objs.length;
}
}
样题描述:有a、b、c三个油桶;a桶的容量为12斤,现有12斤油;b桶容量为8斤,现有0斤;c桶容量5斤,现有0斤。现一次只能由一个桶向另一个同倒油,问怎样才能倒出6斤油。
[java] view
plain copy
package cn.hncu.search.oil.dfs;
import cn.hncu.search.oil.common.Bucket;
import cn.hncu.search.oil.common.DumpCase;
import cn.hncu.search.oil.common.Myset;
public class DumpOilDFS {
public static void main(String[] args) {
Bucket buckets[] = new Bucket[3];
buckets[0] = new Bucket(12, 12);
buckets[1] = new Bucket(8, 0);
buckets[2] = new Bucket(5, 0);
DumpCase u = new DumpCase(buckets);
Myset caseSet = new Myset();
caseSet.add(u);
dfs(u,caseSet);
}
public static void print(DumpCase u,Myset caseSet){
Myset set = new Myset();
set.add(u);
DumpCase d = u.getParent();
while(d!=null){
set.add(d);
d = d.getParent();
}
System.out.println("------------");
Object objs[] = set.getAll();
for(int i=objs.length-1; i>=0; i--){
DumpCase v = (DumpCase) objs[i];
System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);
}
}
public static void dfs(DumpCase u0, Myset caseSet){
//递归鸿沟
for(Bucket bucket: u0.getBuckets()){
if(bucket.now==6){
//System.out.println("find a case");
print(u0,caseSet);
return;
}
}
int n = u0.getBuckets().length;//桶的个数
DumpCase u = new DumpCase(u0);
//用备份节点去搜
//遍历所有的DumpCase: 依次让桶i向j倒
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
//自己不能给自己倒
if(i==j){
continue;
}
//算出桶i给j倒时,能倒多少-->canDump
int canDump = u.getBuckets()[i].canOut();
if(u.getBuckets()[i].canOut()>u.getBuckets()[j].canIn()){
canDump = u.getBuckets()[j].canIn();
}
//倒油
u.getBuckets()[i].out(canDump);
u.getBuckets()[j].in(canDump);
//System.out.println(u.getBuckets()[0].now+","+u.getBuckets()[1].now+","+u.getBuckets()[2].now);
//判断该情况是否已经出现过了//如果存在,要还原(把油倒回去)
if(caseSet.contains(u)){
//把油还回去
u.getBuckets()[i].in(canDump);
u.getBuckets()[j].out(canDump);
continue;
}
//经过上面的哨兵,说明这样倒可以
DumpCase v = new DumpCase(u);
v.setParent(u0);
caseSet.add(v);
//System.out.println(v.getBuckets()[0].now+","+v.getBuckets()[1].now+","+v.getBuckets()[2].now);
dfs(v,caseSet);
//再倒回去,以重新进行下一个邻居的遍历
u.getBuckets()[i].in(canDump);
u.getBuckets()[j].out(canDump);
}
}
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
public class Bucket {
public int max;
public int now;
public Bucket(int max, int now) {
this.max = max;
this.now = now;
}
public void in(int a){
now += a;
}
public void out(int a){
now -=a;
}
public int canIn(){
return max-now;
}
public int canOut(){
return now;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + max;
result = prime * result + now;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bucket other = (Bucket) obj;
if (max != other.max)
return false;
if (now != other.now)
return false;
return true;
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
import java.util.Arrays;
public class DumpCase {
Bucket buckets[];
DumpCase parent = null;
public DumpCase() {
}
public DumpCase(Bucket buckets[]) {
this.buckets = buckets;
}
//必须要进行深拷贝
public DumpCase(DumpCase u) {
this.buckets = new Bucket[ u.getBuckets().length ];
for(int i=0; i<u.getBuckets().length;i++){
buckets[i] = new Bucket(0,0);
buckets[i].max = u.getBuckets()[i].max;
buckets[i].now = u.getBuckets()[i].now;
}
}
public Bucket[] getBuckets() {
return buckets;
}
public DumpCase getParent() {
return parent;
}
public void setParent(DumpCase parent) {
this.parent = parent;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(buckets);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DumpCase other = (DumpCase) obj;
if (!Arrays.equals(buckets, other.buckets))
return false;
return true;
}
//※1 用“特征串”来代表整个对象,如果特征串相等,则表示是相等的对象。这样在比较对象时,性能就提高了
public String toString(){
return "A="+buckets[0].now+",B="+buckets[1].now+",C="+buckets[2].now;
}
}
[java] view
plain copy
package cn.hncu.search.oil.common;
public class Myset {
private Object[] objs= new Object[0];
public boolean contains(Object obj){
for(Object tmp: objs){
if(tmp.equals(obj)){
return true;
}
}
return false;
}
public boolean add(Object obj){
if(contains(obj)){
return false;
}
Object[] tempObjs = new Object[objs.length+1];
System.arraycopy(objs, 0, tempObjs, 0, objs.length);
tempObjs[objs.length] = obj;
objs = tempObjs;
return true;
}
public Object[] getAll(){
return objs;
}
public int size(){
return objs.length;
}
}
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树