java货郎担问题求解_货郎担问题的四种实现方法

{

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

对应结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值