@@ -2408,3 +2408,146 @@ function(D)
2408
2408
M := List(DigraphLoops(D), x -> [ x, x] );
2409
2409
return Union(M, DIGRAPHS_MateToMatching(D, mateD));
2410
2410
end );
2411
+
2412
+ InstallMethod(VertexConnectivity, " for a digraph" , [ IsDigraph] ,
2413
+ function (digraph )
2414
+ local kappas, newnetw, edmondskarp, mat, degs, mindegv, mindeg, Nv, outn, k,
2415
+ i, j, x, y;
2416
+
2417
+ if DigraphNrVertices(digraph) <= 1 or not IsConnectedDigraph(digraph) then
2418
+ return 0 ;
2419
+ fi ;
2420
+
2421
+ if IsMultiDigraph(digraph) then
2422
+ digraph := DigraphRemoveAllMultipleEdges(digraph);
2423
+ fi ;
2424
+
2425
+ kappas := [ DigraphNrVertices(digraph) - 1 ] ;
2426
+
2427
+ # The function newnetw is an implementation of Algorithm Nine from
2428
+ # Abdol-Hossein Esfahanian's ``Connectivity Algorithms'' which can be found at
2429
+ # https://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
2430
+ newnetw := function (digraph, source, sink )
2431
+ local n, mat, outn, x, y;
2432
+ n := DigraphNrVertices(digraph);
2433
+ mat := List([ 1 .. 2 * n] , x -> BlistList([ 1 .. 2 * n] , [] ));
2434
+ outn := OutNeighbours(digraph);
2435
+ for x in [ 1 .. DigraphNrVertices(digraph)] do
2436
+ if x <> source and x <> sink then
2437
+ mat[ x + n][ x] := true ;
2438
+ fi ;
2439
+ for y in outn[ x] do
2440
+ if x = source or x = sink then
2441
+ mat[ x][ y + n] := true ;
2442
+ mat[ y][ x] := true ;
2443
+ elif y = source or y = sink then
2444
+ mat[ y][ x + n] := true ;
2445
+ mat[ x][ y] := true ;
2446
+ else
2447
+ mat[ y][ x + n] := true ;
2448
+ mat[ x][ y + n] := true ;
2449
+ fi ;
2450
+ od ;
2451
+ od ;
2452
+ return List(mat, x -> ListBlist([ 1 .. 2 * n] , x));
2453
+ end ;
2454
+
2455
+ # The following function is an implementation of the Edmonds-Karp algorithm
2456
+ # with some minor adjustments that take into account the fact that the
2457
+ # capacity of all edges is 1.
2458
+ edmondskarp := function (netw, source, sink )
2459
+ local flow, capacity, queue, m, predecessor, edgeindex, stop, current, n, v;
2460
+
2461
+ flow := 0 ;
2462
+ capacity := List(netw, x -> BlistList(x, x));
2463
+ # nredges := Sum(List(netw, Length));
2464
+
2465
+ while true do
2466
+ queue := [ source] ;
2467
+ m := 1 ;
2468
+ predecessor := List(netw, x -> 0 );
2469
+ edgeindex := List(netw, x -> 0 );
2470
+ stop := false ;
2471
+ while m <= Size(queue) and not stop do
2472
+ current := queue[ m] ;
2473
+ n := 0 ;
2474
+ for v in netw[ current] do
2475
+ n := n + 1 ;
2476
+ if predecessor[ v] = 0 and v <> source and capacity[ current][ n] then
2477
+ predecessor[ v] := current;
2478
+ edgeindex[ v] := n;
2479
+ Add(queue, v);
2480
+ fi ;
2481
+ if v = sink then
2482
+ stop := true ;
2483
+ break ;
2484
+ fi ;
2485
+ od ;
2486
+ m := m + 1 ;
2487
+ od ;
2488
+
2489
+ if predecessor[ sink] <> 0 then
2490
+ v := predecessor[ sink] ;
2491
+ n := edgeindex[ sink] ;
2492
+ while v <> 0 do
2493
+ capacity[ v][ n] := false ;
2494
+ n := edgeindex[ v] ;
2495
+ v := predecessor[ v] ;
2496
+ od ;
2497
+ flow := flow + 1 ;
2498
+ else
2499
+ return flow;
2500
+ fi ;
2501
+ od ;
2502
+ end ;
2503
+
2504
+ # Referring once again to Abdol-Hossein Esfahanian's paper (see newnetw, above)
2505
+ # the following lines implement Algorithm Eleven of that paper.
2506
+ mat := BooleanAdjacencyMatrix(digraph);
2507
+ degs := ListWithIdenticalEntries(DigraphNrVertices(digraph), 0 );
2508
+ for i in DigraphVertices(digraph) do
2509
+ for j in [ i + 1 .. DigraphNrVertices(digraph)] do
2510
+ if mat[ i][ j] or mat[ j][ i] then
2511
+ degs[ i] := degs[ i] + 1 ;
2512
+ degs[ j] := degs[ j] + 1 ;
2513
+ fi ;
2514
+ od ;
2515
+ od ;
2516
+
2517
+ mindegv := 0 ;
2518
+ mindeg := DigraphNrVertices(digraph) + 1 ;
2519
+ for i in DigraphVertices(digraph) do
2520
+ if degs[ i] < mindeg then
2521
+ mindeg := degs[ i] ;
2522
+ mindegv := i;
2523
+ fi ;
2524
+ od ;
2525
+
2526
+ Nv := OutNeighboursOfVertex(digraph, mindegv);
2527
+ outn := OutNeighbours(digraph);
2528
+
2529
+ for x in DigraphVertices(digraph) do
2530
+ if x <> mindegv and not mat[ x][ mindegv] and not mat[ mindegv][ x] then
2531
+ k := edmondskarp(newnetw(digraph, mindegv, x), mindegv, x);
2532
+ if k = 0 then
2533
+ return 0 ;
2534
+ else
2535
+ AddSet(kappas, k);
2536
+ fi ;
2537
+ fi ;
2538
+ od ;
2539
+
2540
+ for x in [ 1 .. Size(Nv) - 1 ] do
2541
+ for y in [ x + 1 .. Size(Nv)] do
2542
+ if not mat[ Nv[ x]][ Nv[ y]] and not mat[ Nv[ y]][ Nv[ x]] then
2543
+ k := edmondskarp(newnetw(digraph, Nv[ x] , Nv[ y] ), Nv[ x] , Nv[ y] );
2544
+ if k = 0 then
2545
+ return 0 ;
2546
+ else
2547
+ AddSet(kappas, k);
2548
+ fi ;
2549
+ fi ;
2550
+ od ;
2551
+ od ;
2552
+ return kappas[ 1 ] ;
2553
+ end );
0 commit comments