什么是商旅问题啊?用c语言设计,是关于图的程序。最好能给出代码

Python011

什么是商旅问题啊?用c语言设计,是关于图的程序。最好能给出代码,第1张

旅行商问题(Traveling Saleman Problem,TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。字面上的理解是:有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市的具有最短路程的环路。

解决TSP问题的思想有回溯法、贪心法、动态规划法等。

如果动态规划法解决TSP问题,可以参考程序代码:

#include <list>

#include <iostream>

using namespace std

typedef list<int>LISTINT

LISTINT listAnother

LISTINT list_result

int d[4][4]={{-1,3,6,7},{2,-1,8,6},{7,3,-1,5,},{7,3,7,-1}}

int matrix_length=4

int getPath(int n,LISTINT list_org)

{

LISTINT::iterator i

int minValue

if(n==1)

{

i=list_org.begin()

minValue= d[*i-1][0]

if(list_org.size()==matrix_length-1)

{

list_result=list_org

}

}

else

{

int temp

i=list_org.begin()

temp=*i

list_org.erase(i)

i=list_org.begin()

minValue=d[temp-1][*(i)-1]+getPath(n-1,list_org)

if(list_org.size()==matrix_length-1)

{

list_result=list_org

}

for(int j=2j<nj++)

{

i=list_org.begin()

for(int k=1k<jk++)

{

i++

}

int tempvalue=*i

list_org.erase(i)

list_org.push_front(tempvalue)

i=list_org.begin()

tempvalue=d[temp-1][*(i)-1]+getPath(n-1,list_org)

if(tempvalue<minValue)

{

if(list_org.size()==matrix_length-1)

{

list_result=list_org

}

minValue=tempvalue

}

}

}

return minValue

}

int main(int argc, char* argv[])

{

LISTINT list_org

LISTINT::iterator h

list_org.push_front(4)

list_org.push_front(3)

list_org.push_front(2)

list_org.push_front(1)

cout<<"旅行商问题动态规划算法"<<endl

cout<<"路线长度的矩阵表示如下 (-1表示无限大)"<<endl

for(int j=0j<matrix_lengthj++){

cout<<endl

for(int k=0k<matrix_lengthk++){

cout<<" "<<d[j][k]

}

}

cout<<endl

cout<<"计算结果:"<<getPath(4,list_org)<<endl

list_result.push_front(1)

list_result.push_back(1)

cout<<"要走的路径:---->:"

for (h = list_result.begin()h != list_result.end()++h)

cout <<*h <<" "

cout <<endl

int i

cin>>i

return 0

}

这是别人的代码,注视很全,自己看吧!我也在研究这个算法问题

#include <stdio.h>

#include <malloc.h>

#define NoEdge 1000//图G的无边标记

struct MinHeapNode//最小堆,用于表示活结点优先队列;

{

int lcost//子树费用的下界

int cc//当前费用

int rcost//x[s:n-1]中顶点最小出边费用和

int s//根节点到当前节点的路径为x[0:s]

int *x//需要进一步搜索的顶点是//x[s+1:n-1]

struct MinHeapNode *next

}

int n//图G的顶点数

int **a//图G的邻接矩阵

int cc//当前费用

int bestc//当前最小费用

MinHeapNode* head = 0/*堆头*/

MinHeapNode* fq = 0/*堆第一个元素*/

MinHeapNode* lq = 0/*堆最后一个元素*/

int DeleteMin(MinHeapNode*&E)

{

MinHeapNode* tmp = NULL

tmp = fq

// w = fq->weight

E = fq

if(E == NULL)

return 0

head->next = fq->next/*一定不能丢了链表头*/

fq = fq->next

// free(tmp)

return 0

}

int Insert(MinHeapNode* hn)

{

if(head->next == NULL)

{

head->next = hn//将元素放入链表中

fq = lq = head->next//一定要使元素放到链中

}else

{

MinHeapNode *tmp = NULL

tmp = fq

if(tmp->cc >hn->cc)

{

hn->next = tmp

head->next = hn

fq = head->next/*链表只有一个元素的情况*/

}else

{

for(tmp != NULL)

{

if(tmp->next != NULL &&tmp->cc >hn->cc)

{

hn->next = tmp->next

tmp->next = hn

break

}

tmp = tmp->next

}

}

if(tmp == NULL)

{

lq->next = hn

lq = lq->next

}

}

return 0

}

int BBTSP(int v[])

{//解旅行售货员问题的优先队列式分支限界法

/*初始化最优队列的头结点*/

head = (MinHeapNode*)malloc(sizeof(MinHeapNode))

head->cc = 0

head->x = 0

head->lcost = 0

head->next = NULL

head->rcost = 0

head->s = 0

int *MinOut = new int[n + 1]/*定义定点i的最小出边费用*/

//计算MinOut[i]=顶点i的最小出边费用

int MinSum = 0//最小出边费用总合

for(int i = 1i <= ni++)

{

int Min = NoEdge/*定义当前最小值*/

for(int j = 1j <= nj++)

if(a[i][j] != NoEdge &&/*当定点i,j之间存在回路时*/

(a[i][j] <Min || Min == NoEdge)) /*当顶点i,j之间的距离小于Min*/

Min = a[i][j]/*更新当前最小值*/

if(Min == NoEdge)

return NoEdge//无回路

MinOut[i] = Min/*顶点i的最小出边费用*/

MinSum += Min/*最小出边费用的总和*/

}

MinHeapNode *E = 0

E = (MinHeapNode*)malloc(sizeof(MinHeapNode))

E->x = new int[n]

// E.x=new int[n]

for(i = 0i <ni++)

E->x[i] = i + 1

E->s = 0

E->cc = 0

E->rcost = MinSum

E->next = 0//初始化当前扩展节点

int bestc = NoEdge/*记录当前最小值*/

//搜索排列空间树

while(E->s <n - 1)

{//非叶结点

if(E->s == n - 2)

{//当前扩展结点是叶结点的父结点

/*

首先考虑s=n-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]/*更新当前最新费用*/

E->cc = bestc

E->lcost = bestc

E->s++

E->next = NULL

Insert(E)/*将该页节点插入到优先队列中*/

}else

free(E->x)//该页节点不满足条件舍弃扩展结点

}else

{/*产生当前扩展结点的儿子结点

当s<n-2时,算法依次产生当前扩展结点的所有儿子结点。由于当前扩展结点所相应的路径是x[0:s],

其可行儿子结点是从剩余顶点x[s+1:n-1]中选取的顶点x[i],且(x[s],x[i])是所给有向图G中的一条边。

对于当前扩展结点的每一个可行儿子结点,计算出其前缀(x[0:s],x[i])的费用cc和相应的下界lcost。

当lcost<bestc时,将这个可行儿子结点插入到活结点优先队列中。*/

for(i = E->s + 1i <ni++)

if(a[E->x[E->s]][E->x[i]] != NoEdge)

{ /*当前扩展节点到其他节点有边存在*/

//可行儿子结点

int cc = E->cc + a[E->x[E->s]][E->x[i]]/*加上节点i后当前节点路径*/

int rcost = E->rcost - MinOut[E->x[E->s]]/*剩余节点的和*/

int b = cc + rcost//下界

if(b <bestc || bestc == NoEdge)

{//子树可能含最优解,结点插入最小堆

MinHeapNode * N

N = (MinHeapNode*)malloc(sizeof(MinHeapNode))

N->x = new int[n]

for(int j = 0j <nj++)

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 = b/*更新当前下界*/

N->rcost = rcost

N->next = NULL

Insert(N)/*将这个可行儿子结点插入到活结点优先队列中*/

}

}

free(E->x)

}//完成结点扩展

DeleteMin(E)//取下一扩展结点

if(E == NULL)

break//堆已空

}

if(bestc == NoEdge)

return NoEdge//无回路

for(i = 0i <ni++)

v[i + 1] = E->x[i]//将最优解复制到v[1:n]

while(true)

{//释放最小堆中所有结点

free(E->x)

DeleteMin(E)

if(E == NULL)

break

}

return bestc

}

int main()

{

n = 0

int i = 0

FILE *in, *out

in = fopen("input.txt", "r")

out = fopen("output.txt", "w")

if(in == NULL || out == NULL)

{

printf("没有输入输出文件\n")

return 1

}

fscanf(in, "%d", &n)

a = (int**)malloc(sizeof(int*) * (n + 1))

for(i = 1i <= ni++)

{

a[i] = (int*)malloc(sizeof(int) * (n + 1))

}

for(i = 1i <= ni++)

for(int j = 1j <= nj++)

fscanf(in, "%d", &a[i][j])

// prev = (int*)malloc(sizeof(int)*(n+1))

int*v = (int*)malloc(sizeof(int) * (n + 1))// MaxLoading(w , c , n)

for(i = 1i <= ni++)

v[i] = 0

bestc = BBTSP(v)

for(i = 1i <= ni++)

fprintf(stdout, "%d\t", v[i])

fprintf(stdout, "\n")

fprintf(stdout, "%d\n", bestc)

return 0

}