首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> 数据库教程
深度和广度优先分油问题(C#实现)-.NET教程,C#语言
作者:网友供稿 点击:235
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
分油问题

-、问题描述

分油问题:两个小孩去打油,一人带了一个一斤的空瓶,另一个带了一个七两和一个三两的空瓶。原计划各打一斤油,可是由于所带的钱不够,只好合打了一斤油,在回家的路上,二人想平分这一斤油,可是又没有其它工具。现只用这三个瓶子(一斤、七两、三两)精确地分出两个半斤油来。

二、算法描述

f 算法选择

通过分析题目并结合深度优先、广度优先和迭代加深搜索的算法的特点以及有缺点,这里选择广度优先算法来求解该分油问题。如果采用深度优先算法搜索,由于其盲目性导致搜索陷入局部陷阱,并不一定能求得解即使得到解也不一定是最优解,因此并不采用此算法。迭代加深搜索则是在固定的深度上进行深度和广度搜索结合的策略来进行搜索,这样避免了单一的深度搜索无法得到解的缺点,但是找到的解并不一定是最优解。广度优先以牺牲空间代价和时间代价来换取保证取得最优解。由于该问题并不复杂,即使使用广度优先算法也不会占有太多的空间和时间,因此为了取得最优解这里选择广度优先算法来求解。

f 算法描述

1. 用unvisitedbttsarr表示初始节点列表(待扩展,此为一个动态数组)

2. 如果unvisitedbttsarr为空集,则退出并给出失败信号

3. n取为unvisitedbttsarr的第一个节点,并在 unvisitedbttsarr中删除节点n,放入已访问节点列表havevisitedbttsarr

4. 如果n为目标节点,则退出并给出成功信号

5. 否则,将n的子节点加到n的末尾,并返回2)步

f 问题分析

l 选择合适的数据结构表示问题状态

f 用向量(t,s,r)表示状态——t表示10两瓶中的油量,s表示7两瓶中的油量,r表示3两瓶中的油量。

f 问题的起始状态:(10,0,0)。

f 问题的目标状态:(5,2,3)或者(5,3,2)或者(5,5,0)。

l 确定智能算子,用以表示变化状态的规则。由于总共油量为10两,而10两的瓶可以装满所有的油,因此可以把10两的瓶当作一个大油桶,这样此题就化为和上一题8/6类似的问题了。因此在描述变化状态的时候只需给出7、3瓶的状态即可,10瓶的状态即为10-s-r的油量。可是由于在程序处理上的一致性,在程序的实现上我还是把10、8、6的瓶子统一处理,而不是用两个状态表示。


规则
解释

1
(s,r) and s<7 à (7,r)
7斤瓶不满时装满

2
(s,r) and r <3 à (s,3)
3斤瓶不满时装满

3
(s,r) and s >0 à (0,r)
7斤瓶不空时倒空

4
(s,r) and r >0 à (s,0)
3斤瓶不空时倒空

5
(s,r) and s>0 and s+r≤3à (0,s+r)
7斤瓶中油全倒入3斤瓶

6
(s,r) and r >0 and s+r≤7à (s+r,0)
3斤瓶中油全倒入7斤瓶

7
(s,r) and s<7 and s+r≥7à (7, s+r -7)
用3斤瓶油装满7斤瓶子

8
(s,r) and r <3 and s+r≥3à (s+r -3,3)
用7斤瓶油装满3斤瓶子


三、程序设计

算法使用c#语言来实现的。程序主要根据上面提供的广度优先算法的描述来对算法进行实现的。程序共有四个类:

bottle类,用来描述瓶子的状态以及一些行为动作和属性。

widthsearch类,是广度优先搜索算法的实现类

depthsearch类,是深度优先搜索算法的实现类

mainform类,是界面设计的类。

这里提供两个算法的实现主要是为了做个对比。

以下主要对几个核心算法的程序实现进行说明介绍。

//瓶子类

public class bottle

{

int capability = 0 ;//瓶子的总容量

int current = 0 ;//当前瓶子中的油量

int remain = 0 ;//瓶子中剩余的量



//倒入油的行为动作

public void add(int val)

{

current += val;

remain -= val;

}

//倒出油的行为动作

public void sub(int val)

{

current -= val;

remain += val;

}



//深度优先算法实现类

public class depthsearch

public void searching()

{

random r = new random();



while(bottle_10.currentval != 5) //判断是否达到目标状态

{

int random = r.next(1,7);//用随机产生的数来随机确定下一个子状态



switch(random)

{

case 1 :

flowto(bottle_03,bottle_07);

break;

case 2 :

flowto(bottle_10,bottle_03);

break;

case 3 :

flowto(bottle_07,bottle_03);

break;

case 4 :

flowto(bottle_10,bottle_07);

break;

case 5 :

flowto(bottle_03,bottle_10);

break;

case 6 :

flowto(bottle_07,bottle_10);

break;

default :

break;

}

if(!statearr.contains(bottlesstate()))

{

statearr.add(bottlesstate());

}

else

{

returntoprestate();

}



}

}



//倒油的动作。这里是从bottle1倒到bottle2

private void flowto(bottle bottle1,bottle bottle2)

{

if(bottle1.currentval>bottle2.remainval)

{

bottle1.sub(bottle2.remainval);

bottle2.currentval = bottle2.capabilityval;

}

else

{

bottle2.add(bottle1.currentval);

bottle1.currentval = 0;

}

}



//广度优先搜索实现类

public class widthsearch

public void s(treenode node)

{

while(unvisitedbttsarr.count>=0) //未访问表中如果有结点继续循环搜索否则跳出

{



treenode n = (treenode)unvisitedbttsarr[0];



bool flag = true;



//检查是否已经访问过

foreach(treenode i in havevisitedbttsarr)

{

if(i.text.equals(n.text))

{

havevisitedbttsarr.add(unvisitedbttsarr[0]);



unvisitedbttsarr.removeat(0);



flag = false;

break;

}

}



//若已经遍历过的不需要继续遍历 跳到下一个

if(flag)

{

if(search(n))

{

return;

}

}



}

}

//创建子结点并加入到unvisitedbttsarr中。

private bool createnode(treenode node)

{

treenode n = new treenode(bottlesstate());



unvisitedbttsarr.add(n);



if(bottle_10.currentval == 5)

{

node.nodes.add(n);



setpath(n);



return true;

}



node.nodes.add(n);



return false;

}

//回溯取得最佳路径

private void setpath(treenode n)

{

while(n.parent!=null)

{

path = n.text + " -> " + path;

n.forecolor = system.drawing.color.blue;

n = n.parent;

}

}





四、试验结果

如下是试验结果:

1)深度优先随机产生子结点的搜索路径






2)广度优先算法实现图





从以上两个结果来看,如果存在解则广度优先总能找到最优解,但是从时间上来看深度优先更快而广度优先需要遍历每个结点造成时间空间都开销比较大,所以时间上肯定花的比较多。但是可以保证找到最优解。此问题由于比较简单,复杂度不高,只需在第九步就可以找到最优解了,因此深度优先是可取的,但是如果是在某些复杂的问题中,此算法就可能导致组合爆炸,占用空间过大导致算法的不可行。

请指点。要源程序的可email给我,代码没有优化。




文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·jsp留言板源代码4-JSP教程,数据库相关
·“脱衣秀”泛滥 四川打击淫秽色情视频聊天室
·c#中使用 crystal reports (水晶报表)的打包和部署问题-.NET教程,报表/图形/Office
·MDAC2.8 下载!-ASP教程,数据库相关
·数据库安装包的制作(参考MSDN)-.NET教程,安装和部署
·asp讲座之七:asp与数据库(二)
·深度和广度优先分油问题(C#实现)-.NET教程,C#语言
·C#在状态栏中,自绘进度条,-.NET教程,C#语言
·怎么清除sql server日志
·C#中的接口-.NET教程,C#语言
最新文章
·sql server 2005 ce基础概要_数据库教程
·用flash as代码制作按钮弹出窗口_flash教程
·alexa:戏曲性地调整_alexa排名
·google也推出域名注册_google推广
·技巧总结:div中class与id的区别及应用_css教程
·windows vista命令runas.exe全解析_windows vista
·photoshop将美女照片处理成仿古斑驳油画_photoshop教程
·百度主题推广代码的完全解析-知己知彼_网赚技巧
·你的google adsense帐号是否被人盗用?_网赚技巧
·如何挑出google adsense中单价极低的广告商_网赚技巧
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭