Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Kosaraju/00-META.yaml
Normal file
4
Task/Kosaraju/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Algorithm
|
||||
from: http://rosettacode.org/wiki/Kosaraju
|
||||
18
Task/Kosaraju/00-TASK.txt
Normal file
18
Task/Kosaraju/00-TASK.txt
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<br>
|
||||
Kosaraju's algorithm (also known as the Kosaraju–Sharir algorithm) is a linear time algorithm to find the strongly connected components of a directed graph. Aho, Hopcroft and Ullman credit it to an unpublished paper from 1978 by S. Rao Kosaraju. The same algorithm was independently discovered by Micha Sharir and published by him in 1981. It makes use of the fact that the transpose graph (the same graph with the direction of every edge reversed) has exactly the same strongly connected components as the original graph.
|
||||
<br>
|
||||
For this task consider the directed graph with these connections:
|
||||
0 -> 1
|
||||
1 -> 2
|
||||
2 -> 0
|
||||
3 -> 1, 3 -> 2, 3 -> 4
|
||||
4 -> 3, 4 -> 5
|
||||
5 -> 2, 5 -> 6
|
||||
6 -> 5
|
||||
7 -> 4, 7 -> 6, 7 -> 7
|
||||
|
||||
And report the kosaraju strongly connected component for each node.
|
||||
<br>
|
||||
;References:
|
||||
* The article on [[wp:Kosaraju's_algorithm|Wikipedia]].
|
||||
|
||||
33
Task/Kosaraju/11l/kosaraju.11l
Normal file
33
Task/Kosaraju/11l/kosaraju.11l
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
F kosaraju(g)
|
||||
V size = g.len
|
||||
V vis = [0B] * size
|
||||
V l = [0] * size
|
||||
V x = size
|
||||
V t = [[Int]()] * size
|
||||
|
||||
F visit(Int u) -> N
|
||||
I !@vis[u]
|
||||
@vis[u] = 1B
|
||||
L(v) @g[u]
|
||||
@visit(v)
|
||||
@t[v] [+]= u
|
||||
@x--
|
||||
@l[@x] = u
|
||||
|
||||
L(u) 0 .< g.len
|
||||
visit(u)
|
||||
V c = [0] * size
|
||||
|
||||
F assign(Int u, root) -> N
|
||||
I @vis[u]
|
||||
@vis[u] = 0B
|
||||
@c[u] = root
|
||||
L(v) @t[u]
|
||||
@assign(v, root)
|
||||
|
||||
L(u) l
|
||||
assign(u, u)
|
||||
R c
|
||||
|
||||
V g = [[1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7]]
|
||||
print(kosaraju(g))
|
||||
87
Task/Kosaraju/C++/kosaraju.cpp
Normal file
87
Task/Kosaraju/C++/kosaraju.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
|
||||
auto it = v.cbegin();
|
||||
auto end = v.cend();
|
||||
|
||||
os << "[";
|
||||
if (it != end) {
|
||||
os << *it;
|
||||
it = std::next(it);
|
||||
}
|
||||
while (it != end) {
|
||||
os << ", " << *it;
|
||||
it = std::next(it);
|
||||
}
|
||||
return os << "]";
|
||||
}
|
||||
|
||||
std::vector<int> kosaraju(std::vector<std::vector<int>>& g) {
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
auto size = g.size();
|
||||
std::vector<bool> vis(size); // all false by default
|
||||
std::vector<int> l(size); // all zero by default
|
||||
auto x = size; // index for filling l in reverse order
|
||||
std::vector<std::vector<int>> t(size); // transpose graph
|
||||
|
||||
// Recursive subroutine 'visit':
|
||||
std::function<void(int)> visit;
|
||||
visit = [&](int u) {
|
||||
if (!vis[u]) {
|
||||
vis[u] = true;
|
||||
for (auto v : g[u]) {
|
||||
visit(v);
|
||||
t[v].push_back(u); // construct transpose
|
||||
}
|
||||
l[--x] = u;
|
||||
}
|
||||
};
|
||||
|
||||
// 2. For each vertex u of the graph do visit(u)
|
||||
for (int i = 0; i < g.size(); ++i) {
|
||||
visit(i);
|
||||
}
|
||||
std::vector<int> c(size); // used for component assignment
|
||||
|
||||
// Recursive subroutine 'assign':
|
||||
std::function<void(int, int)> assign;
|
||||
assign = [&](int u, int root) {
|
||||
if (vis[u]) { // repurpose vis to mean 'unassigned'
|
||||
vis[u] = false;
|
||||
c[u] = root;
|
||||
for (auto v : t[u]) {
|
||||
assign(v, root);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 3: For each element u of l in order, do assign(u, u)
|
||||
for (auto u : l) {
|
||||
assign(u, u);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>> g = {
|
||||
{1},
|
||||
{2},
|
||||
{0},
|
||||
{1, 2, 4},
|
||||
{3, 5},
|
||||
{2, 6},
|
||||
{5},
|
||||
{4, 6, 7},
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace std;
|
||||
|
||||
cout << kosaraju(g) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
Task/Kosaraju/C-sharp/kosaraju.cs
Normal file
72
Task/Kosaraju/C-sharp/kosaraju.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class Node
|
||||
{
|
||||
public enum Colors
|
||||
{
|
||||
Black, White, Gray
|
||||
}
|
||||
|
||||
public Colors color { get; set; }
|
||||
public int N { get; }
|
||||
|
||||
public Node(int n)
|
||||
{
|
||||
N = n;
|
||||
color = Colors.White;
|
||||
}
|
||||
}
|
||||
|
||||
class Graph
|
||||
{
|
||||
public HashSet<Node> V { get; }
|
||||
public Dictionary<Node, HashSet<Node>> Adj { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Kosaraju's strongly connected components algorithm
|
||||
/// </summary>
|
||||
public void Kosaraju()
|
||||
{
|
||||
var L = new HashSet<Node>();
|
||||
|
||||
Action<Node> Visit = null;
|
||||
Visit = (u) =>
|
||||
{
|
||||
if (u.color == Node.Colors.White)
|
||||
{
|
||||
u.color = Node.Colors.Gray;
|
||||
|
||||
foreach (var v in Adj[u])
|
||||
Visit(v);
|
||||
|
||||
L.Add(u);
|
||||
}
|
||||
};
|
||||
|
||||
Action<Node, Node> Assign = null;
|
||||
Assign = (u, root) =>
|
||||
{
|
||||
if (u.color != Node.Colors.Black)
|
||||
{
|
||||
if (u == root)
|
||||
Console.Write("SCC: ");
|
||||
|
||||
Console.Write(u.N + " ");
|
||||
u.color = Node.Colors.Black;
|
||||
|
||||
foreach (var v in Adj[u])
|
||||
Assign(v, root);
|
||||
|
||||
if (u == root)
|
||||
Console.WriteLine();
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var u in V)
|
||||
Visit(u);
|
||||
|
||||
foreach (var u in L)
|
||||
Assign(u, u);
|
||||
}
|
||||
}
|
||||
67
Task/Kosaraju/D/kosaraju.d
Normal file
67
Task/Kosaraju/D/kosaraju.d
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import std.container.array;
|
||||
import std.stdio;
|
||||
|
||||
/* the list index is the first vertex in the edge(s) */
|
||||
auto g = [
|
||||
[1],
|
||||
[2],
|
||||
[0],
|
||||
[1, 2, 4],
|
||||
[3, 5],
|
||||
[2, 6],
|
||||
[5],
|
||||
[4, 6, 7],
|
||||
];
|
||||
|
||||
int[] kosaraju(int[][] g) {
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
auto size = g.length; // all false by default
|
||||
Array!bool vis;
|
||||
vis.length = size;
|
||||
int[] l; // all zero by default
|
||||
l.length = size;
|
||||
auto x = size; // index for filling l in reverse order
|
||||
int[][] t; // transpose graph
|
||||
t.length = size;
|
||||
|
||||
// Recursive subroutine 'visit':
|
||||
void visit(int u) {
|
||||
if (!vis[u]) {
|
||||
vis[u] = true;
|
||||
foreach (v; g[u]) {
|
||||
visit(v);
|
||||
t[v] ~= u; // construct transpose
|
||||
}
|
||||
l[--x] = u;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. For each vertex u of the graph do visit(u)
|
||||
foreach (u, _; g) {
|
||||
visit(u);
|
||||
}
|
||||
int[] c; // used for component assignment
|
||||
c.length = size;
|
||||
|
||||
// Recursive subroutine 'assign':
|
||||
void assign(int u, int root) {
|
||||
if (vis[u]) { // repurpose vis to mean 'unassigned'
|
||||
vis[u] = false;
|
||||
c[u] = root;
|
||||
foreach(v; t[u]) {
|
||||
assign(v, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3: For each element u of l in order, do assign(u, u)
|
||||
foreach (u; l) {
|
||||
assign(u, u);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void main() {
|
||||
writeln(kosaraju(g));
|
||||
}
|
||||
112
Task/Kosaraju/Delphi/kosaraju.delphi
Normal file
112
Task/Kosaraju/Delphi/kosaraju.delphi
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
program KosarajuApp;
|
||||
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
type
|
||||
TKosaraju = TArray<TArray<Integer>>;
|
||||
|
||||
var
|
||||
g: TKosaraju;
|
||||
|
||||
procedure Init();
|
||||
begin
|
||||
SetLength(g, 8);
|
||||
g[0] := [1];
|
||||
g[1] := [2];
|
||||
g[2] := [0];
|
||||
g[3] := [1, 2, 4];
|
||||
g[4] := [3, 5];
|
||||
g[5] := [2, 6];
|
||||
g[6] := [5];
|
||||
g[7] := [4, 6, 7];
|
||||
end;
|
||||
|
||||
procedure Println(vector: TArray<Integer>);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
write('[');
|
||||
if (Length(vector) > 0) then
|
||||
for i := 0 to High(vector) do
|
||||
begin
|
||||
write(vector[i]);
|
||||
if (i < high(vector)) then
|
||||
write(', ');
|
||||
end;
|
||||
|
||||
writeln(']');
|
||||
end;
|
||||
|
||||
function Kosaraju(g: TKosaraju): TArray<Integer>;
|
||||
var
|
||||
vis: TArray<Boolean>;
|
||||
L, c: TArray<Integer>;
|
||||
x: Integer;
|
||||
t: TArray<TArray<Integer>>;
|
||||
Visit: TProc<Integer>;
|
||||
u: Integer;
|
||||
Assign: TProc<Integer, Integer>;
|
||||
begin
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
|
||||
SetLength(vis, Length(g));
|
||||
SetLength(L, Length(g));
|
||||
x := Length(L);
|
||||
// index for filling L in reverse order
|
||||
SetLength(t, Length(g)); // transpose graph
|
||||
|
||||
// 2. recursive subroutine:
|
||||
|
||||
Visit := procedure(u: Integer)
|
||||
begin
|
||||
if (not vis[u]) then
|
||||
begin
|
||||
vis[u] := true;
|
||||
for var v in g[u] do
|
||||
begin
|
||||
Visit(v);
|
||||
t[v] := concat(t[v], [u]);
|
||||
// construct transpose
|
||||
end;
|
||||
|
||||
dec(x);
|
||||
L[x] := u;
|
||||
end;
|
||||
end;
|
||||
|
||||
// 2. For each vertex u of the graph do Visit(u)
|
||||
|
||||
for u := 0 to High(g) do
|
||||
begin
|
||||
Visit(u);
|
||||
end;
|
||||
|
||||
SetLength(c, Length(g)); // result, the component assignment
|
||||
|
||||
// 3: recursive subroutine:
|
||||
|
||||
Assign := procedure(u, root: Integer)
|
||||
begin
|
||||
if vis[u] then
|
||||
// repurpose vis to mean "unassigned"
|
||||
begin
|
||||
vis[u] := false;
|
||||
c[u] := root;
|
||||
|
||||
for var v in t[u] do
|
||||
Assign(v, root);
|
||||
end;
|
||||
end;
|
||||
|
||||
// 3: For each element u of L in order, do Assign(u,u)
|
||||
|
||||
for u in L do
|
||||
Assign(u, u);
|
||||
|
||||
Result := c;
|
||||
end;
|
||||
|
||||
begin
|
||||
Init;
|
||||
Println(Kosaraju(g));
|
||||
end.
|
||||
60
Task/Kosaraju/Go/kosaraju.go
Normal file
60
Task/Kosaraju/Go/kosaraju.go
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var g = [][]int{
|
||||
0: {1},
|
||||
1: {2},
|
||||
2: {0},
|
||||
3: {1, 2, 4},
|
||||
4: {3, 5},
|
||||
5: {2, 6},
|
||||
6: {5},
|
||||
7: {4, 6, 7},
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(kosaraju(g))
|
||||
}
|
||||
|
||||
func kosaraju(g [][]int) []int {
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
|
||||
vis := make([]bool, len(g))
|
||||
L := make([]int, len(g))
|
||||
x := len(L) // index for filling L in reverse order
|
||||
t := make([][]int, len(g)) // transpose graph
|
||||
// 2. recursive subroutine:
|
||||
var Visit func(int)
|
||||
Visit = func(u int) {
|
||||
if !vis[u] {
|
||||
vis[u] = true
|
||||
for _, v := range g[u] {
|
||||
Visit(v)
|
||||
t[v] = append(t[v], u) // construct transpose
|
||||
}
|
||||
x--
|
||||
L[x] = u
|
||||
}
|
||||
}
|
||||
// 2. For each vertex u of the graph do Visit(u)
|
||||
for u := range g {
|
||||
Visit(u)
|
||||
}
|
||||
c := make([]int, len(g)) // result, the component assignment
|
||||
// 3: recursive subroutine:
|
||||
var Assign func(int, int)
|
||||
Assign = func(u, root int) {
|
||||
if vis[u] { // repurpose vis to mean "unassigned"
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
for _, v := range t[u] {
|
||||
Assign(v, root)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3: For each element u of L in order, do Assign(u,u)
|
||||
for _, u := range L {
|
||||
Assign(u, u)
|
||||
}
|
||||
return c
|
||||
}
|
||||
24
Task/Kosaraju/J/kosaraju-1.j
Normal file
24
Task/Kosaraju/J/kosaraju-1.j
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
kosaraju=: {{
|
||||
coerase([cocurrent)cocreate''
|
||||
visit=: {{
|
||||
if.y{unvisited do.
|
||||
unvisited=: 0 y} unvisited
|
||||
visit y{::out
|
||||
L=: y,L
|
||||
end.
|
||||
}}"0
|
||||
assign=: {{
|
||||
if._1=y{assigned do.
|
||||
assigned=: x y} assigned
|
||||
x&assign y{::in
|
||||
end.
|
||||
}}"0
|
||||
out=: y
|
||||
in=: <@I.|:y e.S:0~i.#y
|
||||
unvisited=: 1#~#y
|
||||
assigned=: _1#~#y
|
||||
L=: i.0
|
||||
visit"0 i.#y
|
||||
assign~L
|
||||
assigned
|
||||
}}
|
||||
2
Task/Kosaraju/J/kosaraju-2.j
Normal file
2
Task/Kosaraju/J/kosaraju-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
kosaraju 1;2;0;1 2 4;3 5;2 6;5;4 6 7
|
||||
0 0 0 3 3 5 5 7
|
||||
29
Task/Kosaraju/J/kosaraju-3.j
Normal file
29
Task/Kosaraju/J/kosaraju-3.j
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
kosarajud=: {{
|
||||
coerase([cocurrent)cocreate''
|
||||
visit=: {{
|
||||
if.y{unvisited do.
|
||||
unvisited=: 0 y} unvisited
|
||||
visit y{::out
|
||||
L=: y,L
|
||||
end.
|
||||
}}"0
|
||||
assign=: {{
|
||||
if.-.y e.;assigned do.
|
||||
assigned=: (y,L:0~x{assigned) x} assigned
|
||||
x&assign y{::in
|
||||
end.
|
||||
}}"0
|
||||
out=: y
|
||||
in=: <@I.|:y e.S:0~i.#y
|
||||
unvisited=: 1#~#y
|
||||
assigned=: a:#~#y
|
||||
L=: i.0
|
||||
visit"0 i.#y
|
||||
assign~L
|
||||
assigned
|
||||
}}
|
||||
|
||||
kosarajud 1;2;0;1 2 4;3 5;2 6;5;4 6 7
|
||||
┌─────┬┬┬───┬┬───┬┬─┐
|
||||
│0 2 1│││3 4││5 6││7│
|
||||
└─────┴┴┴───┴┴───┴┴─┘
|
||||
4
Task/Kosaraju/J/kosaraju-4.j
Normal file
4
Task/Kosaraju/J/kosaraju-4.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
((<@I.@e."1 0)i.@#) 0 0 0 3 3 5 5 7
|
||||
┌─────┬┬┬───┬┬───┬┬─┐
|
||||
│0 1 2│││3 4││5 6││7│
|
||||
└─────┴┴┴───┴┴───┴┴─┘
|
||||
87
Task/Kosaraju/Java/kosaraju.java
Normal file
87
Task/Kosaraju/Java/kosaraju.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Kosaraju {
|
||||
static class Recursive<I> {
|
||||
I func;
|
||||
}
|
||||
|
||||
private static List<Integer> kosaraju(List<List<Integer>> g) {
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
int size = g.size();
|
||||
boolean[] vis = new boolean[size];
|
||||
int[] l = new int[size];
|
||||
AtomicInteger x = new AtomicInteger(size);
|
||||
|
||||
List<List<Integer>> t = new ArrayList<>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
t.add(new ArrayList<>());
|
||||
}
|
||||
|
||||
Recursive<IntConsumer> visit = new Recursive<>();
|
||||
visit.func = (int u) -> {
|
||||
if (!vis[u]) {
|
||||
vis[u] = true;
|
||||
for (Integer v : g.get(u)) {
|
||||
visit.func.accept(v);
|
||||
t.get(v).add(u);
|
||||
}
|
||||
int xval = x.decrementAndGet();
|
||||
l[xval] = u;
|
||||
}
|
||||
};
|
||||
|
||||
// 2. For each vertex u of the graph do visit(u)
|
||||
for (int i = 0; i < size; ++i) {
|
||||
visit.func.accept(i);
|
||||
}
|
||||
int[] c = new int[size];
|
||||
|
||||
Recursive<BiConsumer<Integer, Integer>> assign = new Recursive<>();
|
||||
assign.func = (Integer u, Integer root) -> {
|
||||
if (vis[u]) { // repurpose vis to mean 'unassigned'
|
||||
vis[u] = false;
|
||||
c[u] = root;
|
||||
for (Integer v : t.get(u)) {
|
||||
assign.func.accept(v, root);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 3: For each element u of l in order, do assign(u, u)
|
||||
for (int u : l) {
|
||||
assign.func.accept(u, u);
|
||||
}
|
||||
|
||||
return Arrays.stream(c).boxed().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<List<Integer>> g = new ArrayList<>();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
g.add(new ArrayList<>());
|
||||
}
|
||||
g.get(0).add(1);
|
||||
g.get(1).add(2);
|
||||
g.get(2).add(0);
|
||||
g.get(3).add(1);
|
||||
g.get(3).add(2);
|
||||
g.get(3).add(4);
|
||||
g.get(4).add(3);
|
||||
g.get(4).add(5);
|
||||
g.get(5).add(2);
|
||||
g.get(5).add(6);
|
||||
g.get(6).add(5);
|
||||
g.get(7).add(4);
|
||||
g.get(7).add(6);
|
||||
g.get(7).add(7);
|
||||
|
||||
List<Integer> output = kosaraju(g);
|
||||
System.out.println(output);
|
||||
}
|
||||
}
|
||||
58
Task/Kosaraju/Jq/kosaraju-1.jq
Normal file
58
Task/Kosaraju/Jq/kosaraju-1.jq
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Fill an array of the specified length with the input value
|
||||
def dimension($n): . as $in | [range(0;$n) | $in];
|
||||
|
||||
# $graph should be an adjacency-list graph with IO==0
|
||||
def korasaju($graph):
|
||||
($graph|length) as $length
|
||||
| def init: {
|
||||
vis: (false | dimension($length)), # visited
|
||||
L: [], # for an array of $length integers
|
||||
t: ([]|dimension($length)), # transposed graph
|
||||
x: $length # index
|
||||
};
|
||||
|
||||
# input: {vis, L, t, x, t}
|
||||
def visit($u):
|
||||
if .vis[$u] | not
|
||||
then .vis[$u] = true
|
||||
| reduce ($graph[$u][]) as $v (.;
|
||||
visit($v)
|
||||
| .t[$v] += [$u] )
|
||||
| .x -= 1
|
||||
| .L[.x] = $u
|
||||
else .
|
||||
end ;
|
||||
|
||||
# input: {vis, t, c}
|
||||
def assign($u; $root):
|
||||
if .vis[$u]
|
||||
then .vis[$u] = false
|
||||
| .c[$u] = $root
|
||||
| reduce .t[$u][] as $v (.; assign($v; $root))
|
||||
else .
|
||||
end ;
|
||||
|
||||
# For each vertex u of the graph, mark u as unvisited.
|
||||
init
|
||||
|
||||
# For each vertex u of the graph do visit(u)
|
||||
| reduce range(0;$length) as $u (.; visit($u))
|
||||
| .c = (null|dimension($length))
|
||||
|
||||
# For each element u of L in order, do assign(u, u)
|
||||
| reduce .L[] as $u (.; assign($u; $u) )
|
||||
| .c ;
|
||||
|
||||
# An example adjacency list using IO==1
|
||||
def g: [
|
||||
[1],
|
||||
[2],
|
||||
[0],
|
||||
[1, 2, 4],
|
||||
[3, 5],
|
||||
[2, 6],
|
||||
[5],
|
||||
[4, 6, 7]
|
||||
];
|
||||
|
||||
korasaju(g)
|
||||
1
Task/Kosaraju/Jq/kosaraju-2.jq
Normal file
1
Task/Kosaraju/Jq/kosaraju-2.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
[0,0,0,3,3,5,5,7]
|
||||
43
Task/Kosaraju/Julia/kosaraju.julia
Normal file
43
Task/Kosaraju/Julia/kosaraju.julia
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
function korasaju(g::Vector{Vector{T}}) where T<:Integer
|
||||
# 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
|
||||
vis = falses(length(g))
|
||||
L = Vector{T}(length(g))
|
||||
x = length(L) + 1
|
||||
t = collect(T[] for _ in eachindex(g))
|
||||
|
||||
# Recursive
|
||||
function visit(u::T)
|
||||
if !vis[u]
|
||||
vis[u] = true
|
||||
for v in g[u]
|
||||
visit(v)
|
||||
push!(t[v], u)
|
||||
end
|
||||
x -= 1
|
||||
L[x] = u
|
||||
end
|
||||
end
|
||||
# 2. For each vertex u of the graph do visit(u)
|
||||
for u in eachindex(g)
|
||||
visit(u)
|
||||
end
|
||||
c = Vector{T}(length(g))
|
||||
# 3. Recursive subroutine:
|
||||
function assign(u::T, root::T)
|
||||
if vis[u]
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
for v in t[u]
|
||||
assign(v, root)
|
||||
end
|
||||
end
|
||||
end
|
||||
# 3. For each element u of L in order, do assign(u, u)
|
||||
for u in L
|
||||
assign(u, u)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
g = [[2], [3], [1], [2, 3, 5], [4, 6], [3, 7], [6], [5, 7, 8]]
|
||||
println(korasaju(g))
|
||||
11
Task/Kosaraju/K/kosaraju-1.k
Normal file
11
Task/Kosaraju/K/kosaraju-1.k
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
F:{[g] / graph
|
||||
n: #g / number of vertices
|
||||
v::&n / visited?
|
||||
L::!0 / dfs order
|
||||
V: {[g;x] $[v x;;[v[x]:1;o[g]'g x;L::x,L]];}[g]
|
||||
V'!n / Visit
|
||||
G: @[n#,!0;g;,;!n] / transposed graph
|
||||
c::n#-1 / assigned components
|
||||
A: {[G;x;y] $[-1=c x;[c[x]:y;G[x]o[G]'y];]}[G]'
|
||||
A'/2#,L / Assign
|
||||
.=c}
|
||||
5
Task/Kosaraju/K/kosaraju-2.k
Normal file
5
Task/Kosaraju/K/kosaraju-2.k
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
F(1;2;0;1 2 4;3 5;2 6;5;4 6 7)
|
||||
(0 1 2
|
||||
3 4
|
||||
5 6
|
||||
,7)
|
||||
7
Task/Kosaraju/K/kosaraju-3.k
Normal file
7
Task/Kosaraju/K/kosaraju-3.k
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
F:{[g] /graph
|
||||
n:#g /number of vertices
|
||||
G:@[n#,!0;g;,;!n] /transposed graph
|
||||
V:{[g;L;x]$[^L?x;(1_(x,L)o[g]/g x),x;L]}[g]
|
||||
L:|V/[!0;!#g] /Visit
|
||||
A:{[G;c;u;r]$[0>c u;o[G]/[@[c;u;:;r];G u;r];c]}[G]
|
||||
.=A/[n#-1;L;L]} /Assign
|
||||
11
Task/Kosaraju/K/kosaraju-4.k
Normal file
11
Task/Kosaraju/K/kosaraju-4.k
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
F:{[g] / graph
|
||||
n: #g / number of vertices
|
||||
v::&n / visited?
|
||||
L::!0 / dfs order
|
||||
V: {[g;x] :[v x;;[v[x]:1;_f[g]'g x;L::x,L]];}[g]
|
||||
V'!n / Visit
|
||||
G: @[n#,!0;g;,;!n] / transposed graph
|
||||
c::n#-1 / assigned components
|
||||
A: {[G;x;y] :[-1=c x;[c[x]:y;G[x]_f[G]'y];]}[G]'
|
||||
A'/2#,L / Assign
|
||||
.=c}
|
||||
59
Task/Kosaraju/Kotlin/kosaraju.kotlin
Normal file
59
Task/Kosaraju/Kotlin/kosaraju.kotlin
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// version 1.1.3
|
||||
|
||||
/* the list index is the first vertex in the edge(s) */
|
||||
val g = listOf(
|
||||
intArrayOf(1), // 0
|
||||
intArrayOf(2), // 1
|
||||
intArrayOf(0), // 2
|
||||
intArrayOf(1, 2, 4), // 3
|
||||
intArrayOf(3, 5), // 4
|
||||
intArrayOf(2, 6), // 5
|
||||
intArrayOf(5), // 6
|
||||
intArrayOf(4, 6, 7) // 7
|
||||
)
|
||||
|
||||
fun kosaraju(g: List<IntArray>): List<List<Int>> {
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
val size = g.size
|
||||
val vis = BooleanArray(size) // all false by default
|
||||
val l = IntArray(size) // all zero by default
|
||||
var x = size // index for filling l in reverse order
|
||||
val t = List(size) { mutableListOf<Int>() } // transpose graph
|
||||
|
||||
// Recursive subroutine 'visit':
|
||||
fun visit(u: Int) {
|
||||
if (!vis[u]) {
|
||||
vis[u] = true
|
||||
for (v in g[u]) {
|
||||
visit(v)
|
||||
t[v].add(u) // construct transpose
|
||||
}
|
||||
l[--x] = u
|
||||
}
|
||||
}
|
||||
|
||||
// 2. For each vertex u of the graph do visit(u)
|
||||
for (u in g.indices) visit(u)
|
||||
val c = IntArray(size) // used for component assignment
|
||||
|
||||
// Recursive subroutine 'assign':
|
||||
fun assign(u: Int, root: Int) {
|
||||
if (vis[u]) { // repurpose vis to mean 'unassigned'
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
for (v in t[u]) assign(v, root)
|
||||
}
|
||||
}
|
||||
|
||||
// 3: For each element u of l in order, do assign(u, u)
|
||||
for (u in l) assign(u, u)
|
||||
|
||||
// Obtain list of SCC's from 'c' and return it
|
||||
return c.withIndex()
|
||||
.groupBy { it.value }.values
|
||||
.map { ivl -> ivl.map { it.index } }
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(kosaraju(g).joinToString("\n"))
|
||||
}
|
||||
95
Task/Kosaraju/Lua/kosaraju.lua
Normal file
95
Task/Kosaraju/Lua/kosaraju.lua
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
function write_array(a)
|
||||
io.write("[")
|
||||
for i=0,#a do
|
||||
if i>0 then
|
||||
io.write(", ")
|
||||
end
|
||||
io.write(tostring(a[i]))
|
||||
end
|
||||
io.write("]")
|
||||
end
|
||||
|
||||
function kosaraju(g)
|
||||
-- 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
local size = #g
|
||||
|
||||
local vis = {}
|
||||
for i=0,size do
|
||||
-- all false by default
|
||||
vis[i] = false
|
||||
end
|
||||
|
||||
local l = {}
|
||||
for i=0,size do
|
||||
-- all zero by default
|
||||
l[i] = 0
|
||||
end
|
||||
|
||||
local x = size+1 -- index for filling l in reverse order
|
||||
|
||||
local t = {} -- transpose graph
|
||||
|
||||
-- Recursive subroutine 'visit'
|
||||
function visit(u)
|
||||
if not vis[u] then
|
||||
vis[u] = true
|
||||
for i=0,#g[u] do
|
||||
local v = g[u][i]
|
||||
visit(v)
|
||||
if t[v] then
|
||||
local a = t[v]
|
||||
a[#a+1] = u
|
||||
else
|
||||
t[v] = {[0]=u}
|
||||
end
|
||||
end
|
||||
x = x - 1
|
||||
l[x] = u
|
||||
end
|
||||
end
|
||||
|
||||
-- 2. For each vertex u of the graph do visit(u)
|
||||
for i=0,#g do
|
||||
visit(i)
|
||||
end
|
||||
local c = {}
|
||||
for i=0,size do
|
||||
-- used for component assignment
|
||||
c[i] = 0
|
||||
end
|
||||
|
||||
-- Recursive subroutine 'assign'
|
||||
function assign(u, root)
|
||||
if vis[u] then -- repurpose vis to mean 'unassigned'
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
for i=0,#t[u] do
|
||||
local v = t[u][i]
|
||||
assign(v, root)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 3: For each element u of l in order, do assign(u, u)
|
||||
for i=0,#l do
|
||||
local u = l[i]
|
||||
assign(u, u)
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
-- main
|
||||
local g = {
|
||||
[0]={[0]=1},
|
||||
[1]={[0]=2},
|
||||
[2]={[0]=0},
|
||||
[3]={[0]=1, [1]=2, [2]=4},
|
||||
[4]={[0]=3, [1]=5},
|
||||
[5]={[0]=2, [1]=6},
|
||||
[6]={[0]=5},
|
||||
[7]={[0]=4, [1]=6, [2]=7},
|
||||
}
|
||||
|
||||
write_array(kosaraju(g))
|
||||
print()
|
||||
4
Task/Kosaraju/Mathematica/kosaraju.math
Normal file
4
Task/Kosaraju/Mathematica/kosaraju.math
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
g = Graph[{0 -> 1, 1 -> 2, 2 -> 0, 3 -> 1, 3 -> 2, 3 -> 4, 4 -> 3,
|
||||
4 -> 5, 5 -> 2, 5 -> 6, 6 -> 5, 7 -> 4, 7 -> 6, 7 -> 7}];
|
||||
cc = ConnectedComponents[g]
|
||||
Catenate[ConstantArray[Min[#], Length[#]] & /@ SortBy[cc, First]]
|
||||
46
Task/Kosaraju/Nim/kosaraju.nim
Normal file
46
Task/Kosaraju/Nim/kosaraju.nim
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
type
|
||||
Vertex = int
|
||||
Graph = seq[seq[Vertex]]
|
||||
Scc = seq[Vertex]
|
||||
|
||||
func korasaju(g: Graph): seq[Scc] =
|
||||
|
||||
var
|
||||
size = g.len
|
||||
visited = newSeq[bool](size) # All false by default.
|
||||
l = newSeq[Vertex](size) # All zero by default.
|
||||
x = size # Index for filling "l" in reverse order.
|
||||
t = newSeq[seq[Vertex]](size) # Transposed graph.
|
||||
c = newSeq[Vertex](size) # Used for component assignment.
|
||||
|
||||
func visit(u: Vertex) =
|
||||
if not visited[u]:
|
||||
visited[u] = true
|
||||
for v in g[u]:
|
||||
visit(v)
|
||||
t[v].add(u) # Construct transposed graph.
|
||||
dec x
|
||||
l[x] = u
|
||||
|
||||
func assign(u, root: Vertex) =
|
||||
if visited[u]:
|
||||
# Repurpose visited to mean 'unassigned'.
|
||||
visited[u] = false
|
||||
c[u] = root
|
||||
for v in t[u]: v.assign(root)
|
||||
|
||||
for u in 0..g.high: u.visit()
|
||||
for u in l: u.assign(u)
|
||||
|
||||
# Build list of strongly connected components.
|
||||
var prev = -1
|
||||
for v1, v2 in c:
|
||||
if v2 != prev:
|
||||
prev = v2
|
||||
result.add @[]
|
||||
result[^1].add v1
|
||||
|
||||
|
||||
when isMainModule:
|
||||
let g = @[@[1], @[2], @[0], @[1, 2, 4], @[3, 5], @[2, 6], @[5], @[4, 6, 7]]
|
||||
for scc in korasaju(g): echo $scc
|
||||
73
Task/Kosaraju/Pascal/kosaraju.pas
Normal file
73
Task/Kosaraju/Pascal/kosaraju.pas
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
program Kosaraju_SCC;
|
||||
{$mode objfpc}{$modeswitch arrayoperators}
|
||||
{$j-}{$coperators on}
|
||||
type
|
||||
TDigraph = array of array of Integer;
|
||||
|
||||
procedure PrintComponents(const g: TDigraph);
|
||||
var
|
||||
Visited: array of Boolean = nil;
|
||||
RevPostOrder: array of Integer = nil;
|
||||
gr: TDigraph = nil; //reversed graph
|
||||
Counter, Next: Integer;
|
||||
FirstItem: Boolean;
|
||||
|
||||
procedure Dfs1(aNode: Integer);
|
||||
begin
|
||||
Visited[aNode] := True;
|
||||
for Next in g[aNode] do begin
|
||||
gr[Next] += [aNode];
|
||||
if not Visited[Next] then
|
||||
Dfs1(Next);
|
||||
end;
|
||||
RevPostOrder[Counter] := aNode;
|
||||
Dec(Counter);
|
||||
end;
|
||||
|
||||
procedure Dfs2(aNode: Integer);
|
||||
begin
|
||||
Visited[aNode] := True;
|
||||
for Next in gr[aNode] do
|
||||
if not Visited[Next] then
|
||||
Dfs2(Next);
|
||||
if FirstItem then begin
|
||||
FirstItem := False;
|
||||
Write(aNode);
|
||||
end else
|
||||
Write(', ', aNode);
|
||||
end;
|
||||
|
||||
var
|
||||
Node: Integer;
|
||||
begin
|
||||
SetLength(Visited, Length(g));
|
||||
SetLength(RevPostOrder, Length(g));
|
||||
SetLength(gr, Length(g));
|
||||
Counter := High(g);
|
||||
for Node := 0 to High(g) do
|
||||
if not Visited[Node] then
|
||||
Dfs1(Node);
|
||||
FillChar(Pointer(Visited)^, Length(Visited), 0);
|
||||
for Node in RevPostOrder do
|
||||
if not Visited[Node] then begin
|
||||
FirstItem := True;
|
||||
Write('[');
|
||||
Dfs2(Node);
|
||||
WriteLn(']');
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
g: TDigraph = (
|
||||
(1),
|
||||
(2),
|
||||
(0),
|
||||
(1, 2, 4),
|
||||
(3, 5),
|
||||
(2, 6),
|
||||
(5),
|
||||
(4, 6, 7)
|
||||
);
|
||||
begin
|
||||
PrintComponents(g);
|
||||
end.
|
||||
70
Task/Kosaraju/Perl/kosaraju.pl
Normal file
70
Task/Kosaraju/Perl/kosaraju.pl
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
|
||||
sub kosaraju {
|
||||
our(%k) = @_;
|
||||
our %g = ();
|
||||
our %h;
|
||||
my $i = 0;
|
||||
$g{$_} = $i++ for sort keys %k;
|
||||
$h{$g{$_}} = $_ for keys %g; # invert
|
||||
|
||||
our(%visited, @stack, @transpose, @connected);
|
||||
sub visit {
|
||||
my($u) = @_;
|
||||
unless ($visited{$u}) {
|
||||
$visited{$u} = 1;
|
||||
for my $v (@{$k{$u}}) {
|
||||
visit($v);
|
||||
push @{$transpose[$g{$v}]}, $u;
|
||||
}
|
||||
push @stack, $u;
|
||||
}
|
||||
}
|
||||
|
||||
sub assign {
|
||||
my($u, $root) = @_;
|
||||
if ($visited{$u}) {
|
||||
$visited{$u} = 0;
|
||||
$connected[$g{$u}] = $root;
|
||||
assign($_, $root) for @{$transpose[$g{$u}]};
|
||||
}
|
||||
}
|
||||
|
||||
visit($_) for sort keys %g;
|
||||
assign($_, $_) for reverse @stack;
|
||||
|
||||
my %groups;
|
||||
for my $i (0..$#connected) {
|
||||
my $id = $g{$connected[$i]};
|
||||
push @{$groups{$id}}, $h{$i};
|
||||
}
|
||||
say join ' ', @{$groups{$_}} for sort keys %groups;
|
||||
}
|
||||
|
||||
my %test1 = (
|
||||
0 => [1],
|
||||
1 => [2],
|
||||
2 => [0],
|
||||
3 => [1, 2, 4],
|
||||
4 => [3, 5],
|
||||
5 => [2, 6],
|
||||
6 => [5],
|
||||
7 => [4, 6, 7]
|
||||
);
|
||||
|
||||
my %test2 = (
|
||||
'Andy' => ['Bart'],
|
||||
'Bart' => ['Carl'],
|
||||
'Carl' => ['Andy'],
|
||||
'Dave' => [<Bart Carl Earl>],
|
||||
'Earl' => [<Dave Fred>],
|
||||
'Fred' => [<Carl Gary>],
|
||||
'Gary' => ['Fred'],
|
||||
'Hank' => [<Earl Gary Hank>]
|
||||
);
|
||||
|
||||
kosaraju(%test1);
|
||||
say '';
|
||||
kosaraju(%test2);
|
||||
45
Task/Kosaraju/Phix/kosaraju.phix
Normal file
45
Task/Kosaraju/Phix/kosaraju.phix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">visited</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">visit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">visited</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">visited</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">visit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">v</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">v</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">u</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">l</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">u</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">assign</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">root</span><span style="color: #0000FF;">=</span><span style="color: #000000;">u</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">visited</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">visited</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">root</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">assign</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">][</span><span style="color: #000000;">v</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">root</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">korasaju</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">visited</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">visit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">u</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">assign</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">[</span><span style="color: #000000;">u</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">g</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">}}</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">korasaju</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">)</span>
|
||||
<!--
|
||||
40
Task/Kosaraju/Python/kosaraju-1.py
Normal file
40
Task/Kosaraju/Python/kosaraju-1.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
def kosaraju(g):
|
||||
class nonlocal: pass
|
||||
|
||||
# 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
size = len(g)
|
||||
|
||||
vis = [False]*size # vertexes that have been visited
|
||||
l = [0]*size
|
||||
nonlocal.x = size
|
||||
t = [[]]*size # transpose graph
|
||||
|
||||
def visit(u):
|
||||
if not vis[u]:
|
||||
vis[u] = True
|
||||
for v in g[u]:
|
||||
visit(v)
|
||||
t[v] = t[v] + [u]
|
||||
nonlocal.x = nonlocal.x - 1
|
||||
l[nonlocal.x] = u
|
||||
|
||||
# 2. For each vertex u of the graph do visit(u)
|
||||
for u in range(len(g)):
|
||||
visit(u)
|
||||
c = [0]*size
|
||||
|
||||
def assign(u, root):
|
||||
if vis[u]:
|
||||
vis[u] = False
|
||||
c[u] = root
|
||||
for v in t[u]:
|
||||
assign(v, root)
|
||||
|
||||
# 3: For each element u of l in order, do assign(u, u)
|
||||
for u in l:
|
||||
assign(u, u)
|
||||
|
||||
return c
|
||||
|
||||
g = [[1], [2], [0], [1,2,4], [3,5], [2,6], [5], [4,6,7]]
|
||||
print kosaraju(g)
|
||||
36
Task/Kosaraju/Python/kosaraju-2.py
Normal file
36
Task/Kosaraju/Python/kosaraju-2.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
def kosaraju(g):
|
||||
size = len(g)
|
||||
vis = [False] * size
|
||||
l = [0] * size
|
||||
x = size
|
||||
t = [[] for _ in range(size)]
|
||||
|
||||
def visit(u):
|
||||
nonlocal x
|
||||
if not vis[u]:
|
||||
vis[u] = True
|
||||
for v in g[u]:
|
||||
visit(v)
|
||||
t[v].append(u)
|
||||
x -= 1
|
||||
l[x] = u
|
||||
|
||||
for u in range(size):
|
||||
visit(u)
|
||||
c = [0] * size
|
||||
|
||||
def assign(u, root):
|
||||
if vis[u]:
|
||||
vis[u] = False
|
||||
c[u] = root
|
||||
for v in t[u]:
|
||||
assign(v, root)
|
||||
|
||||
for u in l:
|
||||
assign(u, u)
|
||||
|
||||
return c
|
||||
|
||||
|
||||
g = [[1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7]]
|
||||
print(kosaraju(g))
|
||||
33
Task/Kosaraju/Racket/kosaraju.rkt
Normal file
33
Task/Kosaraju/Racket/kosaraju.rkt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/dict)
|
||||
|
||||
;; G is a dictionary of vertex -> (list vertex)
|
||||
(define (Kosuraju G)
|
||||
(letrec
|
||||
((vertices (remove-duplicates (append (dict-keys G) (append* (dict-values G)))))
|
||||
(visited?-dict (make-hash)) ; or any mutable dict type
|
||||
(assigned-dict (make-hash)) ; or any mutable dict type
|
||||
(neighbours:in (λ (u) (for/list (([v outs] (in-dict G)) #:when (member u outs)) v)))
|
||||
(visit! (λ (u L)
|
||||
(cond [(dict-ref visited?-dict u #f) L]
|
||||
[else (dict-set! visited?-dict u #t)
|
||||
(cons u (for/fold ((L L)) ((v (in-list (dict-ref G u)))) (visit! v L)))])))
|
||||
(assign! (λ (u root)
|
||||
(unless (dict-ref assigned-dict u #f)
|
||||
(dict-set! assigned-dict u root)
|
||||
(for ((v (in-list (neighbours:in u)))) (assign! v root)))))
|
||||
(L (for/fold ((l null)) ((u (in-dict-keys G))) (visit! u l))))
|
||||
|
||||
(for ((u (in-list L))) (assign! u u))
|
||||
(map (curry map car) (group-by cdr (dict->list assigned-dict) =))))
|
||||
|
||||
(module+ test
|
||||
(Kosuraju '((0 1)
|
||||
(2 0)
|
||||
(5 2 6)
|
||||
(6 5)
|
||||
(1 2)
|
||||
(3 1 2 4) ; equvalent to (3 . (1 2 4))
|
||||
(4 5 3)
|
||||
(7 4 7 6))))
|
||||
51
Task/Kosaraju/Raku/kosaraju.raku
Normal file
51
Task/Kosaraju/Raku/kosaraju.raku
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
sub kosaraju (%k) {
|
||||
my %g = %k.keys.sort Z=> flat ^%k;
|
||||
my %h = %g.invert;
|
||||
my %visited;
|
||||
my @stack;
|
||||
my @transpose;
|
||||
my @connected;
|
||||
|
||||
sub visit ($u) {
|
||||
unless %visited{$u} {
|
||||
%visited{$u} = True;
|
||||
for |%k{$u} -> $v {
|
||||
visit($v);
|
||||
@transpose[%g{$v}].push: $u;
|
||||
}
|
||||
@stack.push: $u;
|
||||
}
|
||||
}
|
||||
|
||||
sub assign ($u, $root) {
|
||||
if %visited{$u} {
|
||||
%visited{$u} = False;
|
||||
@connected[%g{$u}] = $root;
|
||||
assign($_, $root) for |@transpose[%g{$u}];
|
||||
}
|
||||
}
|
||||
|
||||
.&visit for %g.keys;
|
||||
assign($_, $_) for @stack.reverse;
|
||||
|
||||
(|%g{@connected}).pairs.categorize( *.value, :as(*.key) ).values.map: { %h{|$_} };
|
||||
}
|
||||
|
||||
# TESTING
|
||||
|
||||
-> $test { say "\nStrongly connected components: ", |kosaraju($test).sort } for
|
||||
|
||||
# Same test data as all other entries, converted to a hash of lists
|
||||
(((1),(2),(0),(1,2,4),(3,5),(2,6),(5),(4,6,7)).pairs.hash),
|
||||
|
||||
# Same layout test data with named vertices instead of numbered.
|
||||
(
|
||||
%(:Andy<Bart>,
|
||||
:Bart<Carl>,
|
||||
:Carl<Andy>,
|
||||
:Dave<Bart Carl Earl>,
|
||||
:Earl<Dave Fred>,
|
||||
:Fred<Carl Gary>,
|
||||
:Gary<Fred>,
|
||||
:Hank<Earl Gary Hank>)
|
||||
)
|
||||
47
Task/Kosaraju/Sidef/kosaraju.sidef
Normal file
47
Task/Kosaraju/Sidef/kosaraju.sidef
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
func korasaju(Array g) {
|
||||
# 1. For each vertex u of the graph, mark u as unvisited. Let L be empty.
|
||||
var vis = g.len.of(false)
|
||||
var L = []
|
||||
var x = g.end
|
||||
var t = g.len.of { [] }
|
||||
|
||||
# Recursive
|
||||
func visit(u) {
|
||||
if (!vis[u]) {
|
||||
vis[u] = true
|
||||
g[u].each {|v|
|
||||
visit(v)
|
||||
t[v] << u
|
||||
}
|
||||
L[x--] = u
|
||||
}
|
||||
}
|
||||
|
||||
# 2. For each vertex u of the graph do visit(u)
|
||||
g.range.each {|u|
|
||||
visit(u)
|
||||
}
|
||||
|
||||
var c = []
|
||||
|
||||
# 3. Recursive subroutine:
|
||||
func assign(u, root) {
|
||||
if (vis[u]) {
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
t[u].each {|v|
|
||||
assign(v, root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 3. For each element u of L in order, do assign(u, u)
|
||||
L.each {|u|
|
||||
assign(u, u)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
var g = [[1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7]]
|
||||
say korasaju(g)
|
||||
76
Task/Kosaraju/Standard-ML/kosaraju.ml
Normal file
76
Task/Kosaraju/Standard-ML/kosaraju.ml
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
datatype 'a node = Node of 'a * bool ref * 'a node list ref * 'a node list ref
|
||||
|
||||
fun node x = Node (x, ref false, ref nil, ref nil)
|
||||
fun mark (Node (_, r, _, _)) = !r before r := true
|
||||
fun unmark (Node (_, r, _, _)) = !r before r := false
|
||||
|
||||
fun value (Node (x, _, _, _)) = x
|
||||
fun sources (Node (_, _, ref xs, _)) = xs
|
||||
fun targets (Node (_, _, _, ref ys)) = ys
|
||||
|
||||
fun connect (m, n) =
|
||||
let
|
||||
val Node (_, _, _, ns) = m
|
||||
val Node (_, _, ms, _) = n
|
||||
in
|
||||
ms := m :: !ms;
|
||||
ns := n :: !ns
|
||||
end
|
||||
|
||||
datatype 'a step = One of 'a | Many of 'a list
|
||||
|
||||
fun visit (ms, nil) = ms
|
||||
| visit (ms, One m :: ss) = visit (m :: ms, ss)
|
||||
| visit (ms, Many nil :: ss) = visit (ms, ss)
|
||||
| visit (ms, Many (n :: ns) :: ss) =
|
||||
if mark n then
|
||||
visit (ms, Many ns :: ss)
|
||||
else
|
||||
visit (ms, Many (targets n) :: One n :: Many ns :: ss)
|
||||
|
||||
fun assign (xs, nil) = xs
|
||||
| assign (xs, nil :: ss) = assign (xs, ss)
|
||||
| assign (xs, (n :: ns) :: ss) =
|
||||
if unmark n then
|
||||
assign (value n :: xs, sources n :: ns :: ss)
|
||||
else
|
||||
assign (xs, ns :: ss)
|
||||
|
||||
fun assigns (xs, nil) = xs
|
||||
| assigns (xs, n :: ns) =
|
||||
if unmark n then
|
||||
let
|
||||
val x = sources n :: nil
|
||||
val x = value n :: assign (nil, x)
|
||||
in
|
||||
assigns (x :: xs, ns)
|
||||
end
|
||||
else
|
||||
assigns (xs, ns)
|
||||
|
||||
fun kosaraju xs = assigns (nil, visit (nil, Many xs :: nil))
|
||||
|
||||
fun make (n, is, ijs) =
|
||||
let
|
||||
val xs = Vector.tabulate (n, node)
|
||||
fun item i = Vector.sub (xs, i)
|
||||
fun step (i, j) = connect (item i, item j)
|
||||
fun path (i :: j :: js) = (step (i, j); path (j :: js))
|
||||
| path _ = ()
|
||||
in
|
||||
map item is before app path ijs
|
||||
end
|
||||
|
||||
val is = 0 :: nil
|
||||
val ijs =
|
||||
[0, 1, 2, 0, 3, 4, 0, 5, 7] ::
|
||||
[0, 9, 10, 11, 12, 9, 11] ::
|
||||
[1, 12] ::
|
||||
[3, 5, 6, 7, 8, 6, 15] ::
|
||||
[5, 13, 14, 13, 15] ::
|
||||
[8, 15] ::
|
||||
[10, 13] ::
|
||||
nil
|
||||
|
||||
val ns = make (16, is, ijs)
|
||||
val xs = kosaraju ns
|
||||
60
Task/Kosaraju/Swift/kosaraju.swift
Normal file
60
Task/Kosaraju/Swift/kosaraju.swift
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
func kosaraju(graph: [[Int]]) -> [Int] {
|
||||
let size = graph.count
|
||||
var x = size
|
||||
var vis = [Bool](repeating: false, count: size)
|
||||
var l = [Int](repeating: 0, count: size)
|
||||
var c = [Int](repeating: 0, count: size)
|
||||
var t = [[Int]](repeating: [], count: size)
|
||||
|
||||
func visit(_ u: Int) {
|
||||
guard !vis[u] else {
|
||||
return
|
||||
}
|
||||
|
||||
vis[u] = true
|
||||
|
||||
for v in graph[u] {
|
||||
visit(v)
|
||||
t[v].append(u)
|
||||
}
|
||||
|
||||
x -= 1
|
||||
l[x] = u
|
||||
}
|
||||
|
||||
for u in 0..<graph.count {
|
||||
visit(u)
|
||||
}
|
||||
|
||||
func assign(_ u: Int, root: Int) {
|
||||
guard vis[u] else {
|
||||
return
|
||||
}
|
||||
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
|
||||
for v in t[u] {
|
||||
assign(v, root: root)
|
||||
}
|
||||
}
|
||||
|
||||
for u in l {
|
||||
assign(u, root: u)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
let graph = [
|
||||
[1],
|
||||
[2],
|
||||
[0],
|
||||
[1, 2, 4],
|
||||
[3, 5],
|
||||
[2, 6],
|
||||
[5],
|
||||
[4, 6, 7]
|
||||
]
|
||||
|
||||
print(kosaraju(graph: graph))
|
||||
64
Task/Kosaraju/Visual-Basic-.NET/kosaraju.vb
Normal file
64
Task/Kosaraju/Visual-Basic-.NET/kosaraju.vb
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
Module Module1
|
||||
|
||||
Function Kosaraju(g As List(Of List(Of Integer))) As List(Of Integer)
|
||||
Dim size = g.Count
|
||||
Dim vis(size - 1) As Boolean
|
||||
Dim l(size - 1) As Integer
|
||||
Dim x = size
|
||||
|
||||
Dim t As New List(Of List(Of Integer))
|
||||
For i = 1 To size
|
||||
t.Add(New List(Of Integer))
|
||||
Next
|
||||
|
||||
Dim visit As Action(Of Integer) = Sub(u As Integer)
|
||||
If Not vis(u) Then
|
||||
vis(u) = True
|
||||
For Each v In g(u)
|
||||
visit(v)
|
||||
t(v).Add(u)
|
||||
Next
|
||||
x -= 1
|
||||
l(x) = u
|
||||
End If
|
||||
End Sub
|
||||
|
||||
For i = 1 To size
|
||||
visit(i - 1)
|
||||
Next
|
||||
Dim c(size - 1) As Integer
|
||||
|
||||
Dim assign As Action(Of Integer, Integer) = Sub(u As Integer, root As Integer)
|
||||
If vis(u) Then
|
||||
vis(u) = False
|
||||
c(u) = root
|
||||
For Each v In t(u)
|
||||
assign(v, root)
|
||||
Next
|
||||
End If
|
||||
End Sub
|
||||
|
||||
For Each u In l
|
||||
assign(u, u)
|
||||
Next
|
||||
|
||||
Return c.ToList
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Dim g = New List(Of List(Of Integer)) From {
|
||||
New List(Of Integer) From {1},
|
||||
New List(Of Integer) From {2},
|
||||
New List(Of Integer) From {0},
|
||||
New List(Of Integer) From {1, 2, 4},
|
||||
New List(Of Integer) From {3, 5},
|
||||
New List(Of Integer) From {2, 6},
|
||||
New List(Of Integer) From {5},
|
||||
New List(Of Integer) From {4, 6, 7}
|
||||
}
|
||||
|
||||
Dim output = Kosaraju(g)
|
||||
Console.WriteLine("[{0}]", String.Join(", ", output))
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
38
Task/Kosaraju/Wren/kosaraju.wren
Normal file
38
Task/Kosaraju/Wren/kosaraju.wren
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
var kosaraju = Fn.new { |g|
|
||||
var gc = g.count
|
||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||
var vis = List.filled(gc, false)
|
||||
var l = List.filled(gc, 0)
|
||||
var x = gc // index for filling l in reverse order
|
||||
var t = List.filled(gc, null) // transpose graph
|
||||
for (i in 0...gc) t[i] = []
|
||||
var visit // recursive function
|
||||
visit = Fn.new { |u|
|
||||
if (!vis[u]) {
|
||||
vis[u] = true
|
||||
for (v in g[u]) {
|
||||
visit.call(v)
|
||||
t[v].add(u) // construct transpose
|
||||
}
|
||||
x = x - 1
|
||||
l[x] = u
|
||||
}
|
||||
}
|
||||
// 2. For each vertex u of the graph do visit.call(u).
|
||||
for (i in 0...gc) visit.call(i)
|
||||
var c = List.filled(gc, 0) // result, the component assignment
|
||||
var assign // recursive function
|
||||
assign = Fn.new { |u, root|
|
||||
if (vis[u]) { // repurpose vis to mean 'unassigned'
|
||||
vis[u] = false
|
||||
c[u] = root
|
||||
for (v in t[u]) assign.call(v, root)
|
||||
}
|
||||
}
|
||||
// 3: For each element u of l in order, do assign.call(u,u).
|
||||
for (u in l) assign.call(u, u)
|
||||
return c
|
||||
}
|
||||
|
||||
var g = [ [1], [2], [0], [1, 2, 4], [3, 5], [2, 6], [5], [4, 6, 7] ]
|
||||
System.print(kosaraju.call(g))
|
||||
41
Task/Kosaraju/Zkl/kosaraju-1.zkl
Normal file
41
Task/Kosaraju/Zkl/kosaraju-1.zkl
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
const VISITED=0,ASSIGNED=1;
|
||||
|
||||
fcn visit(u,G,L){ // u is ((visited,assigned), (id,edges))
|
||||
u0:=u[0];
|
||||
if(u0[VISITED]) return();
|
||||
u0[VISITED]=True;
|
||||
foreach idx in (u[1][1,*]){ visit(G[idx],G,L) } // vist out-neighbours
|
||||
L.insert(0,u); // prepend u to L
|
||||
}
|
||||
fcn assign(u,root,G){ // u as above, root is a list of strong components
|
||||
u0:=u[0];
|
||||
if(u0[ASSIGNED]) return();
|
||||
root.append(u[1][0]);
|
||||
u0[ASSIGNED]=True;
|
||||
uid:=u[1][0];
|
||||
foreach v in (G){ // traverse graph to find in-neighbours, fugly
|
||||
n,ins := v[1][0],v[1][1,*];
|
||||
if(ins.holds(uid)) assign(G[n],root,G); // assign in-neighbour
|
||||
}
|
||||
}
|
||||
fcn kosaraju(graph){ // Use Tarjan's algorithm instead of this one
|
||||
// input: graph G = (V, Es)
|
||||
// output: set of strongly connected components (sets of vertices)
|
||||
|
||||
// convert graph to ( (index,lowlink,onStack),(id,links)), ...)
|
||||
// sorted by id
|
||||
G:=List.createLong(graph.len(),0);
|
||||
foreach v in (graph){ G[v[0]]=T( List(False,False),v) }
|
||||
|
||||
L:=List();
|
||||
foreach u in (G){ visit(u,G,L) }
|
||||
|
||||
components:=List.createLong(graph.len(),List.copy,True);
|
||||
foreach u in (L){ assign(u,components[u[1][0]],G) }
|
||||
components=components.filter();
|
||||
|
||||
println("List of strongly connected components:");
|
||||
foreach c in (components){ println(c.reverse().concat(",")) }
|
||||
|
||||
return(components);
|
||||
}
|
||||
7
Task/Kosaraju/Zkl/kosaraju-2.zkl
Normal file
7
Task/Kosaraju/Zkl/kosaraju-2.zkl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// graph from https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
|
||||
// with vertices id zero based (vs 1 based in article)
|
||||
// ids start at zero and are consecutive (no holes), graph is unsorted
|
||||
graph:= // ( (id, links/Edges), ...)
|
||||
T( T(0,1), T(2,0), T(5,2,6), T(6,5),
|
||||
T(1,2), T(3,1,2,4), T(4,5,3), T(7,4,7,6) );
|
||||
kosaraju(graph);
|
||||
Loading…
Add table
Add a link
Reference in a new issue