Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

12/9宿題 #358

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions 20151209/src/enshu_20151209/data/romania2.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Romanian Cities and Road Network Graph
# (See Russell & Norvig Chapter 3 )
#
Oradea 380 Zerind 71 Sibiu 151
Arad 366 Zerind 75 Sibiu 140 Timisoara 118
Zerind 374 Arad 75 Oradea 71
Timisoara 329 Arad 118 Lugoj 111
Sibiu 253 Oradea 151 Arad 140 Fagaras 99 Rimnicu-Vilcea 80
Lugoj 244 Timisoara 111 Mehadia 70
Mehadia 241 Lugoj 70 Dobreta 75
Dobreta 242 Mehadia 75 Craiova 120
Craiova 160 Rimnicu-Vilcea 146 Pitesti 138 Dobreta 120
Pitesti 100 Rimnicu-Vilcea 97 Craiova 138 Bucharest 101
Rimnicu-Vilcea 193 Sibiu 80 Craiova 146 Pitesti 97
Fagaras 176 Sibiu 99 Bucharest 211
Bucharest 0 Fagaras 211 Giurgiu 90 Urziceni 85 Pitesti 101
Giurgiu 77 Bucharest 90
Urziceni 80 Bucharest 85 Hirsova 98 Vaslui 142
Vaslui 199 Iasi 92 Urziceni 142
Iasi 227 Neamt 87 Vaslui 92
Neamt 234 Iasi 87
Hirsova 151 Urziceni 98 Eforie 86
Eforie 161 Hirsova 86
129 changes: 129 additions & 0 deletions 20151209/src/enshu_20151209/src/a_star.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

class city
{
public:
string name;
int dist;
map<string, int> nextto;
int cost = -1;
int checked = 0;
string prev = "";
city(string name, int dist){
this->name = name;
this->dist = dist;
}
~city(){}

void addcity(string nextname, int nextdist){
this->nextto.insert(map<string, int>::value_type(nextname, nextdist));
}

};


void readfile(string src, map<string, city*>& citylist){
ifstream ifs(src.c_str());
string line;
stringstream ssline;
while(ifs && getline(ifs, line)){
if(line.find('#') == 0){
continue;
}
ssline.str("");
ssline.clear(stringstream::goodbit);
ssline.str(line);

stringstream sstmp;
string name;
string nextname;
string tmp;
int dist;
city* citytmp;
getline(ssline, name, ' ');
getline(ssline, tmp, ' ');
sstmp.str(tmp);
sstmp >> dist;
citytmp = new city(name, dist);
while(getline(ssline, nextname, ' ')){
getline(ssline, tmp, ' ');
sstmp.str("");
sstmp.clear(stringstream::goodbit);
sstmp.str(tmp);
sstmp >> dist;
citytmp->addcity(nextname, dist);
}
citylist.insert(pair<string, city*>(name, citytmp));
}
}

city* a_star_search(map<string, city*>& citylist, string startcity){
vector<city*> stack;
city* popcity;
stack.push_back(citylist[startcity]);
citylist[startcity]->checked = 1;
citylist[startcity]->cost = 0;

while(stack.size()){
//A*でソート(評価関数が最小のものを末尾へ)
sort(stack.begin(), stack.end(), [](const city* x, const city* y){return (y->cost + y->dist) -(x->cost + x->dist);});
//スタックの末尾取り出し
popcity = stack.back();
stack.pop_back();
//ゴールかどうかチェック
if(popcity->dist == 0){
return popcity;
}
//周りをスタックに入れる
for(map<string, int>::iterator itr = popcity->nextto.begin(); itr != popcity->nextto.end(); itr++){
if(citylist[itr->first]->checked == 0){
citylist[itr->first]->checked = 1;
citylist[itr->first]->cost = popcity->cost + itr->second;
citylist[itr->first]->prev = popcity->name;
stack.push_back(citylist[itr->first]);
}
}
}
//ゴールを見つける前にスタックが空になった場合
return NULL;
}

void trackback(map<string, city*> citylist, city* goal, string startcity){
vector<city*> route;
city* cityptr = goal;
while(true){
route.push_back(cityptr);
if(cityptr->prev == ""){
break;
}
cityptr = citylist[cityptr->prev];
}
reverse(route.begin(), route.end());

//結果表示
for(vector<city*>::iterator itr = route.begin(); itr != route.end(); itr++){
cout << (*itr)->name << endl;
}
}

int main(){
map<string, city*> citylist;
readfile("../data/romania2.dat", citylist);

string startcity = "Oradea";
city* goal = a_star_search(citylist, startcity);
if(goal == NULL){
cout << "Couldn't find the goal" << endl;
}else{
trackback(citylist, goal, startcity);
}
return 0;
}