深度和广度优先分油问题(C#实现)

2016-01-29 13:25 2 1 收藏

深度和广度优先分油问题(C#实现),深度和广度优先分油问题(C#实现)

【 tulaoshi.com - ASP.NET 】

分油问题-、问题描述分油问题:两个小孩去打油,一人带了一个一斤的空瓶,另一个带了一个七两和一个三两的空瓶。原计划各打一斤油,可是由于所带的钱不够,只好合打了一斤油,在回家的路上,二人想平分这一斤油,可是又没有其它工具。现只用这三个瓶子(一斤、七两、三两)精确地分出两个半斤油来。二、算法描述F 算法选择通过分析题目并结合深度优先、广度优先和迭代加深搜索的算法的特点以及有缺点,这里选择广度优先算法来求解该分油问题。如果采用深度优先算法搜索,由于其盲目性导致搜索陷入局部陷阱,并不一定能求得解即使得到解也不一定是最优解,因此并不采用此算法。迭代加深搜索则是在固定的深度上进行深度和广度搜索结合的策略来进行搜索,这样避免了单一的深度搜索无法得到解的缺点,但是找到的解并不一定是最优解。广度优先以牺牲空间代价和时间代价来换取保证取得最优解。由于该问题并不复杂,即使使用广度优先算法也不会占有太多的空间和时间,因此为了取得最优解这里选择广度优先算法来求解。F 算法描述1. 用unVisitedBttsArr表示初始节点列表(待扩展,此为一个动态数组)2. 如果unVisitedBttsArr为空集,则退出并给出失败信号3. n取为unVisitedBttsArr的第一个节点,并在 unVisitedBttsArr中删除节点n,放入已访问节点列表haveVisitedBttsArr4. 如果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.Eq

来源:https://www.tulaoshi.com/n/20160129/1490104.html

延伸阅读
在.Net 中 DataGrid 虽然有排序的功能,但并不支持双向的排序。用到了,看了些相关的帖子,自己尝试了一种方法,竟然也行得通,主要是用DataGrid.Attributes 存了一个参数,同时在onSortCommand中修改了DataGridColumn的SortExpression. 代码如下: private void BindData(){ DataTable dt = .......; if(dt != null) { DataVi...
现在有很多网络管理软件都具备网络上信息实时传送的功能,虽然有些网络通讯软件功能比较强大,有的软件不仅可以传送文本信息,还可以传送二进制文件等。但它们都有一个无法克服的缺点,那就是分发比较困难,信息传送双方计算机都需要安装通讯软件的客户端和服务器端软件,并且只有但双方都打开相应软件时,才可能进行信息传送。而信使通讯...
最近经朋友介绍开始玩 密传 网络游戏 升级升级,突然觉得太费键盘,于是自己用C#写了一个程序,想代替我的操作,自己去打怪物,自己升级 用这个东西升了好多级了,现在把源码贴出来,和大家共享,欢迎大家批评指正,感激不尽。 程序大概分成两个部分,一个部分是类库,一个是应用程序 大概的思路就是找到游戏进程的主窗口句柄,然后发送游戏...
橡皮区矩形 CRectTracker C# 实现 作者:fanjunxing 下载源代码 本文要求读者熟悉 C# 开发环境: Visual Studio .NET 2003 Windows 2000 测试环境:Windows 2000 更新记录:2004.4.7 第一次更新 使用许可:代码...
本文给出一个用 C# 编程实现 读写 Binary 的实例代码,对于初学者来说是个不可多得的参考性文章…… 以下是引用片段: //返回blob数据 public MemoryStream getBlob(string SQL) ...{ try ...{ Db_Conn(); cmd = new OleDbCommand(SQL, Conn); cmd.Comma...

经验教程

65

收藏

71
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部