Add kruskals algorithm

master
Oystein Kristoffer Tveit 2021-05-17 23:32:51 +02:00
parent f2a26807c1
commit bc1609c549
7 changed files with 180 additions and 14 deletions

View File

@ -168,7 +168,7 @@ See examples of what the engine for the exam template can do here: [exam_templat
- [X] Output a graph to a matrix
- [X] Draw an undirected graph
- [X] Draw a directed graph
- [ ] Find a minimal spanning tree with Kruskals algorithm
- [X] Find a minimal spanning tree with Kruskals algorithm
#### Chapter 8. Finite state automata

View File

@ -68,7 +68,7 @@ class Graph:
return \
f'Nodes: {" ".join(self.nodes)}\n' \
+ f'Edges: {" ".join(x+y for x,y in (self.undirectedEdgeSet() if self.isUndirected() else self.edges))}'
@classmethod
def fromMatrix(cls, matrix):
return matrix.toGraph()
@ -136,12 +136,14 @@ class Graph:
new_connected_subgraphs = [subgraph_v.union(x) if u in x else x for x in new_connected_subgraphs]
return new_connected_subgraphs
sorted_edges = [ e for e in sorted(self.edges, key=lambda e: weigths[str(e)]) ]
sorted_edges = [ e for e in sorted(self.edges, key=lambda e: weigths[e[0] + e[1]]) ]
for u,v in sorted_edges:
if find_subgraph_containing(u) != find_subgraph_containing(v):
edges += [(u, v)]
connected_subgraphs = merge_subgraphs_that_contains(u, v)
edges += [(y,x) for x,y in edges]
return Graph(self.nodes, edges)
@ -161,6 +163,15 @@ class Graph:
return (nodeString, edgeString)
def toLaTeXWithWeights(self, weights):
zippedNodes = zip(self.nodes, generateNodeCoords(len(self.nodes)))
nodeString = '\n'.join(f'\\node ({name}) at ({x},{y}) {{${name}$}};' for name,(x,y) in zippedNodes)
if self.isUndirected():
edgeString = '\n'.join(f'\\draw ({x}) -- ({y}) node [midway, above, sloped] (Tx{x+y}) {{{weights[x+y]}}};' for x,y in self.undirectedEdgeSet())
return (nodeString, edgeString)
def generateLoopInOutAngle(node, nodes):
baseAngle = 360 / len(nodes)
@ -186,11 +197,37 @@ def generateNodeCoords(n):
return nodeCoords
def extractWeights(string):
weights = dict()
lines = string.split('\n')
for i in range(4, len(lines)):
edge, weight = lines[i].split(' ')
weights[edge] = int(weight)
weights[edge[1] + edge[0]] = int(weight)
lines[i] = edge
return ('\n'.join(lines), weights)
def processFileContent(raw):
lines = raw.split('\n')
lines.pop(1)
outputType = lines.pop(0)
if lines[0] == 'kruskals':
lines[0] = 'undirected'
string, weights = extractWeights('\n'.join(lines))
graph1 = Graph.fromString(string)
graph2 = graph1.getKruskalsSpanningTree(weights)
return replaceContent(
(graph1.toLaTeXWithWeights(weights), graph2.toLaTeXWithWeights(weights)),
'Kruskals',
replaceF = lambda temp, cont:
temp.replace('%NODES1', cont[0][0])
.replace('%EDGES1', cont[0][1])
.replace('%NODES2', cont[1][0])
.replace('%EDGES2', cont[1][1])
)
graph = Graph.fromString('\n'.join(lines))
print(graph)
@ -207,11 +244,14 @@ def processFileContent(raw):
content = graph.toMatrix().toLaTeX()
return replaceContent(content, 'Matrix')
if __name__ == '__main__':
pass
# matrix = Matrix([[False, False, True], [True, False, True], [True, False, False]])
# print(matrix)
# print(matrix.toGraph())
# print(matrix.toGraph().isUndirected())
g = Graph.fromString('complete\n\n6')
print(g)
import random
d = dict()
for e in g.edges:
d[str(e)] = random.randint(0, 10)
print(g.getKruskalsSpanningTree(d))

View File

@ -0,0 +1,37 @@
\begin{mgraphbox}[width=\linewidth]
\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\begin{scope}[every node/.style={shape=circle, fill=white, draw, inner sep=2pt}]
%NODES1
\end{scope}
\begin{scope}[every draw/.style={}]
%EDGES1
\end{scope}
\end{tikzpicture}
\end{center}
\end{figure}
\end{mgraphbox}
Minimal spanning tree:
\begin{mgraphbox}[width=\linewidth]
\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\begin{scope}[every node/.style={shape=circle, fill=white, draw, inner sep=2pt}]
%NODES2
\end{scope}
\begin{scope}[every draw/.style={}]
%EDGES2
\end{scope}
\end{tikzpicture}
\end{center}
\end{figure}
\end{mgraphbox}

View File

@ -0,0 +1,67 @@
\begin{mgraphbox}[width=\linewidth]
\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\begin{scope}[every node/.style={shape=circle, fill=white, draw, inner sep=2pt}]
\node (A) at (0,4.0) {$A$};
\node (B) at (-2.82843,2.82843) {$B$};
\node (C) at (-4.0,0.0) {$C$};
\node (D) at (-2.82843,-2.82843) {$D$};
\node (E) at (-0.0,-4.0) {$E$};
\node (F) at (2.82843,-2.82843) {$F$};
\node (G) at (4.0,-0.0) {$G$};
\node (H) at (2.82843,2.82843) {$H$};
\end{scope}
\begin{scope}[every draw/.style={}]
\draw (A) -- (B) node [midway, above, sloped] (TxAB) {1};
\draw (A) -- (C) node [midway, above, sloped] (TxAC) {2};
\draw (A) -- (H) node [midway, above, sloped] (TxAH) {11};
\draw (B) -- (C) node [midway, above, sloped] (TxBC) {7};
\draw (B) -- (F) node [midway, above, sloped] (TxBF) {12};
\draw (C) -- (D) node [midway, above, sloped] (TxCD) {3};
\draw (C) -- (H) node [midway, above, sloped] (TxCH) {14};
\draw (D) -- (E) node [midway, above, sloped] (TxDE) {9};
\draw (D) -- (F) node [midway, above, sloped] (TxDF) {6};
\draw (D) -- (G) node [midway, above, sloped] (TxDG) {10};
\draw (F) -- (G) node [midway, above, sloped] (TxFG) {8};
\end{scope}
\end{tikzpicture}
\end{center}
\end{figure}
\end{mgraphbox}
Minimal spanning tree:
\begin{mgraphbox}[width=\linewidth]
\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\begin{scope}[every node/.style={shape=circle, fill=white, draw, inner sep=2pt}]
\node (A) at (0,4.0) {$A$};
\node (B) at (-2.82843,2.82843) {$B$};
\node (C) at (-4.0,0.0) {$C$};
\node (D) at (-2.82843,-2.82843) {$D$};
\node (E) at (-0.0,-4.0) {$E$};
\node (F) at (2.82843,-2.82843) {$F$};
\node (G) at (4.0,-0.0) {$G$};
\node (H) at (2.82843,2.82843) {$H$};
\end{scope}
\begin{scope}[every draw/.style={}]
\draw (A) -- (B) node [midway, above, sloped] (TxAB) {1};
\draw (A) -- (C) node [midway, above, sloped] (TxAC) {2};
\draw (A) -- (H) node [midway, above, sloped] (TxAH) {11};
\draw (C) -- (D) node [midway, above, sloped] (TxCD) {3};
\draw (D) -- (E) node [midway, above, sloped] (TxDE) {9};
\draw (D) -- (F) node [midway, above, sloped] (TxDF) {6};
\draw (F) -- (G) node [midway, above, sloped] (TxFG) {8};
\end{scope}
\end{tikzpicture}
\end{center}
\end{figure}
\end{mgraphbox}

View File

@ -0,0 +1,19 @@
# Graph
kruskals
A B C D E F G H
AB 1
AC 2
CD 3
DE 4
HA 5
FD 6
CB 7
FG 8
DE 9
DG 10
AH 11
FB 12
HC 13
CH 14

View File

@ -95,6 +95,8 @@
\verbatimInput{undirectedGraphToMatrix}
\verbatimDiagram{directedFromMatrix}
\verbatimInput{kruskals}
\section{Finite state automata}

View File

@ -17,7 +17,8 @@
\contentsline {subsection}{\numberline {5.4}adjacency}{12}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}undirectedGraphToMatrix}{13}{subsection.5.5}%
\contentsline {subsection}{\numberline {5.6}directedFromMatrix}{14}{subsection.5.6}%
\contentsline {section}{\numberline {6}Finite state automata}{15}{section.6}%
\contentsline {subsection}{\numberline {6.1}automata}{15}{subsection.6.1}%
\contentsline {section}{\numberline {7}Raw python}{16}{section.7}%
\contentsline {subsection}{\numberline {7.1}python}{16}{subsection.7.1}%
\contentsline {subsection}{\numberline {5.7}kruskals}{15}{subsection.5.7}%
\contentsline {section}{\numberline {6}Finite state automata}{17}{section.6}%
\contentsline {subsection}{\numberline {6.1}automata}{17}{subsection.6.1}%
\contentsline {section}{\numberline {7}Raw python}{18}{section.7}%
\contentsline {subsection}{\numberline {7.1}python}{18}{subsection.7.1}%