Anvendelser III

70
1 Anvendelser III Grafer

description

Grafer. Anvendelser III. Plan. Grafer Terminologi Repræsentation Traversering Korteste vej Topologisk sortering Problemkompleksitet og afgørlighed. A. I. H. G. B. C. D. E. F. Grafer. En graf er et nyttigt, abstrakt begreb. - PowerPoint PPT Presentation

Transcript of Anvendelser III

Page 1: Anvendelser III

1

Anvendelser III

Grafer

Page 2: Anvendelser III

2

• Grafer Terminologi

Repræsentation Traversering

Korteste vejTopologisk sortering

• Problemkompleksitet og afgørlighed

Plan

Page 3: Anvendelser III

3

Grafer

En graf er et nyttigt, abstrakt begreb.

Intuitiv definition: En graf er en mængde af objekter og forbindelser imellem disse.

Matematisk definition: En graf G = (V,E) består af en endelig mængde af knuder, V, og en endelig mængde af kanter, E, hvor hver kant forbinder to af knuderne (E VxV).

A

B C G

F

D E

H I

V = A, B, C, D, E, F, G, H, I

E = (A,B), (A,C), (A,F), (A,G), (D,E), (D,F), (E,F), (E,G), (H,I)

Page 4: Anvendelser III

4

Anvendelsesområder

Alt hvad der involverer relationer imellem

objekter kan modelleres ved hjælp af en graf

Trafiknetværk: Knuder: byer, vejkryds Kanter: veje

Organiske molekyler: Knuder: atomer Kanter: bindinger

Elektriske kredsløb: Knuder: komponenter Kanter: ledninger

Page 5: Anvendelser III

5

Objektorienteret design (UML-diagrammering): Knuder: klasser/objekter Kanter: nedarvning, aggregering eller associering

Projektplanlægning: Knuder: delopgaver Kanter: præcedenser (delopgave A skal udføres før delopgave B)

Programsystemer: Knuder: metoder Kanter: metode A kan kalde metode B

Anvendelsesområder(fortsat)

Page 6: Anvendelser III

6

Terminologi

En orienteret graf er en graf, hvor alle kanter er orienterede. En ikke-orienteret graf er en graf, hvor ingen kanter er orienterede.

H I

Hvis rækkefølgen af en kants endeknuder har betydning, kaldes kanten for orienteret.

Dette angives på den grafiske repræsentation ved at kanten forsynes med en pil. Endeknuderne kaldes da for henholdsvis begyndelsesknuden og slutknuden.

H I

En kants to knuder kaldes endeknuder for kanten.

Page 7: Anvendelser III

7

Terminologi (fortsat)

En vej er en liste af knuder, hvor successive knuder er forbundet med en kant.

En vej kaldes simpel, hvis ingen knude gentages.

En cykel er en vej, der er simpel, bortset fra at den første og sidste knude er den samme.

Cykler: FDEF, AFEGA og AFDEGA.

A

B C G

F

D E

H I

Page 8: Anvendelser III

8

En graf G’ = (V’,E’) er en delgraf af G = (V,E), hvis V’ Vog E’

E.

En graf kaldes sammenhængende, hvis der for enhver knude findes en vej til enhver anden knude.

En graf, der ikke er sammenhængende, består af sammenhængende delgrafer, også kaldet komponenter.

2 komponenter

Terminologi (fortsat)

A

B C G

F

D E

H I

Page 9: Anvendelser III

9

Et træ er en sammenhængende graf uden cykler.

En mængde af disjunkte træer kaldes en skov.

Et udspændende træ for en graf G er en delgraf af G, der indeholder alle grafens knuder, og som udgør et træ.

Graf G Udspændende træ for G

Terminologi (fortsat)

Page 10: Anvendelser III

10

En graf, hvor enhver knude er forbundet med enhver anden knude, kaldes for komplet.

[ for en ikke-orienteret graf: |E| = |V|*(|V|-1)/2) ]

En tynd graf er en graf med relativt få kanter (i forhold til |V|)

En tæt graf er en graf med relativt mange kanter (i forhold til |V|)

En vægtet graf er en graf, hvor kanterne er forsynet med talværdier, kaldet vægte.[ vægtene repræsenterer normalt omkostninger ]

Terminologi (fortsat)

Page 11: Anvendelser III

11

Basale grafproblemer

Veje: Er der en vej fra knude A til knude B?

Cykler:Indeholder grafen en cykel?

Sammenhæng (udspændende træ): Er der for hver knude en vej til enhver anden knude?

2-sammenhæng: Vil grafen blive usammenhængende, hvis en af knuderne og de tilstødende kanter fjernes?

Planaritet: Kan grafen tegnes, uden at to kanter krydser hinanden?

Page 12: Anvendelser III

12

Basale grafproblemer(fortsat)

Korteste vej:Hvilken vej er den korteste fra knude A til knude B?

Længste vej: Hvilken vej er den længste fra knude A til knude B?

Minimalt udspændende træ: Hvad er den billigste måde at forbinde alle knuder?

Hamilton-cykel: Er der en cykel, som indeholder samtlige knuder?

Den rejsende sælgers problem: Hvilken Hamilton-cykel er den billigste?

Page 13: Anvendelser III

13

Repræsentation af grafer

Grafer er abstrakte matematiske objekter.Algoritmer må arbejde med konkrete repræsentationer.

Mange mulige repræsentationer. Valget er bestemt af algoritmer og graftyper (tynde/tætte, vægtede/uvægtede, orienterede/ikke-orienterede).

I det følgende gennemgås 3 repræsentationer:

(1) kantmængde (2) nabomatrix (3) nabolister

Page 14: Anvendelser III

14

(1) Kantmængde-repræsentation

class Edge

Vertex source, dest;

double cost;

class Graph Set edges;

class Vertex String name;

Page 15: Anvendelser III

15

(2) Nabomatrix-repræsentation

A B C D E F G H I

A 0 1 1 0 0 1 1 0 0

B 1 0 0 0 0 0 0 0 0

C 1 0 0 0 0 0 0 0 0

D 0 0 0 0 1 1 0 0 0

E 0 0 0 1 0 1 1 0 0

F 1 0 0 1 1 0 0 0 0

G 1 0 0 0 1 0 0 0 0

H 0 0 0 0 0 0 0 0 1

I 0 0 0 0 0 0 0 1 0

class Graph // unweighted boolean[][] adjMatrix;

class Graph // weighted double[][] adjMatrix;

A

B C G

F

D E

H I

Page 16: Anvendelser III

16

(3) Naboliste-repræsentation

A

B C G

F

D E

H IA:

B:

C:

D:

E:

F:

G:

H:

I:

F C B G

A

A

F E

G F D

A E D

E A

I

H

Page 17: Anvendelser III

17

Naboliste-repræsentation

class Edge

Vertex dest; // Second vertex of edge

double cost; // Edge cost

class Graph Map vertexMap; // Map String to Vertex

class Vertex String name; // Vertex name List adj; // List of edges

Page 18: Anvendelser III

18

Sammenligning af repræsentationer

Pladskrav:

Kantmængde: O(|E|)

Nabomatrix: O(|V|2)

Nabolister: O(|V| + |E|)

Page 19: Anvendelser III

19

Værste tilfælde:

Er der en kant fra knude A til knude B? Kantmængde: O(|E|) Nabomatrix: O(1) Nabolister: O(|V|)

Er der en kant fra knude A? Kantmængde: O(|E|) Nabomatrix O(|V|) Nabolister: O(1)

Repræsentation har betydning for algoritmers effektivitet

Page 20: Anvendelser III

20

Mål: at besøge enhver knude i en graf.

Dybde-først-traversering:

Rekursiv algoritme:

* Mærk alle knuder “ubesøgt”.

* Besøg startknuden.

* Ved besøg af en knude, v:Mærk knuden “besøgt” Besøg (rekursivt) alle ubesøgte

knuder, der er forbundet med v.

Traversering af grafer

Løser nogle simple grafproblemer: sammenhæng, cykler

Basis for løsning af nogle vanskelige grafproblemer:2-sammenhæng

Page 21: Anvendelser III

21

class Vertex String name; List adj; boolean visited;

void visit() visited = true; Iterator itr = adj.iterator(); while (itr.hasNext()) Vertex w = ((Edge) itr.next()).dest; if (!w.visited) w.visit();

Implementering af dybde-først-traversering

Kompleksitet: O(|E|)

Page 22: Anvendelser III

22

Dybde-først-traversering af en komponent

A

B C G

F

D E

A

B C G

F

D E

A

B C G

D E

F

A

B C

D

G

E

F

A

B

D

C G

E

F

A

B C G

D E

F

A: F C B GB: AC: AD: F EE: G F DF: A E DG: E A

A

B C G

F

D E

Page 23: Anvendelser III

23

Dybde-først-traversering af en sammenhængende graf repræsenteret ved nabolister kræver tid proportional med |E|

Dybde-først-traversering af en komponent udgør et dybde-først-træ

A

F C B

E

DG

1

2

3

4 5

6 7

Page 24: Anvendelser III

24

void traverse(Vertex startVertex) Stack stack = new ArrayStack(); stack.push(startVertex); startVertex.visited = true; while (!stack.isEmpty()) Vertex v = (Vertex) stack.topAndPop(); Iterator itr = v.adj.iterator(); while (itr.hasNext())

Vertex w = ((Edge) itr.hasNext()).dest; if (!w.visited) stack.push(w); w.visited = true;

Ikke-rekursiv dybde-først-traversering

Benyt en eksplicit stak af knuder.

Page 25: Anvendelser III

25

Hvis stakken erstattes med en kø, foretages bredde-først-traversering.

Bredde-først-traversering

void traverse(Vertex startVertex) Queue queue = new ListQueue(); queue.enqueue(startVertex); startVertex.visited = true; while (!queue.isEmpty()) Vertex v = (Vertex) queue.dequeue(); Iterator itr = v.adj.iterator(); while (itr.hasNext())

Vertex w = ((Edge) itr.next()).dest; if (!w.visited) queue.enqueue(w); w.visited = true;

Page 26: Anvendelser III

26

Bredde-først-traversering af en komponent

A: F C B GB: AC: AD: F EE: G F DF: A E DG: E A

A

B C G

F

D E

F C B G

A

B C G

F

D E

C B G E D

A

B C G

D E

F B G E D

A

B C G

D E

F G E D

A

B C G

D E

F E D

A

B C G

D E

F D

A

B C G

D E

F

Page 27: Anvendelser III

27

A

F C B

E D

G

1

2 3 4 5

6 7

Bredde-først- traversering af en komponent udgør et bredde-først-træ

Bredde-først-traversering af en sammenhængende graf repræsenteret ved nabolister kræver tid proportional med |E|

Page 28: Anvendelser III

28

Dybde-først versus bredde-først

Dybde-førststart

aktuel

Bredde-først

start

aktuel

Page 29: Anvendelser III

29

Hvis køen erstattes med en prioritetskø, foretages bedste-først-traversering.

Bedste-først-traversering

void traverse(Vertex startVertex) PriorityQueue pq = new SpecialPriorityQueue(); pq.update(startVertex, priority); while (!pq.isEmpty()) Vertex v = (Vertex) pq.deleteMin(); v.visited = true; Iterator itr = v.adj.iterator(); while (itr.hasNext()) Vertex w = ((Edge) itr.next()).dest; if (!w.visited) pq.update(w, priority);

Page 30: Anvendelser III

30

SpecialPriorityQueue

pq.update(Object obj, int prio)

Hvis obj ikke findes i pq, så indsæt det med prioritet prio. Ellers, opdater dets prioritet til prio.

pq.deleteMin()

Fjern fra pq det objekt, der har mindst prioritet. Returner dette objekt.

Denne abstrakte datatype findes ikke i Java.Men vi kan benytte klassen PairingHeap fra lærebogen.

Page 31: Anvendelser III

31

Pairing Heap

class PairingHeap

Position insert(Comparable x);

Comparable deleteMin();

void decreaseKey(Position pos, Comparable newVal);

boolean isEmpty();

Page 32: Anvendelser III

32

Ændringer i class Vertex

class Vertex implements Comparable String name; boolean visited; double priority; Position heapPosition; Vertex prev;

public int compareTo(Object rhs) Vertex v = (Vertex) rhs; return priority < v.priority ? -1 : priority == v.priority ? 0 : 1;

public void reset() visited = false; priority = Graph.INFINITY; heapPosition = null; prev = null;

Page 33: Anvendelser III

33

void traverse(Vertex startVertex) PriorityQueue pq = new PairingHeap(); startVertex.priority = priority; startVertex.heapPosition = pq.insert(startVertex); while (!pq.isEmpty()) Vertex v = (Vertex) pq.deleteMin(); v.visited = true; Iterator itr = v.adj.iterator(); while (itr.hasNext()) Vertex w = ((Edge) itr.next()).dest; if (!w.visited && priority < w.priority) w.priority = priority; w.prev = v; if (w.heapPosition == null) w.heapPosition = pq.insert(w); else pq.decreaseKey(w.heapPosition, w);

Page 34: Anvendelser III

34

Kompleksitet af bedste-først-søgning

Tidskompleksiteten for bedste-først-søgning i en graf er O((|V|+|E|)log|V|).

|V| kald af deletemin

|E| kald af enten insert eller decreaseKey

Hvis pq er en hob, så er tiden for et kald af såvel deletemin, insert som decreaseKey O(log|V|).

Page 35: Anvendelser III

35

Korteste-vej-problemet

Find den korteste vej fra knude A til knude B.

Uvægtede korteste vej (minimer antallet af kanter fra A til B):Anvend bredde-først-traversering.Traverser grafen startende i A ved hjælp af en kø.

Vægtede korteste vej (bestem den billigste vej fra A til B):Anvend bedste-først-traversering: Dijkstras algoritme. Traverser grafen startende i A ved hjælp af en prioritetskø, idet prioriteten for hver ubesøgt knude er omkostningen af den hidtil billigste vej fra A til knuden.Virker dog kun i en graf med ikke-negative vægte.

Page 36: Anvendelser III

36

Eksempel på bestemmelseaf korteste-vej-træ

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

1

2

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

2

2

3 5

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

2

3 5

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

4

3 4

Page 37: Anvendelser III

37

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

4

4

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

6

5

4

7

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

5

5

7

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

5

7

Page 38: Anvendelser III

38

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 3

2

1

1

2

1

5

1442

2

4 3

6

8A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 3

2

1

1

2

1

5

1442

2

4 3

7

8

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 3

2

1

1

2

1

5

1442

2

4 3

88A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

8

A

B C G

F

D E

H I

J K

L M

1

2

1 2

2

1

1

6 32

1

1

2

1

5

1442

2

4 3

Page 39: Anvendelser III

39

private boolean dijkstra(Vertex startVertex) clearAll(); PriorityQueue pq = new PairHeap(); startVertex.priority = 0; startVertex.heapPosition = pq.insert(startVertex); while (!pq.isEmpty()) Vertex v = (Vertex) pq.deleteMin(); v.visited = true; Iterator itr = v.adj.iterator(); while (itr.hasNext()) Edge e = (Edge) itr.next(); Vertex w = e.dest; double cvw = e.cost; if (cvw < 0) return false; if (!w.visited && v.priority + cvw < w.priority) w.priority = v.priority + cvw; w.prev = v; if (w.heapPosition == null) w.heapPosition = pq.addItem(w); else pq.decreaseKey(w.heapPosition, w); return true;

Page 40: Anvendelser III

40

Minimalt udspændende træ

Hvis udtrykket v.priority + cvw overalt erstattes med cvw, vil det minimalt udspændende træ blive bestemt.

Page 41: Anvendelser III

41

clearAll

private void clearAll() Iterator itr = vertexMap.values().iterator(); while (itr.hasNext()) ((Vertex) itr.next()).reset();

Page 42: Anvendelser III

42

Udskrivning af korteste vej

private void printPath(Vertex destVertex) if (!destVertex.visited) System.out.println(destVertex.name + " is unreachable"); else destVertex.printPath(); System.out.println(" cost: " + destVertex.priority); System.out.println();

public void printPath() if (prev != null) prev.printPath(); System.out.print(" to "); System.out.print(name);

Page 43: Anvendelser III

43

class Graph

public class Graph public Vertex addVertex(String vertexName) ... public void addEdge(String source, String dest, double cost) ... public boolean processRequest(BufferedReader in) ...

public static void main(String[] args) ... private static final double INFINITY = DOUBLE.MAX_VALUE; private HashMap vertexMap = new HashMap(); private void printPath(Vertex destVertex) ... private void clearAll() ... private boolean dijkstra(Vertex startVertex) ...

Page 44: Anvendelser III

44

public static void main(String[] args) BufferedReader graphFile;

try graphFile = new BufferedReader( new FileReader(args[0])); // ... fortsættes

catch(IOException e) System.err.println(e);

main

Page 45: Anvendelser III

45

Graph g = new Graph(); String line; while ((line = graphFile.readLine()) != null) StringTokenizer st = new StringTokenizer(line); try // read source, destination and cost

if (st.countTokens() != 3) System.err.println("Skipping bad line " + line);

continue;

String source = st.nextToken(); String dest = st.nextToken(); int cost = Integer.parseInt(st.nextToken());

g.addEdge(source, dest, cost); catch (NumberFormatException e)

System.err.println("Skipping bad line " + line); BufferedReader in = new BufferedReader(

new FileReader(System.in));while (g.processRequest(in))

;

main(forsat)

Page 46: Anvendelser III

46

public void addEdge(String source, String dest, double cost) getVertex(source).adj.add(new Edge(getVertex(dest), cost));

addEdge

public Vertex getVertex(String vertexName) Vertex v = (Vertex) vertexMap.get(vertexName); if (v == null) v = new Vertex(vertexName); vertexMap.put(vertexName, v); return v;

Page 47: Anvendelser III

47

processRequest

public boolean processRequest(BufferedReader in) String sourceName, destName; try

System.out.println("Enter start vertex:"); if ((sourceName = in.readLine()) == null) return false;

System.out.println("Enter destination vertex:"); if ((destName = in.readLine()) == null) return false;

catch (IOException e) System.out.println("Error: " + e); return false;

Vertex source, dest; if ((source = (Vertex) vertexMap.get(sourceName)) == null)

System.out.println("Start vertex not in graph"); return true;if ((dest = (Vertex) vertexMap.get(destName)) == null) System.out.println("Destination vertex not in graph"); return true;

if (dijkstra(source)) printPath(dest);else System.out.println("Dijkstra fails - negative edge");

return true;

Page 48: Anvendelser III

48

Kompleksitet

Dijkstras algoritme kan implementeres, så den har tidskompleksitet O((|E| + |V|)log(|V|).

Hvis alle vægte er ens, f.eks. 1, eksisterer en algoritme med tidskompleksitet O(|E|+|V|).

Hvis vægte må være negative, eksisterer en algoritme med tidskompleksitet O(|E||V|).

Hvis grafen ikke indeholder cykler, eksisterer en algoritme med tidskompleksitet O(|E|).

Page 49: Anvendelser III

49

DAGs

En orienteret graf uden cykler kaldes for en DAG (Directed Acyclic Graph).

En DAG kan f.eks. benyttes til at modellere et aktivitetsnetværk, hvor pilene angiver, at en aktivitets færdiggørelse er en forudsætning for en andens påbegyndelse.

Eksempel: kursusforudsætninger.

Page 50: Anvendelser III

50

Netværksplanlægning

aktivitet forgænger(e) varighed (uger)

A konstruer lagerstyringsmodel - 4

B implementer lagerstyringsprogram A 13

C konstruer prognosemodel - 4

D implementer prognoseprogram C 15

E indsaml data - 12

F design database A 4

G implementer database E, F 2

H oplær personale B, D 2

I afprøv system G, H 2

C D

H

B

E

A

F

G

Iaktivitetsnetværk

Page 51: Anvendelser III

51

En DAG kan ordnes, således at ingen knude kommer før nogen anden knude, der peger på den. Denne operation kaldes topologisk sortering.

Topologisk sortering

A

B C G

F

D E

H I

J K

L M

Topologisk orden: Alle pile vender samme vej, fra venstre mod højre [ ikke unik ]

J K L M A G H I F E D B C

Page 52: Anvendelser III

52

Dybde-først-traversering af en DAG

A

B C G

F

D E

H I

J K

L M

A J

F C B G K L

E

D

H

I

M

En skov for dybde-først-søgning har ingen opadgående kanter.

Page 53: Anvendelser III

53

Omvendt topologisk orden kan opnås ved dybde-først-traversering.

Omvendt topologisk orden

A J

F C B G K L

E

D

H

I

M

D E F C B I H G A K M L J

Page 54: Anvendelser III

54

void visit() visited = true; Iterator itr = v.adj.iterator(); while (itr.hasNext()) Vertex w = ((Edge) itr.next()).dest; if (!w.visited) w.visit(); stack.push(this);

Implementering af topologisk sortering

Tidskompleksitet: O(|E|)

Page 55: Anvendelser III

55

Alternativ algoritme til topologisk sortering

(1) Lav en tom kø

(2) Vælg en knude uden indgående kanter

(3) Indsæt knuden i køen. Fjern knuden og alle dens kanter fra grafen

(4) Gentag (2) og (3), indtil der ikke er flere knuder i grafen

Page 56: Anvendelser III

56

Implementering i Java

ArrayList tologicalOrder() Iterator vitr = vertexSet.values().iterator();

while (vitr.hasNext()) ((Vertex) vitr.next()).inDegree = 0;

vitr = vertexSet.values().iterator(); while (vitr.hasNext()) Vertex v = (Vertex) vitr.next(); Iterator witr = v.adj.iterator();

while (witr.hasNext()) ((Edge) witr.next()).dest.inDegree++;

Queue queue = new ListQueue();

vitr = vertexSet.values().iterator(); while (vitr.hasNext()) Vertex v = (Vertex) vitr.next(); if (v.inDegree == 0)

queue.enqueue(v);// ... fortsættes

Page 57: Anvendelser III

57

ArrayList result = new ArrayList(); int iterations = 0; while (!queue.isEmpty() && ++iterations <= vertexMap.size()) Vertex v = (Vertex) queue.dequeue(); result.add(v); Iterator witr = v.adj.iterator();

while (witr.hasNext()) Vertex w = ((Edge) witr.next()).dest; if (--w.inDegree == 0) queue.enqueue(w);

return iterations == vertexMap.size() ? result : null;

Implementering i Java(fortsat)

Page 58: Anvendelser III

58

Problemkompleksitet og afgørlighed

Page 59: Anvendelser III

59

Problemers kompleksitet

For en stor klasse af vigtige problemer kendes ingen løsningsalgoritmer, der kan garanteres at være hurtige.

En ineffektiv algoritme: køretiden vokser mindst eksponentielt [Ω(cn) ]

Et problem, der ikke kan løses med en effektiv algoritme, siges at være svært.

En effektiv algoritme: køretiden er opad begrænset af et polynomium [ O(nc) ]

Et problem, der kan løses med en effektiv algoritme, siges at være let.

Page 60: Anvendelser III

60

Eksempler på svære problemer

• Den rejsende sælgers problem En sælger skal besøge N byer. Find en rejserute, der minimerer hans rejseomkostninger.

• Planlægning Et antal opgaver af varierende varighed skal udføres på to identiske maskiner inden en vis tidsfrist. Kan tidsfristen overholdes?

• Tilfredsstillelighed Er det muligt at tildele sandhedsværdier til de variable i et logisk udtryk, som gør udtrykket sandt?

(a b) (a b)

Page 61: Anvendelser III

61

Flere eksempler på svære problemer

• Den længste vej Find den længste simple vej imellem to knuder i en graf.

• Opdeling Givet en mængde af heltal. Findes der en opdeling i to delmængder, således at summen af elementer i hver af de to delmængder er den samme?

• 3-farvning Kan knuderne i en graf farves med tre farver, således at hvert par af forbundne knuder har forskellig farve?

Page 62: Anvendelser III

62

NP-komplette problemer

For intet af disse problemer kendes en algoritme, der løser problemet i polynomiel tid.

Alle eksperter er overbevist om, at en sådan algoritme ikke eksisterer. Det er dog endnu ikke bevist.

Problemerne tilhører den såkaldte klasse af NP-komplette problemer.

Page 63: Anvendelser III

63

Et NP-komplet problem, er et problem der kan løses på en ikke-deterministisk maskine i polynomiel tid.

En ikke-deterministisk maskine er forsynet med den vidunderlige evne, at den i enhver valgsituation foretager det korrekte valg.

En sædvanlig, deterministisk maskine kan simulere korrekte valg i eksponentiel tid ved at afprøve enhver mulighed.

Hvis blot ét NP-komplet problem kan løses i polynomiel tid på en deterministisk maskine, så vil ethvert NP-komplet problem kunne løses i polynomiel tid.

NP-komplethed

Page 64: Anvendelser III

64

Afgørlighed

Uafgørlige problemer er problemer, som ikke kan løses algoritmisk.

Eksempler:

• Bevis at en algoritme altid terminerer (Stopproblemet)

• Afgør om en sætning i prædikatlogikken er gyldig eller ej.

• Afgør om to syntaksbeskrivelser definerer det samme sprog.

Page 65: Anvendelser III

65

(a)while (x != 1) x = x - 2;

Terminering?

while (x != 1) if (x % 2 == 0) x = x / 2; else x = 3 * x + 1;

Collatz sekvenser: 12, 6, 3, 10, 5, 16, 8, 4, 2, 1

9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1

(b)

Page 66: Anvendelser III

66

Programmets stopper, hvis og kun hvis Fermats sidste teorem er falsk.

For n ≥ 3 findes der ikke tre naturlige tal a, b, og c, så an + bn = cn.

P. de Fermat (1601-65)

(c) for (int x = 3; ; x++)

for (int a = 1; a <= x; a++)

for (int b = 1; b <= x; b++)

for (int c = 1; c <= x; c++)

for (int n = 3; n <= x; n++)

if (Math.pow(a,n) + Math.pow(b,n) == Math.pow(c,n))

System.exit(0);

Terminering?(fortsat)

Page 67: Anvendelser III

67

Det er umuligt at konstruere en algoritme, der for enhver algoritme kan afgøre, om den terminerer.

Stopproblemet

Definer nu:

void p() while (terminates(p)) /* do nothing */;

Hvad returnerer da følgende kald: terminates(p)?

Bevis (indirekte):

Antag eksistensen af terminates(p), som for enhver metode p returnerer true, hvis p terminerer; ellers false.

Page 68: Anvendelser III

68

Et spørgsmål

void p() while (terminates(p)) /* do nothing */;

void p() while (terminates(p)) /* do nothing */;

Som bekendt tillader Java ikke, at en metoder som parametre til metoder. Således er koden nedenfor ikke lovlig Java-kode:

Hvorledes kan den ønskede effekt alligevel opnås i Java?

Page 69: Anvendelser III

69

Svar

class Method

void p()

while (terminates(this)) /* do nothing */;

og definer metoden terminates således:

boolean terminates(Method m)

return ”kaldet m.p() vil terminere”;

Benyt en svøbeklasse (wrapper class) for metoden p:

Page 70: Anvendelser III

70

• Læs kapitel 15, 16, 17 og 18

• Løs følgende opgaver

Opgave 30: 14.1 (1 point) Opgave 31: 14.2 (1 point)

Opgave 32: 14.8 (2 point, ikke-obligatorisk)Opgave 33: 14.10 (2 point)

Afleveringsfrist: tirsdag den 27. november

Ugeseddel 913. november - 20. november