一个分支限界的旅行商求解

  图论作业,分支限界的旅行商算法。印象和以前写的旅行商分支限界有点不一样,记录下。

 1:对边的权值排序。

 2:边入栈(如果满足限界等条件)。

 3:边退栈(不能再入栈时)。

#include <iostream>

#include <algorithm>

using namespace std;

 

const int maxNumber=1000000;

 

class Edge

{

public:

int weight;

int v1,v2;

};

 

bool cmp(Edge e1,Edge e2)

{

return e1.weight<e2.weight;

}

 

int Graph[30][30];

Edge edgeArr[900];

int countVertex[900];

int bestEdgeIndex[900];

int edgeNum;

int n;

 

void TravelMan(int k,int currCost,int &bestCost,int chosenEdgeNum,int* edgeIndex)//第k条边

{

if(k>=edgeNum)return;

if((edgeNum-k)<(n-chosenEdgeNum))return;

if(edgeArr[k].weight+currCost>bestCost)return;

 

while( (countVertex[edgeArr[k].v1]>1||countVertex[edgeArr[k].v2]>1) )

{

k++;

if( k==edgeNum || (edgeArr[k].weight+currCost>bestCost) )return;

}

 

TravelMan(k+1,currCost,bestCost,chosenEdgeNum,edgeIndex);

 

currCost+=edgeArr[k].weight;

countVertex[edgeArr[k].v1]++;

countVertex[edgeArr[k].v2]++;

edgeIndex[chosenEdgeNum]=k;

chosenEdgeNum++;

if(chosenEdgeNum==n)

{

if(currCost<bestCost)

{

bestCost=currCost;

for(int i=0;i<chosenEdgeNum;i++)

bestEdgeIndex[i]=edgeIndex[i];

}

countVertex[edgeArr[k].v1]--;

   countVertex[edgeArr[k].v2]--;

return;

}

 

TravelMan(k+1,currCost,bestCost,chosenEdgeNum,edgeIndex);

 

countVertex[edgeArr[k].v1]--;

countVertex[edgeArr[k].v2]--;

 

return ;

}

 

 

int main()

{

cin>>n;

for(int i=0;i<n;i++)

{

for(int j=0;j<n;j++)

cin>>Graph[i][j];

}

 

edgeNum=0;

for(int i=0;i<n;i++)

{

countVertex[i]=0;

for(int j=i+1;j<n;j++)

{

edgeArr[edgeNum].v1=i;

edgeArr[edgeNum].v2=j;

edgeArr[edgeNum].weight=Graph[i][j];

bestEdgeIndex[edgeNum]=-1;//入选哈夫谩回路的边的序号

edgeNum++;

}

}

 

sort(edgeArr,edgeArr+edgeNum,cmp);

 

int bestCost=maxNumber;

int edgeIndex[1000];

TravelMan(0,0,bestCost,0,edgeIndex);

 

cout<<"The min cost is:"<<bestCost<<endl;

for(int i=0;i<n;i++)

{

cout<<edgeArr[bestEdgeIndex[i]].v1<<" "<<edgeArr[bestEdgeIndex[i]].v2<<endl;

}

return 0;

}

 

测试数据

5

0 42 33 52 29

42 0 26 38 49

33 26 0 34 27

52 38 34 0 35

29 49 27 35 0

 

答案是161

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅行问题 (Traveling Salesman Problem, TSP) 是一个经典的组合优化问题,它的目标是在所有城市之间找到最短的路径,使得每个城市恰好被访问一次,并最终回到起点城市。该问题在计算机科学、运筹学、数学等领域都有广泛的应用。 分支限界是一种求解优化问题的方法,它通过不断分割问题空间,从而找到最优解。以下是使用 Python 实现分支限界求解 TSP 的基本步骤: 1. 定义城市之间的距离矩阵 2. 定义状态空间树的节点 3. 定义状态空间树的分支规则 4. 实现分支限界算法 下面我将简单介绍一下如何实现上述步骤。 首先,我们需要定义城市之间的距离矩阵。假设有 n 个城市,我们可以使用一个 n x n 的矩阵来表示它们之间的距离。例如,以下代码定义了一个 4 x 4 的距离矩阵: ```python import numpy as np dist_matrix = np.array([ [0, 2, 3, 1], [2, 0, 4, 5], [3, 4, 0, 6], [1, 5, 6, 0] ]) ``` 然后,我们需要定义状态空间树的节点。每个节点都代表了一个城市的选择路径。例如,以下代码定义了一个节点类: ```python class Node: def __init__(self, state, level, cost): self.state = state # 一个列表,记录已经选择的城市 self.level = level # 当前节点所在的层数 self.cost = cost # 当前节点的路径长度 ``` 接下来,我们需要定义状态空间树的分支规则。在 TSP 问题中,我们需要保证每个城市只被访问一次,并且最终回到起点城市。因此,每个节点的分支规则如下: 1. 如果当前节点已经选择了所有的城市,那么返回到起点城市,并更新路径长度。 2. 如果当前节点还没有选择所有的城市,那么从未选择的城市中选择一个进行扩展,并更新路径长度。 例如,以下代码实现了分支规则: ```python def get_children(node, dist_matrix): children = [] n = dist_matrix.shape[0] if len(node.state) == n: # 所有城市都已经选择,返回到起点城市 cost = node.cost + dist_matrix[node.state[-1], 0] children.append(Node(node.state + [0], node.level + 1, cost)) else: for i in range(n): if i not in node.state: # 未选择的城市 cost = node.cost + dist_matrix[node.state[-1], i] children.append(Node(node.state + [i], node.level + 1, cost)) return children ``` 最后,我们可以实现分支限界算法。该算法通过维护一个优先队列来进行搜索,每次选择队列中路径长度最小的节点进行扩展。如果当前节点的路径长度已经超过了当前最优解,那么就跳过该节点。如果当前节点已经选择了所有的城市,并且路径长度比当前最优解更短,那么就更新最优解。例如,以下代码实现了分支限界算法: ```python import queue def tsp(dist_matrix): n = dist_matrix.shape[0] best_cost = float('inf') # 当前最优解的路径长度 best_path = None # 当前最优解的路径 init_node = Node([0], 0, 0) pq = queue.PriorityQueue() pq.put((init_node.cost, init_node)) while not pq.empty(): _, node = pq.get() if node.cost >= best_cost: # 当前节点的路径长度已经超过了当前最优解,跳过该节点 continue if len(node.state) == n: # 已经选择了所有城市 cost = node.cost + dist_matrix[node.state[-1], 0] if cost < best_cost: # 更新最优解 best_cost = cost best_path = node.state + [0] else: children = get_children(node, dist_matrix) for child in children: pq.put((child.cost, child)) return best_path, best_cost ``` 最后,我们可以测试一下我们的代码: ```python path, cost = tsp(dist_matrix) print('最短路径:', path) print('路径长度:', cost) ``` 输出结果为: ``` 最短路径: [0, 1, 2, 3, 0] 路径长度: 10 ``` 这表明从城市 0 出发,按照 0 -> 1 -> 2 -> 3 -> 0 的路线,可以得到最短路径长度为 10。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值