旅行售货员问题(回溯法搜索排列树)
来源:互联网 发布:淘宝提高动态评分 编辑:程序博客网 时间:2024/06/04 18:45
用回朔法解旅行售货员问题:
解法1:建立一个无向完全图,根据图建立一颗排列树,用深度优先搜索排列树,找到最优解
困难1:在建树的过程中,如何得知当前结点的祖先结点有哪些?(即如何得知哪些结点已经访问过)
解决办法:每个树结点的都含有这样一个信息域,负责记录还没有访问过的结点集合。具体做法是在创建每个结点时,结点的这个信息域的值等于从其父节点的这个信息域的值集合中删除自身结点得到的集合。
困难2:在遍历排列树的时候,需要记录结点间的路径和,我是从下至上记录的(遍历到叶结点才开始记录权值,每向上走一层,都比较同一父亲的子树中的路径,选取最短的,舍弃其它的),而不是采用从上至下(在遍历每一个结点时,立即计算从根节点到该结点的路径和,直至到达叶结点,再比较刚得到的路径是否为当前最短路径), 如何记录遍历的路径?
解决办法:从上至下的方法,设置一个栈,在遍历每一个结点前入栈,对该结点遍历结束后出栈;
然而,从下至上法,路径的记录比较麻烦,因为每向上走一层,都要在同一父亲的子树间选取最优的,舍弃其它的。用一个堆栈是不能解决这个问题的,还需要一个保留最优路径的栈时刻跟踪记录当前得到的最优子树,核心代码如下:
public int Traverse(TreeNode node,Graph g,ref Stack priPathStack)//自下而上计算权值
//找到该结点下的最小路径,并返回最小路径,priPathStack负责传出这个结点返回的最优路径的序列(不包括这个结点)
...{
if (node.firstchild == null)//到了叶结点
...{
return (int)((ArrayList)g.AdjacentMatrix[node.data])[0];//叶结点与根结点之间的路径,因为需要回路
}
int iTemp;
TreeNode lastnode;
int minPath;
Stack emptyStack = new Stack();//!!!!!!!!!!!!!!!!!!!!!!!!!!!!
lastnode = node.firstchild;
minPath = lastnode.upedgeweight + Traverse(lastnode,g,ref emptyStack);
emptyStack.Push(lastnode.data);//!!!!!!!!!!!!!!!!!
priPathStack = new Stack(emptyStack);//得到第一棵子树内的最优路径,并记下!!!!!!!!!!!
lastnode = lastnode.nextsib;
while (lastnode != null)
...{
emptyStack.Clear();//开始查找下一棵子树,emptyStack准备存放下一棵子树的最优路径!!!!!
iTemp = lastnode.upedgeweight + Traverse(lastnode,g,ref emptyStack);
if (iTemp < minPath)
...{
minPath = iTemp;
emptyStack.Push(lastnode.data);//!!!!!!!!!!!!!!!!
priPathStack = new Stack(emptyStack);//!!!!!!!!!!!!!!!!!
}
lastnode = lastnode.nextsib;
}
priPathStack = new Stack(priPathStack);//因为堆栈的复制结果会颠倒顺序,所以需要这样倒一下!!!!!!
return minPath;
}
//找到该结点下的最小路径,并返回最小路径,priPathStack负责传出这个结点返回的最优路径的序列(不包括这个结点)
...{
if (node.firstchild == null)//到了叶结点
...{
return (int)((ArrayList)g.AdjacentMatrix[node.data])[0];//叶结点与根结点之间的路径,因为需要回路
}
int iTemp;
TreeNode lastnode;
int minPath;
Stack emptyStack = new Stack();//!!!!!!!!!!!!!!!!!!!!!!!!!!!!
lastnode = node.firstchild;
minPath = lastnode.upedgeweight + Traverse(lastnode,g,ref emptyStack);
emptyStack.Push(lastnode.data);//!!!!!!!!!!!!!!!!!
priPathStack = new Stack(emptyStack);//得到第一棵子树内的最优路径,并记下!!!!!!!!!!!
lastnode = lastnode.nextsib;
while (lastnode != null)
...{
emptyStack.Clear();//开始查找下一棵子树,emptyStack准备存放下一棵子树的最优路径!!!!!
iTemp = lastnode.upedgeweight + Traverse(lastnode,g,ref emptyStack);
if (iTemp < minPath)
...{
minPath = iTemp;
emptyStack.Push(lastnode.data);//!!!!!!!!!!!!!!!!
priPathStack = new Stack(emptyStack);//!!!!!!!!!!!!!!!!!
}
lastnode = lastnode.nextsib;
}
priPathStack = new Stack(priPathStack);//因为堆栈的复制结果会颠倒顺序,所以需要这样倒一下!!!!!!
return minPath;
}
解法2:(巧妙)不需要建立排列树,用一个数组实现结点的排列遍历,并存放当前遍历的路径,核心代码如下:
public void Backtrack(int t)//t从1到n
...{
if (t > g.NodeNumber)
Output();
else
...{
for (int i = t; i <= g.NodeNumber; i++)
...{
Swap(ref alnode,t-1,i-1);//注意,层次从1开始,结点编号从0开始
if (Constraint(t) && Bound(t))
...{
Backtrack(t+1);
}
Swap(ref alnode,t-1,i-1);
}
}
}
...{
if (t > g.NodeNumber)
Output();
else
...{
for (int i = t; i <= g.NodeNumber; i++)
...{
Swap(ref alnode,t-1,i-1);//注意,层次从1开始,结点编号从0开始
if (Constraint(t) && Bound(t))
...{
Backtrack(t+1);
}
Swap(ref alnode,t-1,i-1);
}
}
}
- 旅行售货员问题(回溯法搜索排列树)
- 算法java实现--回溯法--旅行售货员问题--排列树
- 旅行售货员问题(回溯法实现)
- 回溯法----旅行售货员问题
- 旅行售货员问题(回溯法)
- 旅行售货员问题-回溯法
- 回溯法-旅行售货员问题(C语言)
- 旅行售货员问题的回溯法求解
- 回溯法_旅行售货员问题
- 旅行售货员问题(回溯、分枝限界)
- 回溯子集树与排列树——装载问题&旅行售货员问题(算法设计课题)
- 旅行商问题(深度优先搜索 回溯法 排列树)
- 旅行售货员问题 回溯法 与 01背包的区别
- 回溯算法;旅行售货员问题;排列树;需要访问的是各个地点,不是路径;第一个排列点是出发点;O(n!)
- 回溯法搜索排列树的问题
- 旅行售货员问题(c++)
- 分支限界法----旅行售货员问题
- 分支限界法----旅行售货员问题
- 因为数据库正在使用,所以未能获得对数据库的排它访问权。RESTORE DATABASE 操作异常终止。
- HELLO WORLD!
- 中文版SPPS 2003安装手册
- ajax执行的顺序问题.
- I learned several ASP.NET's AJAX ability today! It is so interesting and so easy to use AJAX in ASP.NET.
- 旅行售货员问题(回溯法搜索排列树)
- 相关网站
- linux-Vi使用方法(备查)
- 打印预览时看不到报告图片
- 纪念的新电脑:时隔4年,我再次彻底买了一台新电脑。真是爽!
- vb.net学习总结五(数组)
- 抓取屏幕中选中区域并存取为bmp位图的类
- asp.net大附件上传问题
- Sharepoint开发中所需要的系统环境