Version 1.5 (16/03/2017) Σχολή Τεχνολογικών Εφαρμογών (ΣΤΕΦ) Τμήμα Μηχανικών Πληροφορικής Τ.Ε. Διδάσκων: Γκόγκος Χρήστος Μάθημα: Τεχνητή Νοημοσύνη (εργαστήριο Δ εξαμήνου) Ακαδημαϊκό έτος 2016-2017 εαρινό εξάμηνο ΑΣΚΗΣΕΙΣ ΓΙΑ ΤΟ ΕΡΓΑΣΤΗΡΙΟ 2 Άσκηση 1 Σχεδιάστε στον ακόλουθο χώρο δεξιά το γράφημα που αντιστοιχεί στα παρακάτω δεδομένα. [VERTICES:4] A B C D [EDGES:5] A,B,5 A,C,2 C,B,1 C,D,10 B,D,8 [STRAIGHT_LINE_DISTANCE_TO:D] A,10 B,4 C,8 D,0 toy2_h.txt Άσκηση 2 Για το γράφημα toy1_h.txt με τα ακόλουθα δεδομένα να εφαρμοστούν οι αλγόριθμοι HC, BestFS και A* και να συμπληρωθούν οι ακόλουθοι πίνακες για την εύρεση της διαδρομής από την κορυφή A στην κορυφή G. [VERTICES:7] A B C D E F G [EDGES:8] A,B,25 A,D,15 B,C,15 B,E,20 D,C,35 D,F,20 E,F,15 F,G,14 [STRAIGHT_LINE_DISTANCE_TO:G] A,34 B,16 C,12 D,26 E,15 F,10 G,0 toy1_h.txt Για τον αλγόριθμο HC Τρέχουσα Κατάσταση Παιδιά 1
Για τον αλγόριθμο ΒestFS Για τον αλγόριθμο A* Άσκηση 3 Γράψτε πρόγραμμα που να εκτυπώνει όλες τις πόλεις οι οποίες αν χρησιμοποιηθούν στην αναρρίχηση λόφου ως αφετηρίες στο πρόβλημα tour_romania με προορισμό την πόλη B (Bucharest) οδηγούν σε αδιέξοδο. Άσκηση 4 Τροποποιήστε τον αλγόριθμο Α* έτσι ώστε να μην χρησιμοποιεί κλειστό σύνολο. Χρησιμοποιήστε και τους δύο αλγορίθμους Α* (με κλειστό σύνολο και χωρίς κλειστό σύνολο) έτσι ώστε να βρεθεί η συντομότερη διαδρομή από την κορυφή Α στην κορυφή D στο γράφημα της Άσκησης 1 (toy2_h.txt). Συμπληρώστε τους ακόλουθους πίνακες. Τι παρατηρείτε; Για τον αλγόριθμο A* (με κλειστό σύνολο) Για τον αλγόριθμο A* (χωρίς κλειστό σύνολο) Μέτωπο αναζήτησης Τρέχουσα Κατάσταση Παιδιά 2
ΛΥΣΕΙΣ ΑΣΚΗΣΕΩΝ Άσκηση 1 [VERTICES:4] A B C D [EDGES:5] A,B,5 A,C,2 C,B,1 C,D,10 B,D,8 [STRAIGHT_LINE_DISTANCE_TO:D] A,10 B,4 C,8 D,0 Άσκηση 2 Για τον αλγόριθμο HC Τρέχουσα Κατάσταση (Α,34) (B,16) (C,12) αδιέξοδο (B,16),(D,26) (C,12),(E,15) Παιδιά Για τον αλγόριθμο ΒestFS [(Α-34)] Α [B,D] [(A-B,16),(A-D,26)] [A] B [C,E] [(A-B-C,12),(A-B-E,15),(A-D,26)] [A,B] C [(A-B-E,15),(A-D,26)] [A,B,C] E [F] [(A-B-E-F,10),(A-D,26)] [A,B,C,E] F [G] [(A-B-E-F-G,0),(A-D,26)] [A,B,C,E,F] G A-B-E-F-G,74 Για τον αλγόριθμο A* [(Α,0+34=34)] Α [B,D] [(Α-Β,25+16=41), (A-D,15+26=41)] [A] B [C,E] [(A-D,15+26=41), (Α-Β-C,40+12=52), (A-B-E,45+15=60)] [A,B] D [C,F] [(A-D-F,35+10=45), (A-B-C,40+12=52), (A-B-E 45+15=60), [A,B,D] F G (A-D-C,50+12=62)] (A-D-F-G,49+0=49), (A-B-C,40+12=52), (A-B-E,45+15=60), [A,B,D,F] G (A-D-C 50+12=62) A-D-F-G,49 Άσκηση 3 #include "lab02_search.hpp" #include <stdlib.h> bool hill_climbing_base(struct di_graph graph, string start_vertex, string goal_vertex) { 3
string current_state = start_vertex; while (goal_vertex.compare(current_state)!= 0) { list<string> children = get_successors(graph, current_state); if (children.empty()) return false; string best_child = children.front(); for (string v : children) { if (get_heuristic(graph, v) < get_heuristic(graph, best_child)) best_child = v; if (get_heuristic(graph, best_child) < get_heuristic(graph, current_state)) current_state = best_child; else return false; return true; int main(int argc, char **argv) { struct di_graph graph { ; graph = read_data("data/tour_romania_h.txt"); for (int i = 0; i < graph.v; i++) { string source_vertex{get_vertex_label(graph, i); bool flag = hill_climbing_base(graph, source_vertex, graph.goal_vertex); if (!flag) cout << "source: " << source_vertex << " destination: " << graph.goal_vertex << " DEADLOCK"<< endl; free_memory(graph); lab02_exercise03.cpp Ο κώδικας μεταγλωττίζεται με την ακόλουθη εντολή: g++ lab02_exercise03.cpp lab02_graph.cpp lab02_search.cpp -o lab02_exercise03 -std=c++11 Η εκτέλεση του κώδικα γίνεται ως εξής:./lab02_exercise03 source: L destination: B DEADLOCK source: M destination: B DEADLOCK source: T destination: B DEADLOCK Άσκηση 4 #include "lab02_search.hpp" #include <stdlib.h> void print_status_astar_without_closed_set(list<search_node> frontier, string current_state, list<string> successors) { cout << "frontier:["; for (search_node sn : frontier) cout << search_node_astar_as_string(sn); cout << "]"; cout << " current node:" << current_state; cout << " successors:" << list_as_string(successors) << endl; 4
void alpha_star_search_without_closed_set(struct di_graph graph, string start_vertex, string goal_vertex) { cout << "A* no closed set" << endl; priority_queue<search_node> frontier { ; frontier.push( to_search_node(start_vertex, get_heuristic(graph, start_vertex))); search_node current_state = frontier.top(); string current_state_back = current_state.path.back(); bool found { true ; while (goal_vertex.compare(current_state_back)!= 0) { print_status_astar_without_closed_set(priority_queue_to_list(frontier), current_state_back, get_successors(graph, current_state_back)); frontier.pop(); for (string v : get_successors(graph, current_state_back)) frontier.push( to_search_node(graph, current_state, v, get_heuristic(graph, v))); if (frontier.empty()) { found = false; break; current_state = frontier.top(); current_state_back = current_state.path.back(); if (found) { print_status_astar_without_closed_set(priority_queue_to_list(frontier), current_state_back, get_successors(graph, current_state_back)); cout << "Path to goal node found: " << solution_path_cost(graph, current_state) << endl; else cout << "Goal not found!" << endl; int main(int argc, char **argv) { struct di_graph graph { ; string fn{; string start_vertex{, search_method{; if (argc!= 3) { printf("wrong number of arguments\n"); printf("usage : %s <problem_instance> <source>\n", argv[0]); printf("example : %s tour_romania_h.txt A \n", argv[0]); exit(-1); fn = argv[1]; start_vertex = argv[2]; graph = read_data(fn); cout << "Origin: " << start_vertex << " destination: " << graph.goal_vertex << endl; alpha_star_search(graph, start_vertex, graph.goal_vertex); alpha_star_search_without_closed_set(graph, start_vertex, graph.goal_vertex); free_memory(graph); 5
lab02_exercise04.cpp Ο κώδικας μεταγλωττίζεται με την ακόλουθη εντολή: g++ lab02_exercise04.cpp lab02_graph.cpp lab02_search.cpp -o lab02_exercise04 -std=c++11 Η εκτέλεση του κώδικα γίνεται ως εξής:./lab02_exercise04 data\toy2_h.txt A Origin: A destination: D A* frontier:[(a 0+10=10)] closed set:[] current node:a successors:[b C] frontier:[(a-b 5+4=9)(A-C 2+8=10)] closed set:[a] current node:b successors:[d] frontier:[(a-c 2+8=10)(A-B-D 13+0=13)] closed set:[a B] current node:c successors:[b D] frontier:[(a-c-b 3+4=7)(A-C-D 12+0=12)(A-B-D 13+0=13)] closed set:[a B C] current node:b successors:[loop] frontier:[(a-c-d 12+0=12)(A-B-D 13+0=13)] closed set:[a B C] current node:d successors:[] Path to goal node found: (A-C-D 12) A* no closed set frontier:[(a 0+10=10)] current node:a successors:[b C] frontier:[(a-b 5+4=9)(A-C 2+8=10)] current node:b successors:[d] frontier:[(a-c 2+8=10)(A-B-D 13+0=13)] current node:c successors:[b D] frontier:[(a-c-b 3+4=7)(A-C-D 12+0=12)(A-B-D 13+0=13)] current node:b successors:[d] frontier:[(a-c-b-d 11+0=11)(A-C-D 12+0=12)(A-B-D 13+0=13)] current node:d successors:[] Path to goal node found: (A-C-B-D 11) Για τον αλγόριθμο A* (με κλειστό σύνολο) [(A,0+10=10)] Α B C [(A-B 5+4=9), (A-C 2+8=10)] [A] B D [(A-C 2+8=10), (A-B-D 13+0=13)] [A B] C B D [(A-C-B 3+4=7), (A-C-D 12+0=12), (A-B-D 13+0=13)] [A B C] B βρόχος [(A-C-D 12+0=12), (A-B-D 13+0=13)] [A B C] D A-C-D, 12 Για τον αλγόριθμο A* (χωρίς κλειστό σύνολο) Μέτωπο αναζήτησης Τρέχουσα Κατάσταση Παιδιά [(A,0+10=10)] A B,C [(A-B,5+4=9), (A-C,2+8=10)] B D [(A-C,2+8=10), (A-B-D,13+0=13)] C B,D [(A-C-B 3+4=7), (A-C-D,12+0=12), (A-B-D,13+0=13)] B D [(A-C-B-D,11+0=11), (A-C-D,12+0=12), (A-B-D,13+0=13)] D A-C-B-D, 11 Στο συγκεκριμένο πρόβλημα οι δύο αλγόριθμοι δεν επιστρέφουν το ίδιο αποτέλεσμα. Ο αλγόριθμος Α* με το κλειστό σύνολο δεν επιστρέφει τη βέλτιστη τιμή ενώ ο Α* χωρίς κλειστό σύνολο την επιστρέφει. Αυτό συμβαίνει διότι το γράφημα δεν είναι συνεπές. 6