{
tmpPath.push_back(i);
TrackBack(i,sum);
tmpPath.pop_back();
}
cout<
PrintPath();
}
/*
文件名:Node.h 为BoundSalesMan所调用,结点数据结构 */
#pragma once
#include
using namespace std;
struct Node
{
public:
int num;//约数
int level; //层级
int
position; //当前结点
vector> m; //当前结点的矩阵
vectorstates; //当前路径状态集
Node(){};
Node(int n,int l,int
position,vectorpath,vector> mValue);
bool operator< (const
Node & B)const
{
return num>B.num;
}
};
/*
文件名:Node.cpp 为BoundSalesMan所调用,结点数据结构的实现 */
#include "StdAfx.h"
#include "Node.h"
Node::Node(int n,int l,int pos,vectorpath,vector> mValue)
{
num=n;
level=l; position=pos;
states=path; m=mValue;
}
/*
文件名:BoundleSalesMan.h
限界函数法 */
#pragma once
#include "salesman.h"
#include
#include "Node.h"
class BoundSalesMan :
public
SalesMan
{
protected:
int
SetIMatrix(int i,int
k,vector> & im);//生成第i点的规约矩阵,并返回约数,k点为其父结点
int
Cost(vectorA); //获取A中保存的路径的路径长度
int
SimMatrix(vector< vector>
& m); //将m规约
public:
void
Travel();
};
/* 文件名:BoundleSalesMan.cpp
限界函数法 */
#include "StdAfx.h"
#include "BoundSalesMan.h"
#include "Node.h"
#include
#include
int BoundSalesMan::SimMatrix(vector> & m)
//将m规约
{
int
result=0;
int col=(int)m.size()-1;
bool
boolMax,boolZone;
//对行进行规约
for (int i=0;i<=col;i++)
{
boolMax=true,
boolZone=false;
for (int j=0;j<=col;j++)
{
boolMax=boolMax &&
(m[i][j]==MAXNUM); //所有都是无穷大
boolZone=boolZone || (m[i][j]==0)
; //是否有一个是0
}
if
((boolMax) || (boolZone))
//如果本行所有数据元素都是无穷大,或者有一个是0,本行已经规约
continue;//继续下一行
else //否则
{
//从本行中找到最小的一个值,减去他,约数加上这个值
int
min=m[i][0];
for
(int k=1;k<=col;k++)
{
if
(min>m[i][k])
min=m[i][k];
}
for
(int k=0;k<=col;k++)
{
if
(m[i][k]!=MAXNUM) //如果是无穷值,则不变
m[i][k]-=min;
}
result+=min;
}
}
//对列进行规约
for (int i=0;i<=col;i++)
{
boolMax=true,
boolZone=false;
for (int j=0;j<=col;j++)
{
boolMax=boolMax &&
(m[j][i]==MAXNUM); //所有都是无穷大
boolZone=boolZone || (m[j][i]==0)
; //是否有一个是0
}
if
((boolMax) || (boolZone))
//如果本列所有数据元素都是无穷大,或者有一个是0,本列已经规约
continue;//继续下一列
else //否则
{
//从本列中找到最小的一个值,减去他,约数加上这个值
int
min=m[0][i];
for
(int k=1;k<=col;k++)
{
if
(min>m[k][i])
min=m[k][i];
}
for
(int k=0;k<=col;k++)
{
if
(m[k][i]!=MAXNUM) //如果是无穷值,则不变
m[k][i]-=min;
}
result+=min;
}
}
return
result;
}
int
BoundSalesMan::SetIMatrix(int i,int k,vector> & im)
//生成第i点的规约矩阵
{
int
cols=im.size()-1;
//先将k行 和i列置为无穷/
for (int j=0;j<=cols;j++)
{
im[k][j]=MAXNUM;
im[j][i]=MAXNUM;
}
//再将i行0列置为无穷
im[i][0]=MAXNUM;
//再进行规约,记录规约值
return SimMatrix(im);
}
int BoundSalesMan::Cost(vectorA)
//获取A中保存的路径的路径长度
{
int
i=A.size();
int
sum=matrix[0][A[0]];//先求从0到第一个点的距离
for (unsigned int
i=1;i{
sum+=matrix[A[i-1]][A[i]];
}
sum+=matrix[A[i-1]][0];//再加上最后一个点到0点的距离
return sum;
}
void BoundSalesMan::Travel()
{
path.clear();
vector> simpleM=matrix; //0点的规约矩阵
int
n0=SimMatrix(simpleM);
int
cols=matrix.size()-1;
priority_queuep;
Node firstNode(n0,0,0,path,simpleM);
p.push(firstNode); //0结点入队列
Node node;
while (!
p.empty() && p.top().level{
node=p.top();
p.pop();
for (int i=1;i<=cols;i++)
{
for
(int j=0;j{
if
(i==node.states[j]) //路径里有这个点了
break;
}
if
(jcontinue;
//否则
simpleM=node.m;
int
tmp=node.num;
tmp+=simpleM[node.position][i];
tmp+=SetIMatrix(i,node.position
,simpleM); //对第i点的矩阵进行处理 vectortmpPath=node.states;
tmpPath.push_back(i);
Node newNode(tmp,node.level+1,i,tmpPath,simpleM);
p.push(newNode);
}
}
path=p.top().states;
cout<
PrintPath();
}
//
stdafx.h : 标准系统包含文件的包含文件,
//
或是常用但不常更改的项目特定的包含文件
#pragma once
#include
#include
二.测试数据及结果
1.
5
999
20 30
10 11
15 999 16
4 2
3 5
999 2 4
19 6
18 999 3
16 4
7 16 999
对应结果:
2.
4
999
10 15
20
5 999
9 10
6 13
999 12
8 8
9 999
对应结果: