initial commit

This commit is contained in:
Paul 2020-11-10 19:02:31 +01:00
commit f06f678077

320
03_Suche_BFS_DFS.ipynb Normal file
View File

@ -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
}