人工智能导论实验一

#include<iostream>
#include<vector>
#include<unordered_map>
#include<string>
#include<queue>
#include<utility>
#include<fstream>
#include<algorithm>
#define pii pair<int, int>
using namespace std;
unordered_map<string, int> idmap;//记录地名的编号
unordered_map<int, string> namemap;//记录相应编号的地名
struct Node{//树结点
    int id;//结点编号
    string name;//结点地名
    Node* father;
    vector<Node*>child;//子结点
    vector<int> dist;//到子结点的距离
    //int g, h;//代价函数g, 评估函数h
    Node(){
    }
    Node(int i, string name0) {
        id = i; name = name0;// g = g0; h = h0;
    }
};
int locality_num, side_num;
//求启发函数值
void calculate_h(vector<vector<pii>>& graph, vector<int>& h, vector<bool>& visited)
{
    priority_queue<pii,vector<pii>, greater<pii>> q;
    q.push({0, idmap["Bucharest"]});//以Bucharset目标结点用dijdrik算法求其他结点的最短距离,做启发函数值
    while(! q.empty()) {
        pii node = q.top();
        q.pop();
        if (visited[node.second]) continue;
        visited[node.second] = true;
        int nlen = graph[node.second].size();
        for (int i = 0; i < nlen; i ++) {
            pii v = graph[node.second][i];
            if(node.first + v.second < h[v.first]) {
                h[v.first] = node.first + v.second;
                q.push({h[v.first], v.first});
            }
        }
    }
}

//深搜建树
void createTree(Node* root, vector<bool>& visited, vector< vector<pii> >& graph)
{
    for(int i = 0; i < graph[root->id].size(); i ++) {//深搜建树
        if(visited[graph[root->id][i].first]) continue;
        root->child.push_back(nullptr);
        root->child[root->child.size() - 1] = new Node(graph[root->id][i].first, namemap[graph[root->id][i].first]);
        root->child[root->child.size() - 1]->father = root;
        visited[graph[root->id][i].first] = true;
        root->dist.push_back(graph[root->id][i].second);
        createTree(root->child[root->child.size() - 1], visited, graph);
        visited[graph[root->id][i].first] = false;
    }
}
void display(Node* root)
{
    queue<Node*> q;
    q.push(root);
    cout<<root->name<<endl;
    while(! q.empty()) {
        Node *node0 = q.front();
        q.pop();
        cout<<node0->name<<"的子结点:";
        for(auto& v:node0->child){
            cout<<v->name<<' ';
            q.push(v);
        }
        cout<<endl<<endl;;
    }
}

//深度优先搜索
int dfs(Node* root, int dist, vector<string>& path)
{
    path.push_back(root->name);
    if(root->name == "Bucharest") return dist;
    for(int i = 0; i < root->child.size(); i ++) {
        int res = dfs(root->child[i], dist + root->dist[i], path);
        if (res)
            return res;
    }
    path.pop_back();
    return 0;
}

//宽度优先搜索
int bfs(Node* root, vector<string>& path)
{
    queue<pair<Node*, int>> q;
    q.push({root, 0});
    while(! q.empty()) {
        Node* node = q.front().first;
        int dist = q.front().second;
        if (node->name == "Bucharest") {//找到目标结点
            while(node->father != nullptr) {
                path.push_back(node->name);
                node = node->father;
            }
            path.push_back(node->name);
            reverse(path.begin(), path.end());
            return dist;
        }
        q.pop();
        for(int i = 0; i < node->child.size(); i ++) {
            q.push({node->child[i], node->dist[i] + dist});
        }
    }
}

//一致代价搜索
int costSearch(Node* root, vector<string>& path)
{
    priority_queue<pair<int, Node*>, vector<pair<int, Node*> >, greater<pair<int, Node*> > > q;//最小优先队列
    q.push({0, root});
    while(! q.empty()) {
        Node* node = q.top().second;
        int dist = q.top().first;
        if (node->name == "Bucharest") {//找到目标结点
            while(node->father != nullptr) {
                path.push_back(node->name);
                node = node->father;
            }
            path.push_back(node->name);
            reverse(path.begin(), path.end());
            return dist;
        }
        q.pop();
        for(int i = 0; i < node->child.size(); i ++) {
            q.push({node->dist[i] + dist, node->child[i]});
        }
    }
}

//迭代加深的深搜
int dfsid(Node* root, int dist,queue<pair<int, Node*> >&endnode, vector<string>& path, int deep, int max_deep)
{

    if(root->name == "Bucharest") {
        while (root->father != nullptr) {
            path.push_back(root->name);
            root = root->father;
        }
        path.push_back(root->name);
        reverse(path.begin(), path.end());
        return dist;
    }
    if(deep >= max_deep) {
        endnode.push({dist, root});
        return 0;
    }
    for(int i = 0; i < root->child.size(); i ++) {
        int res = dfsid(root->child[i], dist + root->dist[i], endnode, path, deep + 1, max_deep);
        if (res)
            return res;
    }
    return 0;
}

//贪婪最佳优先
int gree_search(Node* root, vector<string>& path, vector<int>& h)
{
    priority_queue<pair<int, Node*>, vector<pair<int, Node*> >, greater<pair<int, Node*> > > q;//最小优先队列
    q.push({0, root});
    while(! q.empty()) {
        Node* node = q.top().second;
        int dist = q.top().first;
        if (node->name == "Bucharest") {//找到目标结点
            while(node->father != nullptr) {
                path.push_back(node->name);
                node = node->father;
            }
            path.push_back(node->name);
            reverse(path.begin(), path.end());
            return dist;
        }
        q.pop();
        for(int i = 0; i < node->child.size(); i ++) {
            q.push({h[idmap[node->child[i]->name]], node->child[i]});
        }
    }
}

//A*搜索
int A_search(Node* root, vector<string>& path, vector<int>& h)
{
    priority_queue<pair<int, Node*>, vector<pair<int, Node*> >, greater<pair<int, Node*> > > q;//最小优先队列
    q.push({h[idmap[root->name]], root});
    while(! q.empty()) {
        Node* node = q.top().second;
        int dist = q.top().first - h[idmap[node->name]];
        if (node->name == "Bucharest") {//找到目标结点
            while(node->father != nullptr) {
                path.push_back(node->name);
                node = node->father;
            }
            path.push_back(node->name);
            reverse(path.begin(), path.end());
            return dist;
        }
        q.pop();
        for(int i = 0; i < node->child.size(); i ++) {
            q.push({h[idmap[node->child[i]->name]] + dist + node->dist[i], node->child[i]});
        }
    }
}
int main()
{
    fstream fcin;
    fcin.open("datain.txt",ios::in);
    fcin>>locality_num>>side_num;
    string start_locality = "Arad";
    vector<Node*> node(locality_num, nullptr);
    for (int i = 0; i < locality_num; i ++) {
        string locality_name;
        fcin>>locality_name;
        idmap[locality_name] = i;
        namemap[i] = locality_name;
        node[i] = new Node(i, locality_name);
    }
    vector< vector<pii> > graph(locality_num, vector<pii>());
    for (int j = 0; j < side_num; j ++) {//存储图
        string u, v;
        int w;
        fcin>>u>>v>>w;
        graph[idmap[u]].push_back({idmap[v], w});
        graph[idmap[v]].push_back({idmap[u], w});
    }
    vector<int> h(locality_num, 0x3f3f3f3f);//评估函数
    vector<bool> visited(locality_num, false);
    h[idmap["Bucharest"]] = 0;
    calculate_h(graph, h, visited);//计算评估函数,可为每个点到目标结点的最短距离
    for (int i = 0; i < locality_num; i ++) {
        //cout<<namemap[i]<<":"<<h[i]<<' ';
        visited[i] = false;
    }
    Node* root = new Node(idmap[start_locality],start_locality );
    visited[root->id] = true;
    root->father = nullptr;
    createTree(root, visited, graph);//建树
    display(root);//输出树
    //深搜
    vector<string> dfspath;
    int dfsres = dfs(root, 0, dfspath);
    cout<<"深度优先路径";
    for(auto&v:dfspath){
        cout<<v<<' ';
    }cout<<endl;
    cout<<"深度优先结果"<<dfsres<<endl;
    //宽搜
    vector<string> bfspath;
    int bfsres = bfs(root, bfspath);
    cout<<"宽度优先路径";
    for(auto&v:bfspath){
        cout<<v<<' ';
    }cout<<endl;
    cout<<"宽度优先结果"<<bfsres<<endl;
    //一致代价搜索
    vector<string> costSearch_path;
    int costSearch_res = costSearch(root, costSearch_path);
    cout<<"一致代价搜索路径";
    for(auto&v:costSearch_path){
        cout<<v<<' ';
    }cout<<endl;
    cout<<"一致代价搜索结果"<<costSearch_res<<endl;
    //迭代加深的深搜
    queue<pair<int, Node*> >endnode;
    int max_dep = 5;
    vector<string> dfsidPath;
    endnode.push({0, root});
    int dfsidres = 0;
    while(! dfsidres) {
        dfsidres = dfsid(endnode.front().second, endnode.front().first, endnode, dfsidPath, 0, max_dep);
        endnode.pop();
    }
    cout<<"迭代加深深度优先路径";
    for(auto&v:dfsidPath){
        cout<<v<<' ';
    }cout<<endl;
    cout<<"迭代加深深度优先结果"<<dfsidres<<endl;
    //贪婪最佳优先搜索
    vector<string> gree_search_path;
    int gree_search_res = gree_search(root, gree_search_path, h);
    cout<<"贪婪最佳优先搜索路径";
    for(auto&v:gree_search_path){
        cout<<v<<' ';
    }cout<<endl;
    //A*
    vector<string> A_path;
    int A_res = A_search(root, A_path, h);
    cout<<"A*搜索路径";
    for(auto&v:A_path){
        cout<<v<<' ';
    }cout<<endl;
    cout<<"A*搜索结果"<<A_res<<endl;
}
 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值