斯坦福 Algorithms: Design and Analysis 2 第五周作业
来自斯坦福网站的Algorithms: Design and Analysis,与目前coursera上的版本内容没有变化,不过时间安排略有不同。
1. Problem Set 5
2. Programming Assignment 5
旅行商问题的实现:
代码如下:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <fstream>
#include <sstream>
#include <set>
#include <cmath>
#include <string>
#include <ctime>
#include <algorithm>
using namespace std;
#define INT_MAX 2147483647
void readGraph(string fileName, vector<vector<double>>&G) {
cout << "read data from "<< fileName <<endl;
ifstream input(fileName);
string line;
int size;
double x,y;
input >> size ;
while(input >> x) {
input >> y;
G.push_back({x,y});
}
}
unordered_set<int> nextSets(unordered_set<int> s) {
unordered_set<int> res;
for(int x : s) {
for(int i = 0; i < 25; i++) {
if((x&(0x1 << i)) == 0)
res.insert((x|(0x1<<i)));
}
}
return res;
}
double distance(vector<double>& v1, vector<double>& v2) {
return sqrt(pow(v1[0]-v2[0],2)+pow(v1[1]-v2[1],2));
}
double tsp(vector<vector<double>>& G) {
vector<vector<double>> dp((0x1<<25),vector<double>(25,10000000));
vector<vector<double>> paths((0x1<<25),vector<double>(25,-1));
unordered_set<int> s = {1};
dp[1][0] = 0;
paths[1][0] = 0;
for(int m = 2; m <= 25; m++) {
cout << m << endl;
s = nextSets(s);
cout << "set size: "<< s.size()<<endl;
for(int state : s) {
for(int j = 1; j < 25; j++)
if((state&(0x1<<j))) {
for(int k = 0; k < 25; k++)
if(k != j && (state&(0x1<<k))){
double d = dp[(state^(0x1<<j))][k]+distance(G[k],G[j]);
if(d <= dp[state][j]){
dp[state][j] = d;
paths[state][j] = k;
}
}
}
}
}
double res = 100000000;
int state = 0x1ffffff;
int f = -1;
for(int i = 1; i < 25; i++){
double d = dp[state][i]+distance(G[0],G[i]);
if(d <= res){
res = d;
f = i;
}
}
double cost = 0;//以下是最短路径的重建
int last = 0;
for(int i = 0; i < 25; i++) {
cout <<"last: "<<last<<" state: "<<hex<<state<<" cur: "<<dec<< f << endl;
cost += distance(G[f],G[last]);
last = f;
f = paths[state][f];
state = (state ^ (0x1 << last));
}
cout << "cost: "<< cost << endl;
return res;
}
int main() {
vector<vector<double>> G;
string fileName = "tsp.txt";
readGraph(fileName,G);
double res = tsp(G);
cout << "the result is: "<<res<<endl;
return 0;
}```
需要注意的部分就是使用了一个整数作为已路过的结点的状态,第0位到第24位取0或1代表是否包含改点。