From 6910cd1f76623867d9c34e9de9a4327ee6f3cc24 Mon Sep 17 00:00:00 2001 From: Louis Gallet Date: Sat, 14 Dec 2024 13:58:30 +0100 Subject: [PATCH] feat: :sparkles: Upload Notebook --- debug.py | 446 +++++++++++++++++++++++++++++++++++++++++++++++++++ graphs.ipynb | 439 ++++++++++++++++++++++++++------------------------ 2 files changed, 678 insertions(+), 207 deletions(-) create mode 100644 debug.py diff --git a/debug.py b/debug.py new file mode 100644 index 0000000..68779c6 --- /dev/null +++ b/debug.py @@ -0,0 +1,446 @@ +import queue + +# -*- coding: utf-8 -*- +"""Graph module. + +Provide an implementation of graphs with adjacency lists. + +In a graph, vertices are considered numbered from 0 to the order of the graph +minus one. The vertex key can then be used to access its +adjacency list. + +""" + + +class Graph: + """ Simple class for graph: adjacency lists + + Attributes: + order (int): Number of vertices. + directed (bool): True if the graph is directed. False otherwise. + adjlists (List[List[int]]): Lists of connected vertices for each vertex. + + """ + + def __init__(self, order, directed, labels=None): + """Init graph, allocate adjacency lists + + Args: + order (int): Number of nodes. + directed (bool): True if the graph is directed. False otherwise. + labels (list[str]): optionnal vector of vertex labels + """ + + self.order = order + self.directed = directed + self.adjlists = [] + for _ in range(order): + self.adjlists.append([]) + self.labels = labels + + def addedge(self, src, dst): + """Add egde to graph. + + Args: + src (int): Source vertex. + dst (int): Destination vertex. + + Raises: + IndexError: If any vertex index is invalid. + + """ + if src >= self.order or src < 0: + raise IndexError("Invalid src index") + if dst >= self.order or dst < 0: + raise IndexError("Invalid dst index") + + self.adjlists[src].append(dst) + if not self.directed and dst != src: + self.adjlists[dst].append(src) + + + def addvertex(self, number=1, labels=None): + """Add number vertices to graph. + + Args: + ref (Graph). + number (int): Number of vertices to add. + + """ + + # Increment order and extend adjacency list + self.order += number + for _ in range(number): + self.adjlists.append([]) + if labels: + self.labels += labels + + def removeedge(self, src, dst): + """Remove egde from the graph. + + Args: + src (int): Source vertex. + dst (int): Destination vertex. + + Raises: + IndexError: If any vertex index is invalid. + + """ + + if src >= self.order or src < 0: + raise IndexError("Invalid src index") + if dst >= self.order or dst < 0: + raise IndexError("Invalid dst index") + if dst in self.adjlists[src]: + self.adjlists[src].remove(dst) + if not self.directed and dst != src: + self.adjlists[dst].remove(src) + +def sortgraph(G): + """ + sorts adjacency lists -> to have same results as those asked in tutorials/exams + """ + for i in range(G.order): + G.adjlists[i].sort() + +def dot(G): + """Dot format of graph. + + Args: + Graph + + Returns: + str: String storing dot format of graph. + + """ + + if G.directed: + s = "digraph {\n" + for x in range(G.order): + if G.labels: + s += " " + str(x) + '[label = "' + G.labels[x] + '"]\n' + else: + s += " " + str(x) + '\n' + for y in G.adjlists[x]: + s += str(x) + " -> " + str(y) + '\n' + else: + s = "graph {\n" + for x in range(G.order): + if G.labels: + s += " " + str(x) + '[label = "' + G.labels[x] + '"]\n' + else: + s += " " + str(x) + '\n' + for y in G.adjlists[x]: + if x <= y: + s += str(x) + " -- " + str(y) + '\n' + return s + '}' + +def display(G, eng=None): + """ + *Warning:* Made for use within IPython/Jupyter only. + eng: graphivz.Source "engine" optional argument (try "neato", "fdp", "sfdp", "circo") + + """ + + try: + from graphviz import Source + from IPython.display import display + except: + raise Exception("Missing module: graphviz and/or IPython.") + display(Source(dot(G), engine = eng)) + + +# load / save gra format + +def load(filename): + """Build a new graph from a GRA file. + + Args: + filename (str): File to load. + + Returns: + Graph: New graph. + + Raises: + FileNotFoundError: If file does not exist. + + """ + + f = open(filename) + lines = f.readlines() + f.close() + + infos = {} + i = 0 + while '#' in lines[i]: + (key, val) = lines[i][1:].strip().split(": ") + infos[key] = val + i += 1 + + directed = bool(int(lines[i])) + order = int(lines[i+1]) + + if infos and "labels" in infos: + labels = infos["labels"].split(',') #labels is a list of str + G = Graph(order, directed, labels) # a graph with labels + else: + G = Graph(order, directed) # a graph without labels + if infos: + G.infos = infos + + for line in lines[i+2:]: + edge = line.strip().split(' ') + (src, dst) = (int(edge[0]), int(edge[1])) + G.addedge(src, dst) + return G + + +def save(G, fileOut): + gra = "" + if G.labels: + lab = "#labels: " + for i in range(G.order - 1): + lab += G.labels[i] + ',' + lab += G.labels[-1] + gra += lab + '\n' + gra += str(int(G.directed)) + '\n' + gra += str(G.order) + '\n' + for x in range(G.order): + for y in G.adjlists[x]: + if G.directed or x >= y: + gra += str(x) + " " + str(y) + '\n' + fout = open(fileOut, mode='w') + fout.write(gra) + fout.close() + + +# -*- coding: utf-8 -*- +"""Graph module. + +Provide an implementation of graphs with adjacency matrix. +This can also be called static implementation. + +In a graph, vertices are considered numbered from 0 to the order of the graph +minus one. + +""" + + +class GraphMat: + """ Simple class for static graph. + + Attributes: + order (int): Number of vertices. + directed (bool): True if the graph is directed. False otherwise. + adj (List[List[int]]): Adjacency matrix + """ + + def __init__(self, order, directed): + """ + Args: + order (int): Number of nodes. + directed (bool): True if the graph is directed. False otherwise. + """ + + self.order = order + self.directed = directed + self.adj = [[0 for j in range(order)] for i in range(order)] + + + def addedge(self, src, dst): + """Add egde to graph. + + Args: + src (int): Source vertex. + dst (int): Destination vertex. + + Raises: + IndexError: If any vertex index is invalid. + + """ + + if src >= self.order or src < 0: + raise IndexError("Invalid src index") + if dst >= self.order or dst < 0: + raise IndexError("Invalid dst index") + + self.adj[src][dst] += 1 + if not self.directed and dst != src: + self.adj[dst][src] += 1 + + + +def dot(G): + """Dot format of graph. + + Args: + GraphMat + + Returns: + str: String storing dot format of graph. + + """ + + if G.directed: + s = "digraph {\n" + link = " -> " + for x in range(G.order): + for y in range(G.order): + s += (str(x) + link + str(y) + '\n') * G.adj[x][y] + else: + s = "graph {\n" + link = " -- " + for x in range(G.order): + for y in range(x+1): + s += (str(x) + link + str(y) + '\n') * G.adj[x][y] + return s + '}' + + + +def display(G, eng=None): + """ + *Warning:* Made for use within IPython/Jupyter only. + eng: graphivz.Source "engine" optional argument (try "neato", "fdp", "sfdp", "circo") + + """ + + try: + from graphviz import Source + from IPython.display import display + except: + raise Exception("Missing module: graphviz and/or IPython.") + display(Source(dot(G), engine = eng)) + + +# load / save gra format (do not manage labels and other infos) + +def load(filename,): + """Build a new graph from a GRA file. + + Args: + filename (str): File to load. + + Returns: + Graph: New graph. + + Raises: + FileNotFoundError: If file does not exist. + + """ + + f = open(filename) + directed = bool(int(f.readline())) + order = int(f.readline()) + g = GraphMat(order, directed) + for line in f.readlines(): + edge = line.strip().split(' ') + (src, dst) = (int(edge[0]), int(edge[1])) + g.addedge(src, dst) + f.close() + return g + +def save(G, fileOut): + gra = str(int(G.directed)) + '\n' + gra += str(G.order) + '\n' + for x in range(G.order): + if G.directed: + n = G.order + else: + n = x + 1 + for y in range(n): + for i in range(G.adj[x][y]): + gra += str(x) + " " + str(y) + '\n' + fout = open(fileOut, mode='w') + fout.write(gra) + fout.close() + +# -*- coding: utf-8 -*- +"""Queue module.""" + +from collections import deque + +class Queue: + """Simple class for FIFO (first-in-first-out) container.""" + + def __init__(self): + """Init queue.""" + + self.elements = deque() + + def enqueue(self, elt): + """Add an element to the queue. + + Args: + elt (Any): Element to enqueue. + + """ + + self.elements.append(elt) + + def dequeue(self): + """Remove and return next element from the queue. + + Returns: + Any: Element from the queue. + + Raises: + IndexError: If queue is empty. + + """ + + return self.elements.popleft() + + def isempty(self): + """Check whether queue is empty. + + Returns: + bool: True if queue is empty, False otherwise. + + """ + + return len(self.elements) == 0 + +G = Graph(10, False) +G.adjlists = [[4, 4, 1, 3], + [0], + [6, 6, 6, 5, 7], + [0], + [0, 0, 9], + [2, 7, 8], + [2, 2, 2, 7], + [2, 6, 5, 8], + [7, 5, 8], + [4]] + + + +def __smallest_level(G, M, src, perLevel): + cur = Queue() + cur.enqueue(src) + cur.enqueue(None) + M[src] = True + temp = [] + while not cur.isempty(): + x = cur.dequeue() + if x is None: + if (len(temp) != 0 and temp != [src]): + perLevel.append(temp) + temp = [] + else: + temp.append(x) + for adj in G.adjlists[x]: + if not M[adj]: + M[adj] = True + cur.enqueue(adj) + cur.enqueue(None) +def smallest_level(G, src): + M = [False] * G.order + perLevel = [] + __smallest_level(G, M, src, perLevel) + min = perLevel[0] + for element in perLevel: + if len(element) < len(min): + min = element + return min + +smallest_level(G, 0) \ No newline at end of file diff --git a/graphs.ipynb b/graphs.ipynb index 2a824b3..3b611b1 100644 --- a/graphs.ipynb +++ b/graphs.ipynb @@ -6,8 +6,8 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2024-12-14T10:54:32.699159Z", - "start_time": "2024-12-14T10:54:32.688460Z" + "end_time": "2024-12-14T12:23:31.698030Z", + "start_time": "2024-12-14T12:23:31.686929Z" } }, "source": [ @@ -227,166 +227,26 @@ " fout.close()\n" ], "outputs": [], - "execution_count": 3 + "execution_count": 1 }, { "metadata": { "ExecuteTime": { - "end_time": "2024-12-14T10:54:33.640420Z", - "start_time": "2024-12-14T10:54:33.634885Z" + "end_time": "2024-12-14T12:23:31.740543Z", + "start_time": "2024-12-14T12:23:31.738488Z" } }, "cell_type": "code", - "source": [ - "# -*- coding: utf-8 -*-\n", - "\"\"\"Graph module.\n", - "\n", - "Provide an implementation of graphs with adjacency matrix.\n", - "This can also be called static implementation.\n", - "\n", - "In a graph, vertices are considered numbered from 0 to the order of the graph\n", - "minus one.\n", - "\n", - "\"\"\"\n", - "\n", - "\n", - "class GraphMat:\n", - " \"\"\" Simple class for static graph.\n", - "\n", - " Attributes:\n", - " order (int): Number of vertices.\n", - " directed (bool): True if the graph is directed. False otherwise.\n", - " adj (List[List[int]]): Adjacency matrix\n", - " \"\"\"\n", - "\n", - " def __init__(self, order, directed):\n", - " \"\"\"\n", - " Args:\n", - " order (int): Number of nodes.\n", - " directed (bool): True if the graph is directed. False otherwise.\n", - " \"\"\"\n", - "\n", - " self.order = order\n", - " self.directed = directed\n", - " self.adj = [[0 for j in range(order)] for i in range(order)]\n", - "\n", - "\n", - " def addedge(self, src, dst):\n", - " \"\"\"Add egde to graph.\n", - "\n", - " Args:\n", - " src (int): Source vertex.\n", - " dst (int): Destination vertex.\n", - "\n", - " Raises:\n", - " IndexError: If any vertex index is invalid.\n", - "\n", - " \"\"\"\n", - "\n", - " if src >= self.order or src < 0:\n", - " raise IndexError(\"Invalid src index\")\n", - " if dst >= self.order or dst < 0:\n", - " raise IndexError(\"Invalid dst index\")\n", - "\n", - " self.adj[src][dst] += 1\n", - " if not self.directed and dst != src:\n", - " self.adj[dst][src] += 1\n", - "\n", - "\n", - "\n", - "def dot(G):\n", - " \"\"\"Dot format of graph.\n", - "\n", - " Args:\n", - " GraphMat\n", - "\n", - " Returns:\n", - " str: String storing dot format of graph.\n", - "\n", - " \"\"\"\n", - "\n", - " if G.directed:\n", - " s = \"digraph {\\n\"\n", - " link = \" -> \"\n", - " for x in range(G.order):\n", - " for y in range(G.order):\n", - " s += (str(x) + link + str(y) + '\\n') * G.adj[x][y]\n", - " else:\n", - " s = \"graph {\\n\"\n", - " link = \" -- \"\n", - " for x in range(G.order):\n", - " for y in range(x+1):\n", - " s += (str(x) + link + str(y) + '\\n') * G.adj[x][y]\n", - " return s + '}'\n", - "\n", - "\n", - "\n", - "def display(G, eng=None):\n", - " \"\"\"\n", - " *Warning:* Made for use within IPython/Jupyter only.\n", - " eng: graphivz.Source \"engine\" optional argument (try \"neato\", \"fdp\", \"sfdp\", \"circo\")\n", - "\n", - " \"\"\"\n", - "\n", - " try:\n", - " from graphviz import Source\n", - " from IPython.display import display\n", - " except:\n", - " raise Exception(\"Missing module: graphviz and/or IPython.\")\n", - " display(Source(dot(G), engine = eng))\n", - "\n", - "\n", - "# load / save gra format (do not manage labels and other infos)\n", - "\n", - "def load(filename,):\n", - " \"\"\"Build a new graph from a GRA file.\n", - "\n", - " Args:\n", - " filename (str): File to load.\n", - "\n", - " Returns:\n", - " Graph: New graph.\n", - "\n", - " Raises:\n", - " FileNotFoundError: If file does not exist.\n", - "\n", - " \"\"\"\n", - "\n", - " f = open(filename)\n", - " directed = bool(int(f.readline()))\n", - " order = int(f.readline())\n", - " g = GraphMat(order, directed)\n", - " for line in f.readlines():\n", - " edge = line.strip().split(' ')\n", - " (src, dst) = (int(edge[0]), int(edge[1]))\n", - " g.addedge(src, dst)\n", - " f.close()\n", - " return g\n", - "\n", - "def save(G, fileOut):\n", - " gra = str(int(G.directed)) + '\\n'\n", - " gra += str(G.order) + '\\n'\n", - " for x in range(G.order):\n", - " if G.directed:\n", - " n = G.order\n", - " else:\n", - " n = x + 1\n", - " for y in range(n):\n", - " for i in range(G.adj[x][y]):\n", - " gra += str(x) + \" \" + str(y) + '\\n'\n", - " fout = open(fileOut, mode='w')\n", - " fout.write(gra)\n", - " fout.close()\n" - ], + "source": "", "id": "e12f5903c5348752", "outputs": [], - "execution_count": 4 + "execution_count": null }, { "metadata": { "ExecuteTime": { - "end_time": "2024-12-14T10:54:34.476061Z", - "start_time": "2024-12-14T10:54:34.472348Z" + "end_time": "2024-12-14T12:23:31.807702Z", + "start_time": "2024-12-14T12:23:31.804575Z" } }, "cell_type": "code", @@ -439,7 +299,7 @@ ], "id": "663b49e4f6763d11", "outputs": [], - "execution_count": 5 + "execution_count": 2 }, { "metadata": {}, @@ -450,8 +310,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-12-14T10:54:38.976275Z", - "start_time": "2024-12-14T10:54:38.973873Z" + "end_time": "2024-12-14T12:23:31.826260Z", + "start_time": "2024-12-14T12:23:31.824156Z" } }, "cell_type": "code", @@ -471,13 +331,13 @@ ], "id": "ca54f5a3f1a225b", "outputs": [], - "execution_count": 6 + "execution_count": 3 }, { "metadata": { "ExecuteTime": { - "end_time": "2024-12-14T10:54:39.957846Z", - "start_time": "2024-12-14T10:54:39.955269Z" + "end_time": "2024-12-14T12:23:31.853995Z", + "start_time": "2024-12-14T12:23:31.851762Z" } }, "cell_type": "code", @@ -498,7 +358,7 @@ ] } ], - "execution_count": 7 + "execution_count": 4 }, { "metadata": {}, @@ -509,8 +369,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-12-14T10:54:41.253023Z", - "start_time": "2024-12-14T10:54:41.250277Z" + "end_time": "2024-12-14T12:23:31.886996Z", + "start_time": "2024-12-14T12:23:31.884644Z" } }, "cell_type": "code", @@ -528,7 +388,7 @@ ], "id": "6920c423c0bdfc24", "outputs": [], - "execution_count": 8 + "execution_count": 5 }, { "metadata": {}, @@ -539,8 +399,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-12-09T14:48:04.596974Z", - "start_time": "2024-12-09T14:48:04.592782Z" + "end_time": "2024-12-14T12:23:31.913924Z", + "start_time": "2024-12-14T12:23:31.909906Z" } }, "cell_type": "code", @@ -561,18 +421,18 @@ "[4, 1, 5, 1, 3, 3, 4, 4, 3, 1]" ] }, - "execution_count": 8, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 8 + "execution_count": 6 }, { "metadata": { "ExecuteTime": { - "end_time": "2024-12-09T14:48:05.120730Z", - "start_time": "2024-12-09T14:48:05.116518Z" + "end_time": "2024-12-14T12:23:31.946802Z", + "start_time": "2024-12-14T12:23:31.943693Z" } }, "cell_type": "code", @@ -596,12 +456,12 @@ "[[3, 4, 1, 2, 3, 2, 3, 0, 2], [6, 1, 1, 2, 0, 3, 2, 3, 2]]" ] }, - "execution_count": 9, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 9 + "execution_count": 7 }, { "metadata": {}, @@ -612,8 +472,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-12-09T14:48:06.156919Z", - "start_time": "2024-12-09T14:48:06.154020Z" + "end_time": "2024-12-14T12:23:32.018541Z", + "start_time": "2024-12-14T12:23:32.015799Z" } }, "cell_type": "code", @@ -696,7 +556,7 @@ ] } ], - "execution_count": 10 + "execution_count": 8 }, { "metadata": {}, @@ -910,21 +770,21 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-12-09T15:48:15.121203Z", - "start_time": "2024-12-09T15:48:15.116918Z" + "end_time": "2024-12-14T12:50:54.278706Z", + "start_time": "2024-12-14T12:50:54.271435Z" } }, "cell_type": "code", "source": [ - "def aux(G, M, src):\n", - " newColor = not M[src]\n", + "def aux_colors(G, M, src):\n", + " new_color = not M[src]\n", " for adj in G.adjlists[src]:\n", " if M[adj] == None:\n", - " M[adj] = newColor\n", - " if not aux(G, M, adj):\n", + " M[adj] = new_color\n", + " if not aux_colors(G, M, adj):\n", " return False\n", " else:\n", - " if M[adj] != newColor:\n", + " if M[adj] != new_color:\n", " return False\n", " return True\n", "\n", @@ -934,8 +794,8 @@ " for src in range(G.order):\n", " if M[src] == None:\n", " M[src] = True\n", - " if not aux(G, M, src):\n", - " return False\n", + " if not aux_colors(G, M, src):\n", + " return False\n", " return True\n", "\n", "two_coloring(G1)" @@ -948,12 +808,12 @@ "False" ] }, - "execution_count": 32, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 32 + "execution_count": 26 }, { "metadata": {}, @@ -970,31 +830,29 @@ }, "cell_type": "code", "source": [ - "def __fakenews(G, M, src, truth):\n", - " cur = Queue()\n", - " cur.enqueue(src)\n", + "def __fakenews(G, M, src, fake):\n", + " q = Queue()\n", + " q.enqueue(src)\n", " stop = False\n", - " while not cur.isempty() and not stop:\n", - " x = cur.dequeue()\n", - " if M[x] > truth + 1:\n", + " while not q.isempty() and not stop:\n", + " x = q.dequeue()\n", + " if M[x] > fake:\n", " for adj in G.adjlists[x]:\n", " if M[adj] == None:\n", " M[adj] = M[x] - 1\n", - " cur.enqueue(adj)\n", + " q.enqueue(adj)\n", " else:\n", " stop = True\n", "\n", "def fakenews(G, src, truth):\n", - " if (truth <= 2):\n", - " raise Exception(\"truth should be > 2\")\n", - " M = [False] * G.order\n", + " M = [None] * G.order\n", " M[src] = truth\n", - " fake = []\n", - " __fakenews(G, M, src, truth // 2)\n", - " for i in range(G.order):\n", - " if M[i] == None:\n", - " fake.append(i)\n", - " return truth" + " __fakenews(G, M, src, truth//2)\n", + " L = []\n", + " for s in range(G.order):\n", + " if M[s] == None:\n", + " L.append(s)\n", + " return L" ], "id": "c66ac4688a6975c9", "outputs": [], @@ -1003,24 +861,191 @@ { "metadata": {}, "cell_type": "markdown", - "source": "# 2027 - Exercice 1", + "source": "# 2027 - Exercice 2", "id": "b8fa23568b4bd3df" }, { - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-14T12:27:17.971319Z", + "start_time": "2024-12-14T12:27:17.967991Z" + } + }, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": [ - "def __longest_path(G, dist, src):\n", + "# Reconstitution du graph du partiel\n", + "# Initialisation d'un graphe non orienté avec 10 sommets\n", + "G = Graph(order=10, directed=False)\n", "\n", + "# Ajout des arêtes selon l'image fournie\n", + "G.addedge(0, 1)\n", + "G.addedge(0, 2)\n", + "G.addedge(0, 8)\n", + "G.addedge(0, 6)\n", + "G.addedge(1, 2)\n", + "G.addedge(1, 3)\n", + "G.addedge(2, 3)\n", + "G.addedge(2, 8)\n", + "G.addedge(3, 5)\n", + "G.addedge(3, 6)\n", + "G.addedge(4, 5)\n", + "G.addedge(5, 7)\n", + "G.addedge(6, 9)\n", + "G.addedge(7, 9)\n", + "G.addedge(8, 9)\n", "\n", - "def longest_path(G):\n", - " dist = [None] * G.order\n", - " for src in range(G.order):\n", - " __longest_path(G, dist, src)" + "# Tri des listes d'adjacence pour une sortie cohérente\n", + "sortgraph(G)\n", + "\n", + "# Affichage du graphe au format DOT (si tu as graphviz configuré)\n", + "print(dot(G))\n", + "\n", + "# Affichage visuel dans Jupyter Notebook (optionnel)\n", + "# display(G, eng=\"neato\") # Utilise l'option \"neato\" pour une disposition automatique" ], - "id": "9a3a85d15dccbb97" + "id": "f3f003f5ecd72f9e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "digraph {\n", + "0 -- 1\n", + "0 -- 2\n", + "0 -- 6\n", + "0 -- 8\n", + "1 -- 0\n", + "1 -- 2\n", + "1 -- 3\n", + "2 -- 0\n", + "2 -- 1\n", + "2 -- 3\n", + "2 -- 8\n", + "3 -- 1\n", + "3 -- 2\n", + "3 -- 5\n", + "3 -- 6\n", + "4 -- 5\n", + "5 -- 3\n", + "5 -- 4\n", + "5 -- 7\n", + "6 -- 0\n", + "6 -- 3\n", + "6 -- 9\n", + "7 -- 5\n", + "7 -- 9\n", + "8 -- 0\n", + "8 -- 2\n", + "8 -- 9\n", + "9 -- 6\n", + "9 -- 7\n", + "9 -- 8\n", + "}\n" + ] + } + ], + "execution_count": 15 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-14T12:42:59.642392Z", + "start_time": "2024-12-14T12:42:59.636696Z" + } + }, + "cell_type": "code", + "source": [ + "\"\"\"\n", + "def __smallest_level(G, M, src, perLevel):\n", + " cur = Queue()\n", + " cur.enqueue(src)\n", + " cur.enqueue(None)\n", + " M[src] = True\n", + " temp = []\n", + " while not cur.isempty():\n", + " x = cur.dequeue()\n", + " if x is None:\n", + " if (len(temp) != 0 and temp != [src]):\n", + " perLevel.append(temp)\n", + " temp = []\n", + " else:\n", + " temp.append(x)\n", + " for adj in G.adjlists[x]:\n", + " if not M[adj]:\n", + " M[adj] = True\n", + " cur.enqueue(adj)\n", + " cur.enqueue(None)\n", + "\n", + "def smallest_level(G, src):\n", + " M = [False] * G.order\n", + " perLevel = []\n", + " __smallest_level(G, M, src, perLevel)\n", + " min = perLevel[0]\n", + " for element in perLevel:\n", + " if len(element) < len(min):\n", + " min = element\n", + " return min\n", + "\"\"\"\n", + "\n", + "def smallest(G, src):\n", + " dist = [None] * G.order\n", + " q = Queue()\n", + " q.enqueue(src)\n", + " dist[src] = 0\n", + " small = G.order\n", + " d = 0\n", + " L = []\n", + " while not q.isempty():\n", + " x = q.dequeue()\n", + " if dist[x] > d:\n", + " if len(L) < small:\n", + " small = len(L)\n", + " Res = L\n", + " d += 1\n", + " L = []\n", + " for y in G.adjlists[x]:\n", + " if dist[y] == None:\n", + " dist[y] = dist[x] + 1\n", + " q.enqueue(y)\n", + " L.append(y)\n", + " return Res" + ], + "id": "9a3a85d15dccbb97", + "outputs": [], + "execution_count": 23 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-14T12:43:03.858284Z", + "start_time": "2024-12-14T12:43:03.855864Z" + } + }, + "cell_type": "code", + "source": [ + "for s in range(10):\n", + " print(s, \"=>\", smallest(G, s))" + ], + "id": "5be240ac4da2b002", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 => [4]\n", + "1 => [0, 2, 3]\n", + "2 => [4, 7]\n", + "3 => [1, 2, 5, 6]\n", + "4 => [5]\n", + "5 => [0, 8]\n", + "6 => [4]\n", + "7 => [5, 9]\n", + "8 => [5]\n", + "9 => [1, 4]\n" + ] + } + ], + "execution_count": 24 } ], "metadata": {