用分支限界法实现旅行售货员问题c++

零起跑线 2009-06-01 10:55:01
下面这个程序能编译成功,但一运行就出错,实在找不出原因,希望高手指点
#include<iostream>
using namespace std;
#define Num 4
#define cNoEdge 99999

template<class Type>
class Traveling{
friend void main(void);
public:
Type BBTSP(int v[]);
private:
int n; //图G的顶点数
Type **a, //图G的邻接矩阵
NoEdge,//图G的无边标志
cc, //当前费用
bestc; //当前最小费用
};

template<class Type>
class MinHeapNode{
friend Traveling<Type>;
public:
operator Type() const {return lcost;}
private:
Type lcost, //子树费用下界
cc, //当前费用
rcost; //x[s:n - 1]中顶点最小的出边费用
int s, //根结点到当前结点的路径为x[0:s]
*x; //需要进一步搜索的顶点是x[s + 1:n - 1]
};

template<typename Type> class MinHeap{
public:
MinHeap(int size):m_nMaxSize(size)
,m_pheap(new Type[m_nMaxSize]),m_ncurrentsize(0){}
~MinHeap(){
delete[] m_pheap;
}

public:
bool Insert(const Type item); //insert element
bool Delete(const Type item); //delete element
void Print(const int start=0, int n=0);

private:
//adjust the elements of the child tree with the root of start from top to bottom
void Adjust(const int start, const int end);

private:
const int m_nMaxSize; //堆中元素数量的最大值
Type *m_pheap; //堆结点指针
int m_ncurrentsize; //当前堆中的元素数量
};

template<typename Type> void MinHeap<Type>::Adjust(const int start, const int end){
int i = start,j = i*2+1; //get the position of the child of i
Type temp=m_pheap[i];
while(j <= end){
if(j<end && m_pheap[j]>m_pheap[j+1]){ //left>right
j++;
}
if(temp <= m_pheap[j]){ //adjust over
break;
}
else{ //change the parent and the child, then adjust the child
m_pheap[i] = m_pheap[j];
i = j;
j = 2*i+1;
}
}
m_pheap[i] = temp;
}

template<typename Type> bool MinHeap<Type>::Insert(const Type item){
//向堆中插入堆结点元素item
if(m_ncurrentsize == m_nMaxSize){
cerr<<"Heap Full!"<<endl;
return 0;
}
m_pheap[m_ncurrentsize] = item;
int j = m_ncurrentsize, i = (j-1)/2; //get the position of the parent of j
Type temp = m_pheap[j];
while(j > 0){ //adjust from bottom to top
if(m_pheap[i] <= temp){
break;
}
else{
m_pheap[j] = m_pheap[i];
j = i;
i = (j-1)/2;
}
}
m_pheap[j] = temp;
m_ncurrentsize++;
return 1;
}

template<typename Type> bool MinHeap<Type>::Delete(const Type item){
//从堆中删除堆结点元素item
if(0 == m_ncurrentsize){
cerr<<"Heap Empty!"<<endl;
return 0;
}
for(int i=0; i<m_ncurrentsize; i++){
if(m_pheap[i] == item){
m_pheap[i] = m_pheap[m_ncurrentsize-1]; //filled with the last element
Adjust(i,m_ncurrentsize-2); //adjust the tree with start of i
m_ncurrentsize--;
i=0;
}
}
return 1;
}

template<typename Type> void MinHeap<Type>::Print(const int start, int n){
if(start >= m_ncurrentsize){
return;
}
Print(start*2+2, n+1); //print the right child tree

for(int i=0; i<n; i++){
cout<<" ";
}
cout<< m_pheap[start] << "--->" << endl;

Print(start*2+1, n+1); //print the left child tree
}


template<class Type>
Type Traveling<Type>::BBTSP(int v[])
{
int i,j;
//定义最小堆容量为1000
MinHeap<MinHeapNode<Type> >H(1000);
Type *MinOut=new Type[n+1];
//计算MinOut[i] = 顶点i的最小出边费用
Type MinSum=0; //最小出边费用和
for(i = 1;i <= n; i++){
Type Min = NoEdge;
for(j=1;j <= n;j++)
if(a[i][j] != NoEdge && (a[i][j] < Min || Min == NoEdge))
Min = a[i][j];
if(Min == NoEdge) return NoEdge;
MinOut[i] = Min;
// cout << MinOut[i] << endl; getchar();
MinSum += Min;
}
// cout << MinSum << endl; getchar();
//初始化
MinHeapNode<Type> E;
E.x=new int[n];
for(i = 0;i < n;i++ )//{
E.x[i] = i + 1;
// cout << E.x[i] << endl;}for(i = 0;i < n;i++ ){delete[] E.x; cout << E.x[i] << endl;getchar();}getchar();
E.s = 0;
E.cc = 0;
E.rcost = MinSum;
Type bestc = NoEdge;
//搜索排列空间树
while (E.s < n - 1){//非叶结点
// for(int i = E.s + 1;i < n; i++) {cout << E.x[i - 1] << endl;getchar();}getchar();
if (E.s == n - 2){//当前扩展结点是叶结点的父结点
//再加2条边构成回路
//所构成回路是否优于当前最优解
if(a[E.x[n - 2]][E.x[n - 1]] != NoEdge &&
a[E.x[n - 1]][1] != NoEdge && (E.cc +
a[E.x[n - 2]][E.x[n - 1]] + a[E.x[n - 1]][1]
< bestc || bestc == NoEdge)){
//费用更小回路
bestc = E.cc + a[E.x[n - 2]][E.x[n - 1]] + a[E.x[n - 1]][1];
// cout << cc << endl; getchar();
E.cc = bestc;
E.s++;
H.Insert(E);}
else delete [] E.x;
}//舍弃扩展结点
else{//产生当前扩展结点的儿子结点
for(int i = E.s + 1;i < n; i++)
// {cout << E.x[i - 1] << endl;getchar();
if(a[E.x[E.s]][E.x[i]] != NoEdge){
//可行儿子结点
Type cc = E.cc + a[E.x[E.s]][E.x[i]];
Type rcost = E.rcost - MinOut[E.x[E.s]];
Type b = cc + rcost;//下界
if(b < bestc || bestc == NoEdge){
//儿子可能含最优解
//结点插入最小堆
MinHeapNode< Type > N;
N.x = new int [n];
for (j = 0;j < n; j++)
N.x[j] =E.x[j];
N.x[E.s + 1] = E.x[i];
N.x[i] = E.x[E.s + 1];
N.cc = cc;
N.s = E.s + 1;
N.lcost = rcost;
H.Insert(N);}
}//}
delete[] E.x;}//完成结点扩展
// try {H.Delete(E);}
// catch(OutOfBounds){break;}
if(H.Delete(E) == 0) break;
}
if(bestc == NoEdge) return NoEdge;//无回路
//将最优级解复制到v[1:n]
for(i = 0;i < n; i++)
v[i + 1] = E.x[i];
while(true){//释放最小堆中所有结点
delete [] E.x;
// try{H.Delete(E);}
// catch(OutOfBounds){break;}
if(H.Delete(E) == 0) break;
}
return bestc;
}

void print(int v[])
{
int i;
for(i = 0; i < Num; i++)
cout << v[i] <<endl;
}

void main()
{
int v[Num + 1];
Traveling<int> Travel;
Travel.NoEdge = cNoEdge;
Travel.n = Num;
Travel.a = new int *[Num+1];
for(int i = 0;i <= Num; i++){
Travel.a[i] = new int [Num+1];
for(int j = 0;j <= Num; j++){
Travel.a[i][j] = Travel.NoEdge;
}
}
Travel.a[1][2] = 30;
Travel.a[1][3] = 6;
Travel.a[1][4] = 4;
Travel.a[2][1] = 30;
Travel.a[2][3] = 5;
Travel.a[2][4] = 10;
Travel.a[3][1] = 6;
Travel.a[3][2] = 5;
Travel.a[3][4] = 20;
Travel.a[4][1] = 4;
Travel.a[4][2] = 10;
Travel.a[4][3] = 20;
if(Travel.BBTSP(v) != Travel.NoEdge){
print(v);
}
else
cout << "无回路" << endl;
getchar();
}



...全文
1560 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
好长啊。。帮顶
零起跑线 2009-06-02
  • 打赏
  • 举报
回复
谢谢各位了,
虽然没解决问题
woods2001 2009-06-02
  • 打赏
  • 举报
回复
顶了~
zhan1094 2009-06-02
  • 打赏
  • 举报
回复
LZ很强悍,很牛······
帮顶
光宇广贞 2009-06-02
  • 打赏
  • 举报
回复
http://zhidao.baidu.com/question/72778805.html

这知道里面的好像说的就是你的问题。往下面看。
aaaa3105563 2009-06-02
  • 打赏
  • 举报
回复
帮顶
lingyin55 2009-06-02
  • 打赏
  • 举报
回复
另外你说无法识别OutOfBounds

加个#include "xcept.h"试试

[Quote=引用 2 楼 blvyoucan 的回复:]
在Type Traveling <Type>::BBTSP(int v[]) {}这个函数中有句
// try{H.Delete(E);}
// catch(OutOfBounds){break;}

我用vc6.0中编译一直无法识别OutOfBounds这个异常被我注释掉了,改成if(H.Delete(E) == 0) break;
今天回头想想,这两句好像不等价,问题可能出在这里,所以请问下,这个OutOfBounds异常该怎么写?
[/Quote]
lingyin55 2009-06-02
  • 打赏
  • 举报
回复
http://topic.csdn.net/t/20020512/20/716754.html

[Quote=引用 2 楼 blvyoucan 的回复:]
在Type Traveling <Type>::BBTSP(int v[]) {}这个函数中有句
// try{H.Delete(E);}
// catch(OutOfBounds){break;}

我用vc6.0中编译一直无法识别OutOfBounds这个异常被我注释掉了,改成if(H.Delete(E) == 0) break;
今天回头想想,这两句好像不等价,问题可能出在这里,所以请问下,这个OutOfBounds异常该怎么写?
[/Quote]
零起跑线 2009-06-02
  • 打赏
  • 举报
回复
在Type Traveling <Type>::BBTSP(int v[]) {}这个函数中有句
// try{H.Delete(E);}
// catch(OutOfBounds){break;}

我用vc6.0中编译一直无法识别OutOfBounds这个异常被我注释掉了,改成if(H.Delete(E) == 0) break;
今天回头想想,这两句好像不等价,问题可能出在这里,所以请问下,这个OutOfBounds异常该怎么写?

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧