算法之回溯法实现文档格式.docx
《算法之回溯法实现文档格式.docx》由会员分享,可在线阅读,更多相关《算法之回溯法实现文档格式.docx(33页珍藏版)》请在冰豆网上搜索。
int**a,
cc,
bestc,
NoEdge;
};
voidSwap(inta,intb)
inttemp;
temp=a;
a=b;
b=temp;
return;
}
voidtravel:
:
Backtrack(inti)
if(i==n)
{
if(a[x[n-1]][x[n]]!
=NoEdge&
&
a[x[n]][1]!
(cc+a[x[n-1]][x[n]]+a[x[n]][1])<
bestc||bestc==NoEdge)
{
for(intj=1;
j<
=n;
j++)bestx[j]=x[j];
bestc=cc+a[x[n-1]][x[n]]+a[x[n]][1];
}
}
else
for(intj=i;
j++)
if(a[x[i-1]][j]!
=NoEdge
&
(cc+a[x[i-1]][x[j]]<
bestc||bestc==NoEdge))
{
swap(x[i],x[j]);
cc+=a[x[i-1]][x[i]];
Backtrack(i+1);
cc-=a[x[i-1]][x[i]];
}
intTSP(int**a,intv[],intn,intNoEdge)
travelY;
Y.x=newint[n+1];
for(inti=1;
i<
i++)
Y.x[i]=i;
Y.a=a;
Y.n=n;
Y.bestc=NoEdge;
Y.bestx=v;
Y.cc=0;
Y.NoEdge=NoEdge;
Y.Backtrack
(2);
delete[]Y.x;
returnY.bestc;
intmain()
intconstmax=10000;
cout<
<
"
请输入节点数:
"
<
endl;
intn;
cin>
>
n;
int*v=newint[n];
//保存路径
intNoEdge=0;
int**p=newint*[max];
for(inti=0;
n+1;
i++)//生成二维数组
p[i]=newint[n+1];
请依次输入各城市之间的路程:
for(intj=0;
cin>
p[i+1][j+1];
最短路径长度:
TSP(p,v,4,1000)<
路径为:
;
5;
cout<
v[i]<
'
'
return0;
运行截图:
旅行售货员问题(分支限界法):
#defineMAX_CITY_NUMBER10//城市最大数目
#defineMAX_COST1000//两个城市之间费用的最大值
intCity_Graph[MAX_CITY_NUMBER][MAX_CITY_NUMBER];
//表示城市间边权重的数组
intCity_Size;
//表示实际输入的城市数目
intBest_Cost;
//最小费用
intBest_Cost_Path[MAX_CITY_NUMBER];
//结点
typedefstructNode{
intlcost;
//优先级
intcc;
//当前费用
intrcost;
//剩余所有结点的最小出边费用的和
ints;
//当前结点的深度,也就是它在解数组中的索引位置
intx[MAX_CITY_NUMBER];
//当前结点对应的路径
structNode*pNext;
//指向下一个结点
}Node;
//堆
typedefstructMiniHeap{
Node*pHead;
//堆的头
}MiniHeap;
//初始化
voidInitMiniHeap(MiniHeap*pMiniHeap){
pMiniHeap->
pHead=newNode;
pHead->
pNext=NULL;
//入堆
voidput(MiniHeap*pMiniHeap,Nodenode){
Node*next;
Node*pre;
Node*pinnode=newNode;
//将传进来的结点信息copy一份保存
//这样在函数外部对node的修改就不会影响到堆了
pinnode->
cc=node.cc;
lcost=node.lcost;
pNext=node.pNext;
rcost=node.rcost;
s=node.s;
for(intk=0;
k<
City_Size;
k++){
pinnode->
x[k]=node.x[k];
pre=pMiniHeap->
pHead;
next=pMiniHeap->
pNext;
if(next==NULL){
pMiniHeap->
pNext=pinnode;
else{
while(next!
=NULL){
if((next->
lcost)>
(pinnode->
lcost)){//发现一个优先级大的,则置于其前面
pinnode->
pNext=pre->
pre->
break;
//跳出
pre=next;
next=next->
pre->
//放在末尾
//出堆
Node*RemoveMiniHeap(MiniHeap*pMiniHeap){
Node*pnode=NULL;
if(pMiniHeap->
pNext!
pnode=pMiniHeap->
pNext=pMiniHeap->
pNext->
returnpnode;
//分支限界法找最优解
voidTraveler(){
inti,j;
inttemp_x[MAX_CITY_NUMBER];
Node*pNode=NULL;
intminiSum;
//所有结点最小出边的费用和
intminiOut[MAX_CITY_NUMBER];
//保存每个结点的最小出边的索引
MiniHeap*heap=newMiniHeap;
//分配堆
InitMiniHeap(heap);
//初始化堆
miniSum=0;
for(i=0;
i<
i++){
miniOut[i]=MAX_COST;
//初始化时每一个结点都不可达
for(j=0;
j<
j++){
if(City_Graph[i][j]>
0&
City_Graph[i][j]<
miniOut[i]){
//从i到j可达,且更小
miniOut[i]=City_Graph[i][j];
if(miniOut[i]==MAX_COST){//i城市没有出边
Best_Cost=-1;
return;
miniSum+=miniOut[i];
i++){//初始化的最优路径就是把所有结点依次走一遍
Best_Cost_Path[i]=i;
Best_Cost=MAX_COST;
//初始化的最优费用是一个很大的数
pNode=newNode;
//初始化第一个结点并入堆
pNode->
lcost=0;
//当前结点的优先权为0也就是最优
cc=0;
//当前费用为0(还没有开始旅行)
rcost=miniSum;
//剩余所有结点的最小出边费用和就是初始化的miniSum
s=0;
//层次为0
k++)