diff --git a/Gruntfile.js b/Gruntfile.js index 0e5ad77..9b72e8d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,7 +10,7 @@ module.exports = function(grunt) { options: { port: port, base: base, - livereload: true, + livereload: false, open: true } } @@ -18,7 +18,7 @@ module.exports = function(grunt) { watch: { options: { - livereload: true + livereload: false }, // js: { // files: [ 'Gruntfile.js', 'js/reveal.js' ], diff --git a/documentation/contents/chapter3-background.tex b/documentation/contents/chapter3-background.tex index d3cc76b..712ac33 100644 --- a/documentation/contents/chapter3-background.tex +++ b/documentation/contents/chapter3-background.tex @@ -69,6 +69,19 @@ \section{The \maxflow{}} \section{\pushRelabel{}} +The push-relabel algorithm operates locally and does not, in contrast to the less efficient globally operating maximum flow algorithms based on augmenting paths, maintain a feasible flow during the algorithm execution. Instead, it maintains a preflow. The capacity constraints of the edges are still maintainted, but the flow conservation at the nodes is not: + +\begin{definition}[preflow] + The preflow $\tilde f$ is a generalization of the flow $f$, the equality sign $=$ in the flow conservation is replaced with $\geq$. This means that more flow can enter an inner node than leaving it, e.g. we allow leaks in our pipe system. +\end{definition} + +Another important concept in in the push-relabel algorithm is the height function, which is an approximation of the distance of a node towards the sink. The local \textit{push} operations try to move \textit{excess} at inner nodes 'downwards' towards the sink. If the current node is at a local minimum and still has excess, we \textit{relabel} the node by increasing its \textit{height} so that subsequent push operations can remove the excess. +\begin{definition}[valid edge with respect to the height function] + An edge $e'=(v,w)$ of the \textbf{residual graph} is valid with respect to the current height function, if $h(v)==h(w)+1$, meaning that the current node is one level above the one to where we wish to push excess to. +\end{definition} + +The important property of the push-relabel algorithm is that when the algorithm terminates, the computed preflow is actually a flow! + \input{pseudocode/pseudocode-maxflow} @@ -106,10 +119,9 @@ \section{The \spprc{}} \begin{example}[SPPTW] An illustrative example is the two-resource SPPRC, the shortest path problem with time windows (SPPTW). In addition to the \textit{cost} $c$, each edge additionally bears the resource \textit{time} $t$. Thus each edge is associated with the two-dimensional resource vector $(t,c) \forall e \in E$. The secondary resource \textit{time} is constrained, while the primary resource \textit{cost} is unconstrained, but seeks to be minimized. -The accumulated consumptions of the resource \textit{time} along a path are constrained at the intermediate vertices along that path by lower and upper limits, that is the earliest arrival time $t_a$ and the latest departure time $t_b$ and called the \textit{resource window}, denoted as a tuple $[t_a,t_b] \forall v \in V$. +The accumulated consumptions of the resource \textit{time} along a path are constrained at the intermediate vertices along that path by lower and upper limits, that is the earliest arrival time $t_a$ and the latest departure time $t_b$ and called the \textit{resource window}, denoted as tuples $[t_a,t_b] \, \forall v \in V$. \end{example} -$[t_{arrival},t_{departure}] \forall v \in V$ \section{\labelSetting{}} diff --git a/documentation/pseudocode/pseudocode-maxflow.tex b/documentation/pseudocode/pseudocode-maxflow.tex index 16bcbbb..96e6a26 100644 --- a/documentation/pseudocode/pseudocode-maxflow.tex +++ b/documentation/pseudocode/pseudocode-maxflow.tex @@ -6,42 +6,39 @@ \begin{algorithm}[h!] \caption{Goldberg-Tarjan Push-Relabel algorithm} -\DontPrintSemicolon % Some LaTeX compilers require you to use \dontprintsemicolon instead -\KwIn{directed Graph $G=(V,E)$ with -\begin{itemize} - \setlength\itemsep{0pt} - \setlength{\parskip}{0pt} - \item digraph $G=(V,E)$ with start $s$, sink $t$ - \item $\forall$ edges $e \in E$: (cap) capacity -\end{itemize} +\DontPrintSemicolon +\KwIn{digraph $G=(V,E)$ with nodes $s,t \in V$ and edge capacities $c(e) \, \forall e \in E$ +%\begin{itemize} +% \setlength\itemsep{0pt} +% \setlength{\parskip}{0pt} +% \item nodes start $s \in V$, sink $t \in V$ +% \item edge capacities $c(e) \, \forall e \in E$ +%\end{itemize} } \KwOut{A feasible maximum s-t flow f(e)}\vspace{0.2cm} (* Initialize the preflow *)\; \ForAll{$e=(u,w) \in E$}{ - \If{$u==s$}{ - $f(e) \gets c(e)$\; - \If{$w \neq t$}{$Q$.add(w)} - } - \Else{$f(e) \gets 0$} + $f(e) \gets (u==s) \; ? \; c(e) : 0$\; + \If{$u==s$ AND $w \neq t$}{$Q$.add(w)} } ((* Initialize the height function *))\; -$h(s) = |V|$\; -\ForAll{$v \in V$}{ - $h(v) \gets$ number of arcs on directed v-t path\; +$h(s) \gets |V|$\; +\ForAll{$v \in V \setminus \{s \}$}{ + $h(v) \gets$ number of arcs on shortest v-t path\; } ((* Main Loop *))\; \While{$\setfont{Q} \neq \emptyset$}{ $v \gets \setfont{Q}$.pop()\; - \While{$e(v)>0$ AND $\exists e'=(v,w) \in E' | h(v)==h(w)+1$}{ + \While{$e(v)>0$ AND $\exists \, e'=(v,w) \in E' \, | \, h(v)==h(w)+1$}{ (* Push *)\; push $\min(e(v),c'(e'))$ flow from v to w\; \If{$w \neq s,t$ AND $w \notin \setfont{Q}$}{ $\setfont{Q}$.add($w$)\; } } - \If{$e(v)>0$ AND $\not\exists e'=(v,w) \in E' | h(v)==h(w)+1$}{ + \If{$e(v)>0$}{ (* Relabel *)\; - $h(v) \gets 1 + \min(h(w) | e*=(v,w)\in E'$ \; + $h(v) \gets 1 + \min(\{h(w) | e^*=(v,w)\in E'\})$ \; $\setfont{Q}$.add($v$) \; } } diff --git a/documentation/pseudocode/pseudocode-spprc.tex b/documentation/pseudocode/pseudocode-spprc.tex index a977f9f..147d393 100644 --- a/documentation/pseudocode/pseudocode-spprc.tex +++ b/documentation/pseudocode/pseudocode-spprc.tex @@ -6,34 +6,30 @@ \begin{algorithm}[h!] \DontPrintSemicolon % Some LaTeX compilers require you to use \dontprintsemicolon instead -\KwIn{directed Graph $G=(V,E)$ with -\begin{itemize} - \setlength\itemsep{0pt} - \setlength{\parskip}{0pt} - \item $\forall$ nodes $v \in V$: [arrive, depart] time window resource constraint - \item $\forall$ edges $e \in E$: (time,cost) 2-dimensional resource consumptions - \item start Node $s$, end Node $t$ -\end{itemize}} -\KwOut{feasible, pareto-optimal $s \rightarrow t$ paths} \vspace{0.2cm} +\KwIn{digraph $G=(V,E)$ with start node $s \in V$, target node $t \in V$, resource windows for all nodes %$[t_a, t_d] \, \forall v \in V$ +and resource vectors for all edges} %$(t,c) \, \forall e \in E$} +\KwOut{feasible, pareto-optimal $s$-$t$ path $l^*$ with minimal cost} \vspace{0.2cm} (* Initialize *) \; -SET $\setfont{U} = \{(s)\}$ and $\setfont{P} = \emptyset$ \; -\While{$\setfont{U} \neq \emptyset$}{ +$U \gets \{(\epsilon,s)\}$ and $P \gets \emptyset$ \; +(* Main Loop *) \; +\While{$\exists l=(\sim,v) \in U$}{ + $U \gets U \setminus \{l\}$\; (* Path extension step *)\; - CHOOSE a path $\setfont{Q} \in \setfont{U}$ and REMOVE $\setfont{Q}$ from $\setfont{U}$\; - \ForAll{arcs $(v(\setfont{Q}), w) \in A$ of the forward star of $v(\setfont{Q})$}{ - \If{$(\setfont{Q},w) \in \setfont{F}(s,w) \cap \setfont{G}$}{ - ADD $(\setfont{Q},w)$ to $\setfont{U}$ + \ForAll{$e=(v,w) \in E$}{ + $l'=(l,w) \gets$ EXTEND$(l,e)$\; + \If{$l' \in \mathrm{FEASIBLE}(w)$}{ + $U \gets U \cup \{l'\}$\; } } - ADD $\setfont{Q}$ to $\setfont{P}$\; + $P \gets P \cup \{l\}$\; (* Dominance step *)\; - \If{(* any condition *)}{ - APPLY dominance algorithm to paths from $\setfont{U} \cup \setfont{P}$ ending at some node $v$\; + \ForAll{$v \in V\setminus\{s\}$}{ + $U,P \gets$ REMOVE-DOMINATED$(U,P)$\; } } -(* Filtering step *)\; -FILTER $\setfont{P}$, i.e., identify a solution $\setfont{S} \subseteq \setfont{P}$\; -\caption{Generic Dynamic Programming SPPRC Algorithm} +((* Filtering step *))\; +$l^* \in P \; | \; cost(l^*) ==\min( \{ cost(l=(\sim,t)\in P) \} )$\; +\caption{Generic Dynamic Programming SPPTW Label Setting Algorithm} \end{algorithm} diff --git a/implementation/library-d3-svg/js/AlgorithmTab.js b/implementation/library-d3-svg/js/AlgorithmTab.js index e7510f1..4826926 100644 --- a/implementation/library-d3-svg/js/AlgorithmTab.js +++ b/implementation/library-d3-svg/js/AlgorithmTab.js @@ -88,7 +88,7 @@ function AlgorithmTab(algo,p_tab) { return "pseudocode"; }); - d3.select("#tw_div_statusPseudocode").text(pseudocode.text()) + d3.select("#tw_div_statusPseudocode").html(pseudocode.html()) Tab.prototype.init.call(this); diff --git a/implementation/library-d3-svg/js/GraphDrawer.js b/implementation/library-d3-svg/js/GraphDrawer.js index 04cf899..d08ddbf 100644 --- a/implementation/library-d3-svg/js/GraphDrawer.js +++ b/implementation/library-d3-svg/js/GraphDrawer.js @@ -101,7 +101,7 @@ GraphDrawer = function(svgOrigin,extraMargin,transTime){ left: global_KnotenRadius+wS +(extraMargin.left || 0) } - var width = xRange - margin.left - margin.right, + var width = xRange - margin.left - margin.right; var height = yRange - margin.top - margin.bottom; this.height = height; diff --git a/implementation/maxflow-push-relabel/index_en.html b/implementation/maxflow-push-relabel/index_en.html index 8780043..ff639e3 100644 --- a/implementation/maxflow-push-relabel/index_en.html +++ b/implementation/maxflow-push-relabel/index_en.html @@ -416,27 +416,25 @@

Finished

s ← pick(v)

t ← pick(v)

BEGIN

-

(* Initializing the preflow *)

-

FORALL e=(u,w) ∈ E

-

IF u == s THEN f(e) ← c(e)

-

ELSE f(e) ← 0

-

IF u == s AND w ≠ t THEN Q.add(w)

-

(* Initializing the height function *)

-

h(s) = |V|

-

FORALL v ∈ V\{s}

-

h(v) ← #arcs on directed v-t path

+

(* Initialize the preflow *)

+

FORALL e=(u,w) ∈ E

+

f(e) ← (u == s) ? c(e) : 0

+

IF u == s AND w ≠ t THEN Q.add(w)

+

(* Initialize the height function *)

+

h(s) ← |V|

+

FORALL v ∈ V\{s}

+

h(v) ← #arcs on shortest v-t path

(* Main Loop *)

-

WHILE Q ≠ ∅

-

v ← Q.pop()

-

WHILE e(v)>0

-

AND ∃ e'=(v,w)∈E'|h(v)==h(w)+1

-

(* PUSH *)

-

push min{e(v),c'(e')} flow from v to w

-

IF w != s,t AND w ∉ Q THEN Q.add(w)

-

IF e(v)>0 AND ∄ e'=(v,w)∈E'|h(v)==h(w)+1

-

(* RELABEL *)

-

h(v) ← 1+min{h(w)|e*=(v,w)∈E'}

-

Q.add(v)

+

WHILE Q ≠ ∅

+

v ← Q.pop()

+

WHILE e(v)>0 AND ∃ e'=(v,w)∈E'|h(v)==h(w)+1

+

(* PUSH *)

+

push min(e(v),c'(e')) flow from v to w

+

IF w ≠ s,t AND w ∉ Q THEN Q.add(w)

+

IF e(v)>0

+

(* RELABEL *)

+

h(v) ← 1+min({h(w)|e*=(v,w)∈E'})

+

Q.add(v)

END

@@ -544,8 +542,10 @@

What is the pseudocode of the algorithm?

The flow value of f(e) is maximized along all feasible flows
-

-
+ +
+

How fast is the algorithm?

diff --git a/implementation/spp-rc-label-setting/index_en.html b/implementation/spp-rc-label-setting/index_en.html index 91b8034..ea3c55b 100644 --- a/implementation/spp-rc-label-setting/index_en.html +++ b/implementation/spp-rc-label-setting/index_en.html @@ -421,31 +421,31 @@

Filtering step

var STATUS_DOMINANCE = id++; var STATUS_DOMINANCE_NODE = id++; var STATUS_FINISHED = id;--> -
-

s ← pick(v)

-

BEGIN

-

(* Initialize *)

-

U ← {(ε,s)}, P ← ∅

-

(* Main Loop *)

-

WHILE ∃ l=(~,v) ∈ U

- -

(* Path extension step *)

-

FORALL e=(v,w) ∈ E

-

l'=(l,w) ← EXTEND(l,e)

-

IF l' ∈ FEASIBLE(w)

-

U ← U ∪ {l'}

-

ELSE

-

throw away l'

-

P ← P ∪ {l}

-

(* Dominance step *)

-

FORALL v ∈ V\{s}

-

U,P ← REMOVE-DOMINATED(U,P)

-

END

-

t ← pick(v)

-

(* Filtering step *)

-

solution ← l=(~,t) ∈ P :

-

cost(l) = min(cost(l)) ∀ l=(~,t) ∈ P

+
+

s ← pick(v)

+

BEGIN

+

(* Initialize *)

+

U ← {(ε,s)} and P ← ∅

+

(* Main Loop *)

+

WHILE ∃ l=(~,v) ∈ U

+

U ← U \ {l}

+

(* Path extension step *)

+

FORALL e=(v,w) ∈ E

+

l'=(l,w) ← EXTEND(l,e)

+

IF l' ∈ FEASIBLE(w)

+

U ← U ∪ {l'}

+

ELSE

+

throw away l'

+

P ← P ∪ {l}

+

(* Dominance step *)

+

FORALL v ∈ V\{s}

+

U,P ← REMOVE-DOMINATED(U,P)

+

END

+

(* Filtering step *)

+

t ← pick(v)

+

l* ∈ P | cost(l*) == min({cost(l=(~,t)∈P)})

Variable status

@@ -560,14 +560,17 @@

Negative cycles: Label-setting vs. Label-correcting

What is the pseudocode of the algorithm?


-Input:  Weighted, undirected graph G=(V,E) with weight function l.
-Output: A list {d(v[j]) : j = 1,..,n} containing the distances dist(v[1],v[j]) = d(v[j]),
-         if there are no negative circles reachable from v[1]. 
-         The message "Negative Circle" is shown, if a negative circle can be reached from v[1].
+Input:  directed graph G=(V,E) with 
+        start node s and end node t
+        resource windows for all nodes
+        resource vectors for all edges
+Output: feasible, pareto-optimal s-t path l* with minimal cost
 

-

-
+ +
+

How fast is the algorithm?