Skip to content

Commit

Permalink
Merge pull request #1 from james-d-mitchell/conn
Browse files Browse the repository at this point in the history
Slight clean up
  • Loading branch information
ffloresbrito authored Dec 6, 2017
2 parents 05adc1b + db883eb commit de81d16
Showing 1 changed file with 85 additions and 86 deletions.
171 changes: 85 additions & 86 deletions gap/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1583,126 +1583,126 @@ function(gr)
return fail;
end);

InstallMethod(VertexConnectivity,
"for a digraph",
[IsDigraph],
InstallMethod(VertexConnectivity, "for a digraph", [IsDigraph],
function(digraph)
local degs, edges, edmondskarp, indegs, k, kappas, mindegv, newnetw, Nv,
outdegs, outn, sdigraph, set1v, x, y;
local kappas, newnetw, edmondskarp, mat, degs, mindegv, mindeg, Nv, outn, k, i, j, x, y;

if DigraphNrVertices(digraph) <= 1 or not IsConnectedDigraph(digraph) then
return 0;
fi;

if IsMultiDigraph(digraph) then
sdigraph := DigraphRemoveAllMultipleEdges(digraph);
else
sdigraph := digraph;
digraph := DigraphRemoveAllMultipleEdges(digraph);
fi;

kappas := [DigraphNrVertices(digraph) - 1];

# The function newnetw is an implementation of Algorithm Nine from Abdol-Hossein
# Esfahanian's ``Connectivity Algorithms'' which can be found at
# https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
newnetw := function(source, sink)
local decide, lst, noutn, x, y;
noutn := List([1 .. (Size(outn) - 2) * 2 + 2], x -> []);

decide := function(p, q)
local cor;
cor := (q - 1) * 2 + 1;
if p = source then
lst{[cor, cor + 1]} := [1, 1];
elif p = sink then
lst{[cor, cor + 1]} := [2, 2];
else
if p > source or p > sink then
if p > source and p > sink then
lst[cor] := (p - 2) * 2 + q;
else
lst[cor] := (p - 1) * 2 + q;
fi;
else
lst[cor] := p * 2 + q;
fi;
lst[cor + 1] := lst[cor] + 1 * (-1) ^ (q + 1);
# The function newnetw is an implementation of Algorithm Nine from Abdol-Hossein
# Esfahanian's ``Connectivity Algorithms'' which can be found at
# https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
newnetw := function(digraph, source, sink)
local n, mat, outn, x, y;
n := DigraphNrVertices(digraph);
mat := List([1 .. 2 * n], x -> BlistList([1 .. 2 * n], []));
outn := OutNeighbours(digraph);
for x in [1 .. DigraphNrVertices(digraph)] do
if x <> source and x <> sink then
mat[x + n][x] := true;
fi;
end;

lst := [0, 0, 0, 0];
for x in [1 .. Size(outn)] do
decide(x, 1);
for y in outn[x] do
decide(y, 2);
AddSet(noutn[lst[1]], lst[3]);
AddSet(noutn[lst[4]], lst[2]);
if x = source or x = sink then
mat[x][y + n] := true;
mat[y][x] := true;
elif y = source or y = sink then
mat[y][x + n] := true;
mat[x][y] := true;
else
mat[y][x + n] := true;
mat[x][y + n] := true;
fi;
od;
od;
return List(mat, x -> ListBlist([1 .. 2 * n], x));
end;

for x in [1 .. Size(outn) - 2] do
Add(noutn[x * 2 + 2], x * 2 + 1);
od;
return noutn;
end;
# The following function is an implementation of the Edmonds-Karp algorithm with
# some minor adjustments that take into account the fact that the capacity of
# all edges is 1.
edmondskarp := function(netw, source, sink)
local flow, capacity, nredges, queue, m, predecessor, edgeindex, stop,
current, n, v;

# The following function is an implementation of the Edmonds-Karp algorithm with
# some minor adjustments that take into account the fact that the capacity of
# all edges is 1.
edmondskarp := function(netw)
local capacity, current, e, flag, flow, m, n, predecessor, queue;
flag := true;
flow := 0;
capacity := List(netw, x -> BlistList(x, x));
nredges := Sum(List(netw, Length));

while flag do
queue := [1];
while true do
queue := [source];
m := 1;
predecessor := List(netw, x -> 0);

m := 1;
while m <= Size(queue) do
edgeindex := List(netw, x -> 0);
stop := false;
while m <= Size(queue) and not stop do
current := queue[m];

n := 0;
for e in netw[current] do
for v in netw[current] do
n := n + 1;
if predecessor[e] = 0 and e <> 1 and capacity[current][n] then
predecessor[e] := [current, n];
Add(queue, e);
if predecessor[v] = 0 and v <> source and capacity[current][n] then
predecessor[v] := current;
edgeindex[v] := n;
Add(queue, v);
fi;
if v = sink then
stop := true;
break;
fi;
od;
m := m + 1;
od;

if predecessor[2] <> 0 then
e := predecessor[2];
while e <> 0 do
capacity[e[1]][e[2]] := false;
e := predecessor[e[1]];
if predecessor[sink] <> 0 then
v := predecessor[sink];
n := edgeindex[sink];
while v <> 0 do
capacity[v][n] := false;
n := edgeindex[v];
v := predecessor[v];
od;
flow := flow + 1;
else
flag := false;
return flow;
fi;
od;
return flow;
end;

# Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
# the following lines implement Algorithm Eleven of that paper.
outdegs := OutDegrees(sdigraph);
indegs := InDegrees(sdigraph);
degs := List([1 .. Size(outdegs)], x -> Maximum(outdegs[x], indegs[x]));
mindegv := Position(degs, Minimum(degs));
set1v := ShallowCopy(DigraphVertices(sdigraph));
Remove(set1v, mindegv);
Nv := OutNeighboursOfVertex(sdigraph, mindegv);
outn := OutNeighbours(sdigraph);

for x in set1v do
if not x in outn[mindegv] and not mindegv in outn[x] then
k := edmondskarp(newnetw(mindegv, x));
# Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
# the following lines implement Algorithm Eleven of that paper.
mat := BooleanAdjacencyMatrix(digraph);
degs := ListWithIdenticalEntries(DigraphNrVertices(digraph), 0);
for i in DigraphVertices(digraph) do
for j in [i + 1 .. DigraphNrVertices(digraph)] do
if mat[i][j] or mat[j][i] then
degs[i] := degs[i] + 1;
degs[j] := degs[j] + 1;
fi;
od;
od;

mindegv := 0;
mindeg := DigraphNrVertices(digraph) + 1;
for i in DigraphVertices(digraph) do
if degs[i] < mindeg then
mindeg := degs[i];
mindegv := i;
fi;
od;

Nv := OutNeighboursOfVertex(digraph, mindegv);
outn := OutNeighbours(digraph);

for x in DigraphVertices(digraph) do
if x <> mindegv and not mat[x][mindegv] and not mat[mindegv][x] then
k := edmondskarp(newnetw(digraph, mindegv, x), mindegv, x);
if k = 0 then
return 0;
else
Expand All @@ -1713,9 +1713,8 @@ function(digraph)

for x in [1 .. Size(Nv) - 1] do
for y in [x + 1 .. Size(Nv)] do
if not Nv[y] in outn[Nv[x]] and not Nv[x] in outn[Nv[y]] then
k := edmondskarp(newnetw(Nv[x], Nv[y]));

if not mat[Nv[x]][Nv[y]] and not mat[Nv[y]][Nv[x]] then
k := edmondskarp(newnetw(digraph, Nv[x], Nv[y]), Nv[x], Nv[y]);
if k = 0 then
return 0;
else
Expand Down

0 comments on commit de81d16

Please sign in to comment.