2
0
Fork 0
mirror of https://github.com/MartinThoma/LaTeX-examples.git synced 2025-04-24 22:08:04 +02:00

Fehler korrigiert; Verlinkung mit cleveref verbessert

This commit is contained in:
Martin Thoma 2014-01-12 15:19:53 +01:00
parent 3d8855c84e
commit e03e13a284
8 changed files with 165 additions and 150 deletions

View file

@ -3,9 +3,9 @@ DYCOS (\underline{DY}namic \underline{C}lassification
algorithm with c\underline{O}ntent and \underline{S}tructure) ist ein
Knotenklassifizierungsalgorithmus, der Ursprünglich in \cite{aggarwal2011} vorgestellt
wurde. Er klassifiziert Knoten, indem mehrfach Random Walks startend
bei dem zu klassifizierenden Knoten gemacht werden und die Labels
bei dem zu klassifizierenden Knoten $v$ gemacht werden und die Labels
der besuchten Knoten gezählt werden. Das Label, das am häufigsten
vorgekommen ist, wird als Label gewählt.
vorgekommen ist, wird als Label für $v$ gewählt.
DYCOS nutzt also die sog. Homophilie, d.~h. die Eigenschaft, dass
Knoten, die nur wenige Hops von einander entfernt sind, häufig auch
ähnlich sind \cite{bhagat}.
@ -17,7 +17,7 @@ stehenden Texte.
Für diese Erweiterung wird zuerst wird Vokabular $W_t$ bestimmt, das
charakteristisch für eine Knotengruppe ist. Wie das gemacht werden kann
und warum nicht einfach jedes Wort in das Vokabular aufgenommen wird,
wird in Abschnitt~\ref{sec:vokabularbestimmung} erläutert.\\
wird in \cref{sec:vokabularbestimmung} erläutert.\\
Nach der Bestimmung des Vokabulars wird für
jedes Wort im Vokabular ein Wortknoten zum Graphen hinzugefügt. Alle
Knoten, die der Graph zuvor hatte, werden nun \enquote{Strukturknoten}
@ -53,17 +53,21 @@ tatsächlich die Grapherweiterung:
Dann heißt das zufällige wechseln des aktuell betrachteten
Knoten $v \in V_t$ zu einem benachbartem Knoten $w \in W_t$
und weiter zu Nachbar von $v' \in V_t$ von $w$
ein \textbf{inhaltlicher Mehrfachsprung}. $v'$ ist also genau
einen Sprung über einen Wortknoten $w$ von $v$ entfernt.
und weiter zu einem zufälligem Nachbar $v' \in V_t$ von $w$
ein \textbf{inhaltlicher Mehrfachsprung}.
\end{definition}
Jeder inhaltliche Mehrfachsprung beginnt und endet also in einem Strukturknoten,
springt über einen Wortknoten und ist ein Pfad der Länge~2.
Bevor der DYCOS-Algorithmus im Detail erklärt wird, sei noch auf eine
Besonderheit hingewiesen:
Der DYCOS-Algorithmus betrachtet die Texte, die einem Knoten
zugeornet sind, als eine
Multimenge von Wörtern. Das heißt, zum einen wird nicht auf die
Reihenfolge der Wörter geachtet, zum anderen wird bei Texten
eines Knotens nicht zwischen verschiedenen Texten unterschieden.
Jedoch wird die Anzahl der Vorkommen jedes Wortes berücksichtigt.
zugeornet sind, als eine Multimenge von Wörtern. Das heißt, zum einen
wird nicht auf die Reihenfolge der Wörter geachtet, zum anderen wird
bei Texten eines Knotens nicht zwischen verschiedenen
Texten unterschieden. Jedoch wird die Anzahl der Vorkommen
jedes Wortes berücksichtigt.
\subsection{Datenstrukturen}
Zusätzlich zu dem gerichteten Graphen $G_t = (V_t, E_t, V_{L,t})$
@ -94,27 +98,32 @@ verwaltet der DYCOS-Algorithmus zwei weitere Datenstrukturen:
\subsection{Der Algorithmus}
Der DYCOS-Algorithmus verwendet nun für jeden Knoten der gelabelt wird
$r$ Random Walks der Länge $l$, wobei mit einer Wahrscheinlichkeit
$p_S$ ein struktureller $l$-Sprung und mit einer Wahrscheinlichkeit
von $(1-p_S)$ ein inhaltlicher $l$-Mehrfachsprung gemacht wird.
$p_S$ ein struktureller Sprung und mit einer Wahrscheinlichkeit
von $(1-p_S)$ ein inhaltlicher Mehrfachsprung gemacht wird. Dieser
Parameter gibt an, wie wichtig die Struktur des Graphen im Verhältnis
zu den textuellen Inhalten ist. Bei $p_S = 0$ werden ausschließlich
die Texte betrachtet, bei $p_S = 1$ ausschließlich die Struktur des
Graphen.
Die Vokabularbestimmung kann zu jedem Zeitpunkt $t$ durchgeführt
werden, muss es aber nicht.
Im Folgenden werde ich den DYCOS-Algorithmus als Pseudocode vorstellen.
Dafür benötigt man die beiden Hilfsfunktionen für den strukturellen
Sprung sowie den inhaltlichen Mehrfachsprung:
In \cref{alg:DYCOS} wurde der DYCOS-Algorithmus als
Pseudocode vorgestellt. Dafür werden die beiden Hilfsfunktionen
für den strukturellen Sprung sowie den inhaltlichen Mehrfachsprung
benötigt.
\begin{algorithm}[H]
\begin{algorithm}
\begin{algorithmic}[1]
\Require \\$\G_t = (\N_t, \A_t, \T_t)$ (Netzwerk),\\
\Require \\$G_t = (V_t, E_t, V_{L,t})$ (Netzwerk),\\
$r$ (Anzahl der Random Walks),\\
$l$ (Länge eines Random Walks),\\
$p_s$ (Wahrscheinlichkeit eines strukturellen Sprungs),\\
$q$ (Anzahl der betrachteten Knoten nach der Aggregatanalyse)
\Ensure Klassifikation von $\N_t \setminus \T_t$\\
$q$ (Anzahl der betrachteten Knoten in der Clusteranalyse)
\Ensure Klassifikation von $V_t \setminus V_{L,t}$\\
\\
\ForAll{Knoten $v$ in $\N_t \setminus \T_t$}
\ForAll{Knoten $v$ in $V_t \setminus V_{L,t}$}
\State $d \gets $ defaultdict
\For{$i$ von $1$ bis $r$}
\State $w \gets v$
@ -140,7 +149,7 @@ Sprung sowie den inhaltlichen Mehrfachsprung:
\State $label \gets \Call{Random}{M_H}$
\State $v.\Call{AddLabel}{label}$ \Comment{und weise dieses $v$ zu}
\EndFor
\State \Return Labels für $\N_t \setminus \T_t$
\State \Return Labels für $V_t \setminus V_{L,t}$
\end{algorithmic}
\caption{DYCOS-Algorithmus}
\label{alg:DYCOS}

Binary file not shown.

View file

@ -24,7 +24,11 @@
\usepackage{csquotes}
\usepackage[colorinlistoftodos]{todonotes}
\usepackage{subfig} % multiple figures in one
\usepackage{caption}
\usepackage{tikz}
\usepackage{enumitem}
\usepackage[german,nameinlink]{cleveref}
\allowdisplaybreaks
\usetikzlibrary{backgrounds}
\usepackage{mystyle}
@ -32,7 +36,7 @@
\setcounter{secnumdepth}{3}
\hypersetup{
pdftitle = {Über die Klassifizierung von Knoten in dynamischen Netzwerken mit Inhalt},
pdftitle = {Über die Klassifizierung von Knoten in dynamischen Netzwerken mit textuellen Inhalten},
pdfauthor = {Martin Thoma},
pdfkeywords = {DYCOS}
}

View file

@ -1,78 +1,10 @@
\subsection{Sprungtypen}
Die beiden bereits definierten Sprungtypen, der strukturelle Sprung
sowie der inhaltliche Mehrfachsprung werden im folgenden erklärt.
\goodbreak
Der strukturelle Sprung entspricht einer zufälligen Wahl eines
Nachbarknotens. Hier gibt es nichts besonderes zu beachten.
Bei inhaltlichen Mehrfachsprüngen sieht die Sache schon anders aus:
Es ist nicht sinnvoll, direkt von einem strukturellem Knoten
$v \in \N_t$ zu einem mit $v$ verbundenen Wortknoten $w$ zu springen
und von diesem wieder zu einem verbundenem strutkurellem Knoten
$v' \in \N_t$. Würde man dies machen, wäre zu befürchten, dass
aufgrund von Homonymen die Qualität der Klassifizierung verringert
wird. So hat \enquote{Brücke} im Deutschen viele Bedeutungen.
Gemeint sein können z.~B. das Bauwerk, das Entwurfsmuster der
objektorientierten Programmierung oder ein Teil des Gehirns.
Deshalb wird für jeden Knoten $v$, von dem aus man einen inhaltlichen
Mehrfachsprung machen will folgendes vorgehen gewählt:
\begin{enumerate}
\item Gehe alle in $v$ startenden Random Walks der Länge 2 durch
und erstelle eine Liste $L$, der erreichbaren Knoten $v'$. Speichere
außerdem, durch wie viele Pfade diese Knoten $v'$ jeweils erreichbar sind.
\item Betrachte im folgenden nur die Top-$q$ Knoten, wobei $q \in \mathbb{N}$
eine zu wählende Konstante des Algorithmus ist.
\item Wähle mit Wahrscheinlichkeit $\frac{\Call{Anzahl}{v'}}{\sum_{w \in L} \Call{Anzahl}{v'}}$
den Knoten $v'$ als Ziel des Mehrfachsprungs.
\end{enumerate}
Konkret könnte also ein Inhaltlicher Mehrfachsprung sowie wie in
Algorithmus~\ref{alg:DYCOS-content-multihop} beschrieben umgesetz werden.
\begin{algorithm}[H]
\begin{algorithmic}[1]
\Procedure{InhaltlicherMehrfachsprung}{Knoten $v$}
\State \textit{//Alle Knoten bestimmen, die von $v$ aus über Pfade der Länge 2 erreichbar sind}
\State \textit{//Zusätzlich wird für diese Knoten die Anzahl der Pfade der Länge 2 bestimmt,}
\State \textit{//durch die sie erreichbar sind}
\State $reachableNodes \gets$ defaultdict
\ForAll{Wortknoten $w$ in $v.\Call{getWordNodes}{ }$}
\ForAll{Strukturknoten $x$ in $w.\Call{getStructuralNodes}{ }$}
\State $reachableNodes[x] \gets reachableNodes[x] + 1$
\EndFor
\EndFor
\State \textit{//Im folgenden gehe ich davon aus, dass ich über Indizes wahlfrei auf Elemente }
\State \textit{//aus $M_H$ zugreifen kann. Dies muss bei der konkreten Wahl der Datenstruktur}
\State \textit{//berücksichtigt werden}
\State $M_H \gets \Call{max}{reachableNodes, q}$ \Comment{Also: $|M_H| = q$, falls $|reachableNodes|\geq q$}
\State \textit{//Generate dictionary with relative frequencies}
\State $s \gets 0$
\ForAll{Knoten $x$ in $M_H$}
\State $s \gets s + reachableNodes[x]$
\EndFor
\State $relativeFrequency \gets $ Dictionary
\ForAll{Knoten $x$ in $M_H$}
\State $relativeFrequency \gets \frac{reachableNodes[x]}{s}$
\EndFor
\State $random \gets \Call{random}{0, 1}$
\State $s \gets 0$
\State $i \gets 0$
\While{$s < random$}
\State $s \gets s + relativeFrequency[i]$
\State $i \gets i + 1$
\EndWhile
\State $v \gets M_H[i-1]$
\State \Return $v$
\EndProcedure
\end{algorithmic}
\caption{Inhaltlicher Mehrfachsprung}
\label{alg:DYCOS-content-multihop}
\end{algorithm}
Nachbarknotens, wie es in \cref{alg:DYCOS-structural-hop}
gezeigt wird.
\begin{algorithm}[H]
\begin{algorithmic}[1]
\Procedure{SturkturellerSprung}{Knoten $v$, Anzahl $q$}
@ -85,3 +17,73 @@ Algorithmus~\ref{alg:DYCOS-content-multihop} beschrieben umgesetz werden.
\caption{Struktureller Sprung}
\label{alg:DYCOS-structural-hop}
\end{algorithm}
Bei inhaltlichen Mehrfachsprüngen ist jedoch nicht sinnvoll so direkt
nach der Definition vorzugehen, also
direkt von einem strukturellem Knoten
$v \in V_t$ zu einem mit $v$ verbundenen Wortknoten $w \in W_t$ zu springen
und von diesem wieder zu einem verbundenem strutkurellem Knoten
$v' \in V_t$. Würde man dies machen, wäre zu befürchten, dass
aufgrund von Homonymen die Qualität der Klassifizierung verringert
wird. So hat \enquote{Brücke} im Deutschen viele Bedeutungen.
Gemeint sein können z.~B. das Bauwerk, das Entwurfsmuster der
objektorientierten Programmierung oder ein Teil des Gehirns.
Deshalb wird für jeden Knoten $v$, von dem aus man einen inhaltlichen
Mehrfachsprung machen will folgendes Clusteranalyse durchgeführt:
\begin{enumerate}[label=C\arabic*),ref=C\arabic*]
\item[C1] Gehe alle in $v$ startenden Random Walks der Länge 2 durch
und erstelle eine Liste $L$, der erreichbaren Knoten $v'$. Speichere
außerdem, durch wie viele Pfade diese Knoten $v'$ jeweils erreichbar sind.
\item[C2] Betrachte im folgenden nur die Top-$q$ Knoten, wobei $q \in \mathbb{N}$
eine zu wählende Konstante des Algorithmus ist. \label{list:aggregate.2}
\item[C3] Wähle mit Wahrscheinlichkeit $\frac{\Call{Anzahl}{v'}}{\sum_{w \in L} \Call{Anzahl}{v'}}$
den Knoten $v'$ als Ziel des Mehrfachsprungs.
\end{enumerate}
Konkret könnte also ein Inhaltlicher Mehrfachsprung sowie wie in
\cref{alg:DYCOS-content-multihop} beschrieben umgesetz werden.
\begin{algorithm}
\caption{Inhaltlicher Mehrfachsprung}
\label{alg:DYCOS-content-multihop}
\begin{algorithmic}[1]
\Procedure{InhaltlicherMehrfachsprung}{Knoten $v$}
\State \textit{//Alle Knoten bestimmen, die von $v$ aus über Pfade der Länge 2 erreichbar sind}
\State \textit{//Zusätzlich wird für diese Knoten die Anzahl der Pfade der Länge 2 bestimmt,}
\State \textit{//durch die sie erreichbar sind}
\State $reachableNodes \gets$ defaultdict
\ForAll{Wortknoten $w$ in $v.\Call{getWordNodes}{ }$}
\ForAll{Strukturknoten $x$ in $w.\Call{getStructuralNodes}{ }$}
\State $reachableNodes[x] \gets reachableNodes[x] + 1$
\EndFor
\EndFor
\State \textit{//Im folgenden wird davon ausgegangen, dass man über Indizes wahlfrei auf}
\State \textit{//Elemente aus $M_H$ zugreifen kann. Dies muss bei der konkreten Wahl}
\State \textit{//der Datenstruktur berücksichtigt werden.}
\State $M_H \gets \Call{max}{reachableNodes, q}$ \Comment{Also: $|M_H| = q$, falls $|reachableNodes|\geq q$}
\State \textit{//Generate dictionary with relative frequencies}
\State $s \gets 0$
\ForAll{Knoten $x$ in $M_H$}
\State $s \gets s + reachableNodes[x]$
\EndFor
\State $relativeFrequency \gets $ Dictionary
\ForAll{Knoten $x$ in $M_H$}
\State $relativeFrequency \gets \frac{reachableNodes[x]}{s}$
\EndFor
\State \textit{//Wähle Knoten $i$ mit einer Wahrscheinlichkeit entsprechend seiner relativen}
\State \textit{//Häufigkeit an Pfaden der Länge 2}
\State $random \gets \Call{random}{0, 1}$
\State $r \gets 0.0$
\State $i \gets 0$
\While{$s < random$}
\State $r \gets r + relativeFrequency[i]$
\State $i \gets i + 1$
\EndWhile
\State $v \gets M_H[i-1]$
\State \Return $v$
\EndProcedure
\end{algorithmic}
\end{algorithm}

View file

@ -21,27 +21,27 @@ In diesem Fall ist $G(w)=0$ nicht möglich, da zur Vokabularbestimmung
nur Wörter betrachtet werden, die auch vorkommen.
Ein Vorschlag, wie die Vokabularbestimmung implementiert werden kann,
ist als Pseudocode mit Algorithmus~\ref{alg:vokabularbestimmung}
ist als Pseudocode mit \cref{alg:vokabularbestimmung}
gegeben. Dieser Algorithmus benötigt neben dem Speicher für den
Graphen, die Texte sowie die $m$ Vokabeln noch $\mathcal{O}(|\text{Verschiedene Wörter in } S_t| \cdot (|\L_t| + 1))$
Speicher. Die Average-Case Zeitkomplexität beträgt
$\mathcal{O}(|\text{Wörter in } S_t|)$, wobei dazu die Vereinigung
von Mengen $M,N$ in $\mathcal{O}(\min{|M|, |N|})$ sein muss.
\begin{algorithm}[H]
\begin{algorithm}
\begin{algorithmic}[1]
\Require \\
$\T_t$ (Knoten mit Labels),\\
$V_{L,t}$ (Knoten mit Labels),\\
$\L_t$ (Labels),\\
$f:\T_t \rightarrow \L_t$ (Label-Funktion),\\
$f:V_{L,t} \rightarrow \L_t$ (Label-Funktion),\\
$m$ (Gewünschte Vokabulargröße)
\Ensure $\M_t$ (Vokabular)\\
\State $S_t \gets \Call{Sample}{\T_t}$ \Comment{Wähle eine Teilmenge $S_t \subseteq \T_t$ aus}
\State $S_t \gets \Call{Sample}{V_{L,t}}$ \Comment{Wähle eine Teilmenge $S_t \subseteq V_{L,t}$ aus}
\State $\M_t \gets \bigcup_{v \in S_t} \Call{getTextAsSet}{v}$ \Comment{Menge aller Wörter}
\State $cLabelWords \gets (|\L_t|+1) \times |\M_t|$-Array, mit 0en initialisert\\
\ForAll{$v \in \T_t$} \Comment{Gehe jeden Text Wort für Wort durch}
\ForAll{$v \in V_{L,t}$} \Comment{Gehe jeden Text Wort für Wort durch}
\State $i \gets \Call{getLabel}{v}$
\ForAll{$(word, occurences) \in \Call{getTextAsMultiset}{v}$}
\State $cLabelWords[i][word] \gets cLabelWords[i][word] + occurences$

View file

@ -1,5 +1,4 @@
In dieser Arbeit wird der DYCOS-Algorithmus, wie ihn Charu Aggarwal
und Nan Li in \cite{aggarwal2011} vorgestellt haben, erklärt.
In dieser Arbeit wird der DYCOS-Algorithmus, wie er in \cite{aggarwal2011} vorgestellt wurde, erklärt.
Er klassifiziert automatisch Knoten in
Netzwerken, die bereits teilweise mit Labels versehen sind. Zur
Klassifizierung kann er textuelle Informationen, die den Knoten

View file

@ -6,26 +6,24 @@
title = {A Scalable Multiclass Algorithm for Node Classification},
version = {1},
date = {2011-12-19},
year = {2011},
eprinttype = {arxiv},
eprintclass = {cs.LG, cs.GT},
eprint = {http://arxiv.org/abs/1112.4344v1}
}
@inproceedings{aggarwal2011,
author = {Charu C. Aggarwal and
Nan Li},
author = {Charu C. Aggarwal AND Nan Li},
title = {On Node Classification in Dynamic Content-based Networks},
booktitle = {SDM},
year = {2011},
pages = {355-366},
ee = {http://siam.omnibooksonline.com/2011datamining/data/papers/033.pdf\#page=1},
crossref = {aggarwal2011},
bibsource = {DBLP, http://dblp.uni-trier.de}
}
@book{DBLP:series/ads/2010-40,
editor = {Charu C. Aggarwal and
Haixun Wang},
editor = {Charu C. Aggarwal AND Haixun Wang},
title = {Managing and Mining Graph Data},
booktitle = {Managing and Mining Graph Data},
publisher = {Springer},
@ -38,9 +36,7 @@
}
@inproceedings{DBLP:conf/kdd/BhagatCR07,
author = {Smriti Bhagat and
Graham Cormode and
Irina Rozenbaum},
author = {Smriti Bhagat AND Graham Cormode AND Irina Rozenbaum},
title = {Applying Link-Based Classification to Label Blogs},
booktitle = {WebKDD/SNA-KDD},
year = {2007},
@ -50,13 +46,13 @@
bibsource = {DBLP, http://dblp.uni-trier.de}
}
@proceedings{DBLP:conf/kdd/2007web,
editor = {Haizheng Zhang and
Myra Spiliopoulou and
Bamshad Mobasher and
C. Lee Giles and
Andrew McCallum and
Olfa Nasraoui and
Jaideep Srivastava and
editor = {Haizheng Zhang AND
Myra Spiliopoulou AND
Bamshad Mobasher AND
C. Lee Giles AND
Andrew McCallum AND
Olfa Nasraoui AND
Jaideep Srivastava AND
John Yen},
title = {Advances in Web Mining and Web Usage Analysis, 9th International
Workshop on Knowledge Discovery on the Web, WebKDD 2007,
@ -85,33 +81,43 @@
}
@article{Vitter,
author = {Vitter, Jeffrey S.},
title = {Random Sampling with a Reservoir},
journal = {ACM Trans. Math. Softw.},
volume = {11},
number = {1},
year = {1985},
issn = {0098-3500},
pages = {37--57},
numpages = {21},
url = {http://doi.acm.org/10.1145/3147.3165},
doi = {10.1145/3147.3165},
acmid = {3165},
author = {Vitter, Jeffrey S.},
title = {Random Sampling with a Reservoir},
journal = {ACM Trans. Math. Softw.},
volume = {11},
number = {1},
year = {1985},
issn = {0098-3500},
pages = {37--57},
numpages = {21},
url = {http://doi.acm.org/10.1145/3147.3165},
doi = {10.1145/3147.3165},
acmid = {3165},
publisher = {ACM},
address = {New York, NY, USA},
address = {New York, NY, USA},
}
@incollection{porter,
author = {Porter, M. F.},
chapter = {An Algorithm for Suffix Stripping},
title = {Readings in Information Retrieval},
editor = {Sparck Jones, Karen and Willett, Peter},
year = {1997},
isbn = {1-55860-454-5},
pages = {313--316},
numpages = {4},
url = {http://dl.acm.org/citation.cfm?id=275537.275705},
acmid = {275705},
publisher = {Morgan Kaufmann Publishers Inc.},
address = {San Francisco, CA, USA},
author = {Porter, M. F.},
chapter = {An Algorithm for Suffix Stripping},
title = {Readings in Information Retrieval},
editor = {Sparck Jones, Karen and Willett, Peter},
year = {1997},
isbn = {1-55860-454-5},
pages = {313--316},
numpages = {4},
url = {http://dl.acm.org/citation.cfm?id=275537.275705},
acmid = {275705},
publisher = {Morgan Kaufmann Publishers Inc.},
address = {San Francisco, CA, USA},
}
@incollection{szummer,
title = {Partially labeled classification with Markov random walks},
author = {Martin Szummer and Jaakkola, Tommi},
booktitle = {Advances in Neural Information Processing Systems 14},
editor = {T.G. Dietterich and S. Becker and Z. Ghahramani},
pages = {945--952},
year = {2001},
url = {http://media.nips.cc/nipsbooks/nipspapers/paper_files/nips14/AA36.pdf},
}

View file

@ -4,9 +4,9 @@
group-separator={\,},
}
\def\edges{\ensuremath{\mathcal{E}_t}}
\def\nodes{\ensuremath{\mathcal{N}_t}}
\def\labeledNodes{\ensuremath{\mathcal{T}_t}}
%\def\edges{\ensuremath{\mathcal{E}_t}}
%\def\nodes{\ensuremath{\mathcal{N}_t}}
%\def\labeledNodes{\ensuremath{\mathcal{T}_t}}
\DeclareUnicodeCharacter{00A0}{~}
\theoremstyle{definition}
@ -14,13 +14,8 @@
\theoremheaderfont{\normalfont\bfseries\hspace{-\theoremindent}}
\renewtheorem{definition}{Definition}
\def\A{\ensuremath{\mathcal{A}}}
\def\G{\ensuremath{\mathcal{G}}}
\def\L{\ensuremath{\mathcal{L}}}
\def\M{\ensuremath{\mathcal{M}}}
\def\N{\ensuremath{\mathcal{N}}}
\def\T{\ensuremath{\mathcal{T}}}
\def\powerset{\ensuremath{\mathcal{P}}}
\renewcommand{\algorithmicrequire}{\textbf{Input:}}
\renewcommand{\algorithmicensure}{\textbf{Output:}}