4.2 Rettede grafer

Rettede grafer.

En rettet graf består af en mængde af knuder og en samling af rettede kanter, der hver forbinder et par af knuder \((u,v)\). Vi siger, at den rettede kant peger fra parrets første knude \(u\) og peger på parrets anden knude \(v\). Vi bruger tallene \(\{0,\ldots V-1\}\) for at navngive knuderne i en graf med \(V\) knuder.

Digraph


Glosar.

Vi benytter følgende definitioner og terminologi.

Anatomy of a Graph     A digraph and its strong components


Datatype for rettede grafer.

Vi implementerer følgende APG for rettede grafer.

public class Digraph
Digraph(int V)rettet graf med \(V\) knuder og ingen kanter
Graph(In in)rettet graf fra indputstrømmen in
intV()antal knuder
intE()antal kanter
voidaddEdge(int v, int w)tilføj kanten v->w til denne graf
Iterable<Integer>adj(int v)naboknuder som kanter fra \(v\) peger på
Digraphreverse()grafens omvending
StringtoString()tekstuel repræsentation af grafen

Den centrale metode er nabogennemløberen adj(), som tillader klientkoden at gennemløbe alle naboer, som den givne knudes nabokanter peger på.

Vores testdata tinyDG.txt og tinyDAG.txt bruger følgende indputformat:

Digraph input format

Grafrepræsentation.

Vi repræsenterer grafer som nabolister. Det vil sige, at vi opretholder en knude-indekseret række af lister, som for hver knude indeholder de knuder, som knudens nabokanter peger på.

Adjacency-lists
representation of an undirected graph

Programmet Digraph.java implementer APG’en for rettede grafer ved brug af nabolisterepræsentationen. Til sammenligning implementerer programmet AdjMatrixDigraph.java samme APG ved brug af nabomatrixrepræsentationen; her repræsenteres grafen af en boolsk matrix \(A\), hvis indgang \(A_{uv\}\) beskriver, om der findes en kant fra \(u\) til \(v\).

Tilgængelighed i rettede grafer.

Både dybde-først- og bredde-først-søgning virker for rettede grafer.

Kredse og rettede acykliske grafer.

Rettede kredse spiller en vigtig rolle for anvendelser, der behandler rettede grafer.

DAG


Påstand.

En rettet graf har en topologisk orden hvis og kun hvis den er acyklisk.

Påstand.

Omvendt postorden i en rettet acyklisk graf er en topologisk orden.

Påstand.

Dybde-først-søgning finder en topologisk orden i en rettet, acyklisk graf i tid proportional med \( V+ E\).

Stærk sammenhæng.

Stærk sammenhæng er en ækvivalensrelation på mængden af knuder: Stærk sammenhæng opdeler knuderne i ækvivalensklasser, som vi kalder stærke sammenhængskomponenter. Vi vil implementere følgende APG:

public class SCC
SCC(Digraph G)forbehandl grafen
booleanstronglyConnected(int v, int w)er u og v stærkt sammenhængende
intcount()antal stærke sammenhængskomponenter
intid(int v)komponentnavn for knuden v (mellem 0 og count()-1)

Kosaraju og Sharirs forbløffende algoritme i programmet KosarajuSharirSCC.java implementerer denne APG med blot nogle få ekstra linjer kode ud over CC.java. Idéen er følgende:

Påstand.

Kosaraju og Sharirs algoritme bruger forbehandlingstid og -plads proportional med \( V + E\) for at besvare sammenhængsforespørgsler i en rettet graf i konstant tid.

Transitiv afslutning.

Den transitive afslutning \(T(G)\) af en rettet graf \( G\) er en rettet graf med samme knudemængde. Der er en kant fra \(u\) til \(v\) i \(T(G)\) hvis og kun hvis der er en sti fra \(u\) til \(v\) i \(G\).

Transitive closure


Programmet TransitiveClosure.java beregner den transitive afslutning af en rettet graf ved at dybde-først-søge fra hver knude. Denne løsning er ideel for små og tætte grafer. Løsningen er ikke god for store, tynde grafer, fordi konstruktøren bruger plads proportional med \( V^2 \) og tid proportional med \(V( V+E)\).