斯坦福 算法2 第五周作业

本文介绍了斯坦福大学算法课程的第五周作业,包括Problem Set 5和Programming Assignment 5,主要内容聚焦于旅行商问题的实现,提供了相应的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

斯坦福 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代表是否包含改点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值