From f06f678077acc2c832984e5cba064ae13adb8937 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 10 Nov 2020 19:02:31 +0100 Subject: [PATCH] initial commit --- 03_Suche_BFS_DFS.ipynb | 320 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 03_Suche_BFS_DFS.ipynb diff --git a/03_Suche_BFS_DFS.ipynb b/03_Suche_BFS_DFS.ipynb new file mode 100644 index 0000000..3f5f868 --- /dev/null +++ b/03_Suche_BFS_DFS.ipynb @@ -0,0 +1,320 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "Technische Hochschule Ostwestfalen-Lippe, inIT\n", + "Kurs Künstliche Intelligenz (KI), Wintersemester 2020\n", + "Malte Schmidt, Arbeitsgruppe Diskrete Systeme\n", + "```\n", + "\n", + "# Suchalgorithmen\n", + "\n", + "In diesem Notebook werden die Breiten-, und Tiefensuche implementiert. Literaturreferenzen finden Sie in den Lösungshinweisen.\n", + "\n", + "Führen Sie die folgende Codezelle aus. In der Codezelle wird der Graph aus Aufgabe 3.2 erstellt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Node:\n", + "\n", + " def __init__(self, name, neighbors=None):\n", + " if neighbors:\n", + " self.neighbors = neighbors\n", + " else:\n", + " self.neighbors = set()\n", + " self.name = name\n", + " \n", + " def connect(self, node):\n", + " if node not in self.neighbors:\n", + " self.neighbors.add(node)\n", + " node.connect(self)\n", + " \n", + " def __str__(self):\n", + " return self.name\n", + "\n", + "a, b, c, d, e, f, g, h = Node('A'), Node('B'), Node('C'), Node('D'), Node('E'), Node('F'), Node('G'), Node('H')\n", + "\n", + "a.connect(c)\n", + "a.connect(d)\n", + "\n", + "b.connect(d)\n", + "b.connect(e)\n", + "\n", + "c.connect(d)\n", + "c.connect(f)\n", + "\n", + "d.connect(g)\n", + "\n", + "e.connect(h)\n", + "\n", + "g.connect(h)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Speicher\n", + "Implementieren Sie die für die Tiefen- und Breitensuche benötigten FIFO- und LIFO-Speicher. Eine Übersicht über Methoden von Python-Listen finden sie in der [Pyhton-Dokumentation](https://docs.python.org/3/tutorial/datastructures.html). Implementieren Sie die `__str__`-Methode. Diese Methode gibt einen String zurück. Dieser String soll alle Elemente im Speicher in der richtigen Reihenfolge auflisten. Das Element, dass mit der Methode `pop()` als nächstes zurückgegeben wird, soll am Anfang des Strings stehen. Benutzen Sie für den Namen eines einzelnen Elements `str(item)`. \n", + "\n", + "Die untenstehenden Implementierungen speichern die Speicherinhalte in einer Python-Liste `items`. Auf diese kann mit `self.items` innehalb der Methoden eines Objekts zugegriffen werden.\n", + "\n", + "Die Implementationen unterstützen die von Pyhton-Listen bekannten Operatoren `in` und `not in` und die Python-Funktion `len()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Queue(ABC):\n", + " \"\"\"An abstract base class for a queue implementation.\"\"\"\n", + "\n", + " def __init__(self, items=()):\n", + " self.items = []\n", + " for item in items:\n", + " self.add(item)\n", + "\n", + " @abstractmethod\n", + " def add(self, item):\n", + " \"\"\"Add item to the queue.\"\"\"\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def pop(self):\n", + " \"\"\"Remove and return an item.\"\"\"\n", + " pass\n", + " \n", + " @abstractmethod\n", + " def __str__(self):\n", + " pass\n", + "\n", + " # Support for built-in len() function\n", + " def __len__(self): return len(self.items)\n", + " \n", + " # Support for \"in\" and \"not in\" operations\n", + " def __contains__(self, key):\n", + " return key in self.items\n", + "\n", + "class FIFOQueue(Queue):\n", + " \"\"\"A FIFO queue.\"\"\"\n", + "\n", + " def __init__(self, items=()):\n", + " super().__init__(items)\n", + " \n", + " def add(self, item):\n", + " \"\"\"Add item to the end of the queue.\"\"\"\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + " \n", + " def pop(self):\n", + " \"\"\"Remove item from the front of the queue.\"\"\"\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + " \n", + " def __str__(self):\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + "\n", + "class LIFOQueue(Queue):\n", + " \"\"\"A FIFO queue.\"\"\"\n", + "\n", + " def __init__(self, items=()):\n", + " super().__init__(items)\n", + " \n", + " def add(self, item):\n", + " \"\"\"Add item to the front of the queue.\"\"\"\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + " \n", + " def pop(self):\n", + " \"\"\"Remove item from the front of the queue.\"\"\"\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + " \n", + " def __str__(self):\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Führen Sie nun die folgende Codezelle aus um ihre Implementierung zu testen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "items = ['a', 'b', 'c']\n", + "\n", + "# Test FIFO Queue\n", + "fifo = FIFOQueue(items)\n", + "if fifo.pop() != 'a':\n", + " raise ValueError('Check your FIFOQueue Implementation.')\n", + "fifo.add('d')\n", + "if 'b' not in fifo or 'c' not in fifo or 'd' not in fifo:\n", + " raise ValueError('Check your FIFOQueue Implementation.')\n", + "pattern = re.compile(\"[\\s\\[']*[b][\\s,']*[c][\\s,']*[d][\\s\\]']*\", re.IGNORECASE)\n", + "if not pattern.match(str(fifo)):\n", + " raise ValueError('Check your FIFOQueue Implementation.' +\n", + " ' Your output of the content was ' + str(fifo) +\n", + " ' but something like [B, C, D] is expected.')\n", + "fifo.pop()\n", + "fifo.pop()\n", + "if fifo.pop() != 'd':\n", + " raise ValueError('Check your FIFOQueue Implementation.')\n", + "\n", + "# Test LIFO Queue\n", + "lifo = LIFOQueue(items)\n", + "if lifo.pop() != 'c':\n", + " raise ValueError('Check your LIFOQueue Implementation.')\n", + "lifo.add('d')\n", + "if 'a' not in lifo or 'b' not in lifo or 'd' not in lifo:\n", + " raise ValueError('Check your LIFOQueue Implementation.')\n", + "pattern = re.compile(\"[\\s\\[']*[d][\\s,']*[b][\\s,']*[a]\", re.IGNORECASE)\n", + "if not pattern.match(str(lifo)):\n", + " raise ValueError('Check your LIFOQueue Implementation.'+ \n", + " ' Your output of the content was ' + str(lifo) +\n", + " ' but something like [D, B, A] is expected.')\n", + "lifo.pop()\n", + "lifo.pop()\n", + "if lifo.pop() != 'a':\n", + " raise ValueError('Check your LIFOQueue Implementation.')\n", + "\n", + "print('Your queue implementations seem to work.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Breitensuche\n", + "Implementieren Sie die Breitensuche und benutzen Sie als Speicher ihre `FIFOQueue`-Implementation. \n", + "\n", + "Die schon gesehenen Knoten werden in einem Python-Set gespeichert. Ein Python-Set Objekt stellt die Methode `add(element)` bereit um dem Set ein Element hinzuzufügen. Eine Überprüfung, ob ein Elemnt in einem Set ist kann wie bei Listen mit `in` geschehen.\n", + "\n", + "Eine alphabetisch sortierte Liste aller Nachfolgerknoten eines Knotens `node` kann mit `sorted([node for node in node.neighbors], key=lambda node: node.name)` erstellt werden.\n", + "\n", + "Fügen Sie an geeigneter Stelle die Textausgabe `print(node.name + ' ' + str(frontier))` hinzu, um eine Ausgabe wie in Aufgabe 3.2 zu erhalten." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def breadth_first_search(start_node):\n", + " \"\"\"\n", + " Search the shallowest nodes in the search tree first.\n", + " \"\"\"\n", + " # Setup:\n", + " node = start_node\n", + " frontier = FIFOQueue([node])\n", + " explored = set() # Set of explored nodes\n", + " # Search:\n", + " while frontier:\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + "\n", + "breadth_first_search(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Implementieren Sie die Funktion `graph_search`, die den Typ des Speichers `frontier` als Parameter erhält. Ein Aufruf von `graph_search(a, FIFOQueue)` soll die gleiche Ausgabe wie ein Aufruf von `breadth_first_search(a)` liefern." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def graph_search(start_node, queue_class):\n", + " \"\"\"\n", + " Graph search according to Artificial Intelligence: A Modern Approach, 3ed., by Stuart Russel and Peter Norvig.\n", + " queue_class should be FIFOQueue for Breadth-First-Search and LIFOQueue for Depth-First-Search.\n", + " \"\"\"\n", + " ########################################\n", + " # Your code goes here.\n", + " ########################################\n", + " \n", + "graph_search(a, FIFOQueue)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tiefensuche\n", + "Führen Sie nun eine Tiefensuche mit Hilfe der Funktion `graph_search` und `a` als Startknoten durch und vergleichen Sie die Ausgabe mit den Ergebnissen aus Aufgabe 3.2." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "########################################\n", + "# Your code goes here.\n", + "########################################" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}