分支限界解决TSP算法
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <omp.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <limits>
#include <queue>
#include <array>
#include <algorithm>
#include <numeric>
#include <set>
#define INVALID_VALUE 0
int times = 0;
int N;
int up_bound = INT_MAX;
int low_bound = INT_MAX;
int** adj;
std::vector<std::pair<int, int>> shortRoadVec;
std::vector<int> lowBoundVec;
std::vector<int> greedyPath;
std::set<int> remaind;
const int INF = std::numeric_limits<int>::max();
struct node
{
int row;
int cost;
bool visit;
std::vector<int> path; // 记录节点的路径
node()
{
row = 0;
cost = 0;
visit = false;
path.clear();
}
struct Compare
{
bool operator()(const node& n1, const node& n2)
{
return n1.cost > n2.cost;
}
};
};
class selectedArray
{
std::vector<int> array;
public:
selectedArray()
{
array.clear();
}
void add(int in)
{
array.push_back(in);
}
void remove(int in)
{
auto it = std::find(array.begin(), array.end(), in);
if (it != array.end())
{
array.erase(it);
}
}
bool isHave(int in)
{
auto it = std::find(array.begin(), array.end(), in);
if (it != array.end())
{
return true;
}
return false;
}
int size()
{
return array.size();
}
int back()
{
return array.back();
}
};
class BABnode
{
public:
int num;
int level;
std::vector<int> path;
int length;
int low_b;
int finish_dis = 0;
int remaind_dis = 0;
std::set<int> finish_city;
std::set<int> remaind_city;
BABnode()
{
num = 0;
level = 0;
path.clear();
length = 0;
low_b = 0;
finish_dis = 0;
remaind_dis = 0;
finish_city.clear();
remaind_city.clear();
}
BABnode(int num, int level, std::vector<int> path, int length, int low_b, std::set<int> finish_city,
std::set<int> remaind_city)
: num(num)
, level(level)
, path(path)
, length(length)
, low_b(low_b)
, finish_city(finish_city)
, remaind_city(remaind_city)
{
;
}
bool operator<(const BABnode& other) const
{
return low_b > other.low_b; // 以小到大的顺序进行比较
}
};
// 旅行商问题的求上界函数
int getUpperBound(std::vector<std::priority_queue<node, std::vector<node>, node::Compare>> graph, int first)
{
// 待选行
selectedArray selected_array;
for (int i = 0; i < graph.size(); i++)
{
selected_array.add(i);
}
// 取第一行最小代价
node min_node;
int upperBound = 0;
int next = first;
// std::cout << " 下一行取 " << next << std::endl;
for (int i = 0; i < graph.size(); i++)
{
while (1)
{
min_node = graph.at(next).top();
if (selected_array.isHave(min_node.row) && min_node.cost > 0)
{
upperBound += min_node.cost;
greedyPath.push_back(next);
selected_array.remove(next);
next = min_node.row;
break;
}
else if (selected_array.size() <= 1)
{
std::cout << " 搜完!!" << std::endl;
break;
}
else if (selected_array.size() > 1 && graph.at(next).size() <= 0)
{
std::cout << " 路径不闭环" << std::endl;
return 0;
}
else
{
graph.at(next).pop();
}
}
}
// std::cout << " 最后一个 = " << selected_array.back() << std::endl;
upperBound += adj[selected_array.back()][first];
return upperBound;
}
void getLowBound(std::vector<std::priority_queue<node, std::vector<node>, node::Compare>> map)
{
low_bound = 0;
for (auto A : map)
{
while (1)
{
if (A.size() < 2)
{
break;
}
else if (A.top().cost != INVALID_VALUE)
{
std::pair<int, int> short_path;
short_path.first = A.top().cost;
A.pop();
short_path.second = A.top().cost;
shortRoadVec.push_back(short_path);
int tmp = (short_path.first + short_path.second);
low_bound += tmp;
lowBoundVec.push_back(tmp);
break;
}
else
{
A.pop();
}
}
}
low_bound = low_bound & 1 ? low_bound / 2 + 1 : low_bound / 2;
}
int getNodeLowBound(BABnode in, int next, std::vector<std::pair<int, int>> shortRoadVec)
{
int last = in.path.back();
int tmp = adj[last][next];
int result = in.low_b * 2;
if (in.path.size() == 1) // 改变四个变量 v0firstMin , v0secMin ,v1firstmin , v1secMin变成v0Min , v01 ,v1min , v10
{
// 求v0firstMin shortRoadVec.at(last).first
// 求v0secMin shortRoadVec.at(last).second
// 求v1firstmin shortRoadVec.at(next).first
// 求v1secMin shortRoadVec.at(next).second
// 求v01
int V01 = adj[last][next];
// 求v0Min
int V0min = 0;
if (V01 != shortRoadVec.at(last).first)
{
V0min = shortRoadVec.at(last).first;
}
else
{
V0min = shortRoadVec.at(last).second;
}
// 求v10
int V10 = adj[next][last];
// 求v1Min
int V1min = 0;
if (V10 != shortRoadVec.at(next).first)
{
V1min = shortRoadVec.at(next).first;
}
else
{
V1min = shortRoadVec.at(next).second;
}
result = result - shortRoadVec.at(last).first - shortRoadVec.at(last).second - shortRoadVec.at(next).first -
shortRoadVec.at(next).second;
result = result + V01 + V0min + V10 + V1min;
}
else // 改变三个变量 v1Min ,v2firstmin , v2secMin变成v12 , v21 ,v2min
{ // 求v1Min
int V1min = 0;
int last_last = in.path.at(in.path.size() - 2);
if (adj[last_last][last] != shortRoadVec.at(last).first)
{
V1min = shortRoadVec.at(last).first;
}
else
{
V1min = shortRoadVec.at(last).second;
}
// 求v2firstmin shortRoadVec.at(next).first;
// 求 v2secMin shortRoadVec.at(next).second;
// 求 v12
int V12 = adj[last][next];
// 求 v21
int V21 = adj[next][last];
// 求 v2min
int V2min = 0;
if (V21 != shortRoadVec.at(next).first)
{
V2min = shortRoadVec.at(next).first;
}
else
{
V2min = shortRoadVec.at(next).second;
}
result = result - V1min - shortRoadVec.at(next).first - shortRoadVec.at(next).second;
result = result + V12 + V21 + V2min;
}
if (result / 2 < in.low_b)
{
std::cout << result / 2 << " 出现了异常 " << in.low_b << " \n ";
}
return result / 2;
}
BABnode TSPBranchAndBound(int** graph, BABnode startNode, int n)
{
std::priority_queue<BABnode> activeNodes;
activeNodes.push(startNode);
BABnode CurrentNode, result;
while (!activeNodes.empty())
{
CurrentNode = activeNodes.top();
activeNodes.pop();
// 找到了全部路径,更新上界
if (CurrentNode.level == n - 1)
{
int length = CurrentNode.length + graph[CurrentNode.path.back()][CurrentNode.path.front()];
if (length <= up_bound)
{
up_bound = length;
result = CurrentNode;
result.length = length;
// return result;
}
}
else
{
for (auto i : CurrentNode.remaind_city)
{
int node_low_bound = getNodeLowBound(CurrentNode, i, shortRoadVec);
BABnode tmp = CurrentNode;
if (node_low_bound <= up_bound)
{
tmp.low_b = node_low_bound;
tmp.length += graph[CurrentNode.path.back()][i];
tmp.path.push_back(i);
tmp.remaind_city.erase(i);
tmp.finish_city.insert(i);
tmp.level++;
activeNodes.push(tmp);
}
}
}
}
return result;
}
int main(int argv, char* argc[])
{
std::vector<std::priority_queue<node, std::vector<node>, node::Compare>> graph_vec;
int n;
std::cin >> n;
for (int i = 1; i < n; i++)
{
remaind.insert(i);
}
int* data = (int*)malloc(n * n * sizeof(int));
adj = (int**)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
adj[i] = &(data[i * n]);
N = n;
for (int i = 0; i < n; i++)
{
std::priority_queue<node, std::vector<node>, node::Compare> tmp_vec;
struct node tmp_node;
for (int j = 0; j < n; j++)
{
scanf("%d", &adj[i][j]);
tmp_node.cost = adj[i][j];
tmp_node.row = j;
tmp_node.visit = false;
if (tmp_node.cost != INVALID_VALUE)
tmp_vec.push(tmp_node);
}
graph_vec.push_back(tmp_vec);
}
// std::vector<int> input;
// int tmp = 0;
// for (int i = 0; i < n; i++)
// {
// scanf("%d", &tmp);
// input.push_back(tmp);
// }
// int sum = 0;
// for (int i = 0; i < n - 1; i++)
// {
// sum += adj[input.at(i)][input.at(i + 1)];
// }
// sum += adj[input.at(n - 1)][input.at(0)];
// std::cout << " 计算得的总代价 = " << sum << std::endl;
for (int i = 0; i < graph_vec.size(); i++)
{
up_bound = std::min(up_bound, getUpperBound(graph_vec, i));
std::cout << "上界 = " << up_bound << std::endl;
}
getLowBound(graph_vec);
std::cout << "下界 = " << low_bound << std::endl;
BABnode start_node(0, 0, { 0 }, 0, low_bound, std::set<int>(), remaind);
BABnode result = TSPBranchAndBound(adj, start_node, n);
printf("Minimum cost : %d\n", result.length);
printf("Path Taken : ");
for (int i = 0; i < N; i++)
printf("%d ", result.path[i]);
free(data);
free(adj);
return 0;
}