算法实验2-1
TSP问题
算法实验二第一题,动态规划处理tsp问题,要求:从任意城市出发,走过所有城市再回到出发点,求最短路径,
2021.5.12. 0:31分
正在学习实现问题要求ing
代码已经解决从0点出发,回到0点的最短路径,明天接着写,困了睡觉嘻嘻
(这个还要交实验报告,老师应该不查重吧,版权还是自个儿的,不可能自己抄自己么)
2021.5.12. 14:21
上午第二节没课,写了一个小时,下午再写一小时完成实验
//TSP问题
#include<bits/stdc++.h>
using namespace std;
//二进制运算,生成子集
vector<int> print_subset(int n, int s,int c)
{
vector<int> exchange;
for (int i = 0; i < n ; i++)
{
if (s & (1 << i))
{
if (i == c)
{
exchange.clear();
break;
}
else
{
exchange.push_back(i);
}
}
}
return exchange;
}
//判断数字n是否存在于vector数组w中
bool search_i(vector<int> w, int n)
{
bool t = false;
for (int i = 0; i < w.size(); i++)
{
if (n == w[i])
{
t = true;
break;
}
}
return t;
}
int road[100][100] = {}; //存输入路径
int value[100][100] = {};//存计算结果的表
int new_road[100][100] = {};//新路径
//存储各个生成子集
struct a {
vector<int> w;
}number[100];
//存储路径
struct b {
vector<int>path;
}num_path[100][100];
int main()
{
vector <int> exchange;
vector <int> index;
int count = 1;
int count2 = 0;
int count3 = 0;
int min = 0;
int n, c;
//输入部分
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{ //if i==j cin>>0
cin >> road[i][j];
}
}
std::cout << "从顶点: ";
std::cin >> c;
std::cout << "出发\n";
//换图
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i == 0 && j==0)
{
new_road[i][j] = road[c][c];
}
else
if (i == c && j == c)
{
new_road[i][j] = road[0][0];
}
else
if (i == 0 && j != 0)
{
if (j == c)
{
new_road[i][j] = road[c][0];
}
else
{
new_road[i][j] = road[c][j];
}
}
else
if(i != 0 && j == 0)
{
if (i == c)
{
new_road[i][j] = road[0][c];
}
else
{
new_road[i][j] = road[i][c];
}
}
else
if (i == c && j != c)
{
if (j == 0)
{
new_road[i][j] = road[0][c];
}
else
{
new_road[i][j] = road[0][j];
}
}
else
if (i != c && j == c)
{
if (i == 0)
{
new_road[i][j] = road[c][0];
}
else
{
new_road[i][j] = road[i][0];
}
}
else
{
new_road[i][j] = road[i][j];
}
}
}
//输出换好的图
cout << "根据出发点调整road路径图,使得出发点c与0全部兑换:\n";
cout << "新图第一行表头实际上对应的原各个点为:\n";
for (int i = 0; i < n; i++)
{
if (i == 0)
cout <<c<< " ";
else
if (i == c)
cout << "0 ";
else
cout << i << " ";
}
cout << endl;
cout << "新图:\n";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d ", new_road[i][j]);
}
cout << endl;
}
//求生成子集
for (int i = 0; i < (1 << n); i++)
{
count2 = 0;
exchange=print_subset(n, i, 0);//取生成子集
while (exchange.empty()==0)//存储生成子集
{
number[count].w.push_back(exchange.back());
exchange.pop_back();
count2++;
}
if (count2!=0)
{
count++;
}
}
cout << "输出生成子集为:\n";
//输出生成子集,查看它们
for (int i = 1; i <= count; i++)
{
for (int j = 0; j < number[i].w.size(); j++)
{
std::cout << number[i].w[j];
}
if (i != count - 1)
{
std::cout << endl;
}
}
//置表,第0列
for (int i = 1; i < n; i++)
{
value[i][0] = new_road[i][0];
}
//置路径表,第0列
for (int i = 1; i < n; i++)
{
num_path[i][0].path.push_back(0);
num_path[i][0].path.push_back(i);
}
int min_x = 0;
int count5 = 0;
int In = 0;
int Jk = 0;
int IJ_count3 = 0;
int change = 0;
//计算表,1 ~ 2^(n-1)-1 列
for (int j = 1; j <= count-1; j++)
{//历遍列,即历遍生成子集,子集里元素:接下来要依次走过并在都走过之后返回0点
for (int i = 1; i < n; i++)
{//历遍行
if (!search_i(number[j].w, i))//该行行数的点不在子集中,可以从该点出发依次走过子集元素,需要计算填表
{
min = 0;
count5 = 0; min_x = 0;
In = 0; Jk = 0; IJ_count3 = 0;
//priority_queue <int, vector<int>, greater<int> > q;//小顶堆升序队列,辅助求最小值
for (int k = 0; k < number[j].w.size(); k++)
{//历遍子集元素
//找count3
if (index.empty() == 0)
{
index.clear();
}
for (int t = 0; t < number[j].w.size(); t++)
{//主要在于求解 value[number[j].w[k][ ? ] 的 " ? " 的内容," ? "为抛去w[k]之后剩余的子集元素集合,该集合由index数组存储
if (number[j].w[t] != number[j].w[k])
{
index.push_back(number[j].w[t]);
}
}
count3 = 0;
while (index.empty() == 0)//计算求解 count3
{
count3 += pow(2,index.back()-1);
index.pop_back();
}
//找最小值
min_x = new_road[i][number[j].w[k]] + value[number[j].w[k]][count3];
if (count5 == 0)
{
min = min_x;
In = i; Jk = number[j].w[k]; IJ_count3 = count3;
}
else
{
if (min_x < min)
{
min = min_x;
In = i; Jk = number[j].w[k]; IJ_count3 = count3;
}
}
count5++;
//q.push(new_road[i][number[j].w[k]] + value[number[j].w[k]][count3]);
}
//处理最短路径的总长度大小
value[i][j] =min;
//处理最短路径的向量解
num_path[i][j].path = num_path[Jk][IJ_count3].path;
//cout << Jk << " " << IJ_count3 << endl;
num_path[i][j].path.push_back(i);
cout<<"表中对应的点坐标: " << i << " " << j << endl;
cout << "对应的片段路径:";
for (int g = num_path[i][j].path.size()-1; g >= 0 ; g--)
{
cout << num_path[i][j].path[g]<<" ";
}
cout << endl;
}
}
}
//计算 第0行,出发点为0时的最短路径长度
int min2 = 0;
int count4 = 0;
vector<int> index2;
int min_x2 = 0;
int count6 = 0;
int In2 = 0;
int Jk2 = 0;
int IJ_count4 = 0;
//priority_queue <int, vector<int>, greater<int> > q_sum;// 辅助计算最小值
for (int j = 1; j < n; j++)
{
if (index2.empty() == 0)
{
index2.clear();
}
for (int t = 0; t <number[count-1].w.size() ; t++)
{
if (number[count-1].w[t]!= j)
{
index2.push_back(number[count-1].w[t]);
}
}
count4 = 0;
while (index2.empty() == 0)
{
count4 += pow(2, index2.back() - 1);
index2.pop_back();
}
//找最小值
min_x2 = new_road[0][j] + value[j][count4];
if (count6 == 0)
{
min2 = min_x2;
In2 = 0; Jk2 = j; IJ_count4 = count4;
}
else
{
if (min_x2 < min2)
{
min2 = min_x2;
In2 = 0; Jk2 = j; IJ_count4 = count4;
}
}
count6++;
}
//处理最短路径的总长度大小
value[0][count - 1] = min2;
//处理最短路径长度的向量解
for (int h = 0; h < num_path[Jk2][IJ_count4].path.size(); h++)
{
num_path[0][count-1].path.push_back(num_path[Jk2][IJ_count4].path[h]);
}
num_path[0][count-1].path.push_back(0);
//输出表
std::cout << " ";
for (int i = 1; i <= count; i++)
{
for (int j = 0; j < number[i].w.size(); j++)
{
printf("%d", number[i].w[j]);
}
std::cout << " ";
}
std::cout << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < count; j++)
{
printf("%9d ", value[i][j]);
}
std::cout << endl;
}
cout << "新图的最短路径如下: \n";
for (int i = num_path[0][count - 1].path.size() - 1; i >= 0; i--)
{
cout << num_path[0][count - 1].path[i] << " ";
}
cout << endl;
//输入的路径图被换过,再换回正确顺序
for (int i = 0; i < num_path[0][count - 1].path.size() ; i++)
{
if (num_path[0][count - 1].path[i] == 0)
{
num_path[0][count - 1].path[i] = c;
}
else
if (num_path[0][count - 1].path[i] == c)
{
num_path[0][count - 1].path[i] = 0;
}
}
//最短路径向量解输出
cout << "实际最短路径如下: \n";
for (int i = num_path[0][count - 1].path.size()-1; i >=0 ; i--)
{
cout << num_path[0][count - 1].path[i]<<" ";
}
}

浙公网安备 33010602011771号