GRAPHENTHEORIE Grundlagen für Routen- und Tourenplanung Algorithmen – Implementierungen - Anwendungen Prof. Dr. Heinrich Paessens Fachhochschule Flensburg IUT Strasbourg Sud 1. Grundlagen 1.1 Graphen-Definitionen 1.2 Darstellung von Problemen durch Graphen 1.3 Speicherung von Graphen 2. Algorithmen 2.1 Nachfolger und Vorgänger 2.2 Kürzeste Wege Algorithmen Dijkstra-Algorithmus Ford-Algorithmus Tripel-Algorithmus 2.3 Tourenplanung – Saving-Algorithmus 3. Implementierungen – Übungen 4. Anwendungen D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 1 von 39 1.1 GRAPHEN - DEFINITIONEN Definition1: Ein ungerichteter Graph G = (V,E) besteht aus einer Menge von Knoten V={1,2,...,n} und Kanten E={e1,e2,...,em}. Die Anzahl der Knoten wird mit n, die Anzahl der Kanten mit m bezeichnet. Die einer Kante e zugeordneten Knoten i, j werden Endknoten von e genannt. Man schreibt e = (i, j) oder e = (j, i) und sagt, daß die Kante e die Knoten i, j "verbindet". Knoten i heißt Nachbar des Knotens j und umgekehrt, falls e = (i, j) eine Kante in G ist. Ein gerichteter Graph G = [V,E] besteht aus einer Menge von Knoten V={1,2,...,n} und Pfeilen E={e1,e2,...,em}. Die Anzahl der Knoten wird wiederum mit n, die Anzahl der Pfeile mit m bezeichnet. Ein gerichteter Graph G = [V,E] wird auch Digraph D = [V,E] genannt. Ein Graph G = (V,E), der sowohl Pfeile wie auch Kanten enthält, heißt gemischter Graph. Für einen Pfeil e wird e = [i, j] geschrieben; i heißt Anfangsknoten und j Endknoten des Pfeiles e. Man sagt auch, daß der Pfeil e "vom Knoten i ausgeht" und "in den Knoten j einmündet". Knoten j wird (unmittelbarer) Nachfolger von Knoten i, Knoten i (unmittelbarer) Vorgänger von Knoten j genannt. Die Menge aller Nachfolger eines Knotens i wird mit Si und die Menge aller Vorgänger eines Knotens i mit Pi bezeichnet. Definition 2: Ist jeder Kante e (jedem Pfeil e) eines Graphen G (Digraphen D) eine Bewertung c(e) zugeordnet, so wird G = (V,E,c) bewerteter Graph (D = [V,E,c] bewerteter Digraph) genannt. Definition 3: Ein Weg w=(i,...,j) in einem ungerichteten Graphen G bzw. ein Weg w=[i,...,j] in einem Digraphen D ist eine Aufeinanderfolge von zusammenhängenden Kanten bzw. Pfeilen entsprechender Richtung mit Anfangsknoten i und Endknoten j. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 2 von 39 Ein Knoten j heißt von einem Knoten i aus erreichbar ,falls ein Weg von i nach j existiert. Ein Weg w mit unterschiedlichen Anfangsknoten i und Endknoten j (i≠j) wird als offener Weg bezeichnet. Ein Weg w, dessen Anfangs- und Endknoten identisch sind (i=j), wird als geschlossener Weg oder Rundreise oder Zyklus bezeichnet. Ein Weg w, der jede Kante bzw. jeden Pfeil eines Graphen G genau einmal enthält, wird Eulerlinie genannt. Ein Weg w, der jeden Knoten eines Graphen G genau einmal enthält, wird Hamiltonlinie genannt. Weitere Typen von Wegen in Graphen sind von praktischer Bedeutung: (1) Ein Weg w, der jede Kante (bestimmte Kanten) bzw. jeden Pfeil (bestimmte Pfeile) eines Graphen G mindestens einmal enthält (2) Ein Weg w, der jeden (bestimmte) Knoten eines Graphen G mindestens einmal enthält DEFINITION 4: Die Länge eines Weges c(w) ergibt sich aus der Aufsummierung der Bewertungen der benutzten Kanten bzw. Pfeile des Weges w. Ein Weg w in einem Graphen G, der unter allen von Knoten i nach Knoten j führenden Wegen die geringste Länge besitzt, heißt kürzester Weg von i nach j. Entsprechend wird eine Rundreise mit geringster Länge kürzeste oder auch minimale Rundreise genannt. DEFINITION 5: Unter dem Grad eines Knotens i in einem ungerichteten Graphen G versteht man die Anzahl derjenigen Kanten, die diesen Knoten als Endknoten besitzen ("berühren"), in Zeichen δ i. Unter dem positiven (negativen) Grad eines Knotens i in einem Digraphen D versteht man die Anzahl der Pfeile, die diesen Knoten als Anfangsknoten (Endknoten) besitzen, in Zeichen δ +i (δ -i). D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 3 von 39 WEG GESCHLOSSEN ZYKLUS RUNDREISE KNOTEN JEDER JEDER BEST. KNOTEN KNOTEN KNOTEN GENAU 1X MIND. 1X G. HAMILTON LINIE TSP OFFEN KANTEN / PFEILE JEDE KANTE/ PFEIL GENAU 1X G. EULERLINIE JEDE KANTE/ PFEIL MIND. 1X BEST. KANTEN/ PFEILE KNOTEN JEDER JEDER KNOTEN KNOTEN GENAU 1X MIND. 1X O. HAMILTON LINIE KANTEN / PFEILE BEST. KNOTEN JEDE KANTE/ PFEIL GENAU 1X O. EULERLINIE JEDE KANTE/ PFEIL MIND. 1X CPP BEI VORLIEGEN EINES BEWERTETEN GRAPHEN KÖNNEN MINIMALE / MAXIMALE WEGE (ZYKLEN, RUNDREISEN,...) BESTIMMT WERDEN. MÖGLICHE WEGE -TYPEN D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 4 von 39 BEST. KANTEN/ PFEILE ANMERKUNGEN zu Eulerlinien: Regeln in ungerichteten Graphen G: Ist der Grad eines jeden Knotens in einem Graphen G gerade, so ist ein geschlossener Weg (Rundreise) w, der jede Kante von G genau einmal enthält (geschlossene Eulerlinie), in G möglich. Ist der Grad von genau 2 Knoten in einem Graphen G ungerade und der Grad aller übrigen Knoten in G gerade, so ist ein offener Weg w, der jede Kante von G genau einmal enthält (offene Eulerlinie), in G möglich. Anfangs- und Endknoten des Weges w sind dabei die beiden Knoten mit ungeradem Grad. Regeln in Digraphen D: Gilt für jeden Knoten i in D δ +i = δ -i , so ist eine geschlossene Eulerlinie in D möglich. Gilt für genau 2 Knoten i und j in D δ +i = δ +j +1 und δ -i = δ -j -1 sowie für alle anderen Knoten k δ +k = δ -k so ist eine offene Eulerlinie in D möglich. i ist der Anfangsknoten und j der Endknoten der Eulerlinie. DEFINITION 6: Ein Knoten i ohne Vorgänger, d.h. δ -i=0, mit δ +i>0 wird Quelle, ein Knoten i ohne Nachfolger, d.h. δ +i=0, mit δ -i>0 wird Senke genannt. DEFINITION 7: (1) Ein Knoten i mit δ i = 0 bzw. mit δ +i = δ -i = 0 heißt isoliert . (2) Existieren mehrere Kanten (Pfeile), die dieselben Endknoten (Anfangs- und Endknoten) besitzen, so nennt man diese Kanten (Pfeile) parallel. (3) Stimmen die beiden Endknoten einer Kante (Anfangs- und Endknoten eines Pfeiles) miteinander überein, dann bezeichnet man diese(n) Kante (Pfeil) als Schlinge. (4) Ungerichtete (gerichtete) Graphen, die sich in der Ebene ohne Überschneiden von Kanten (Pfeilen) zeichnen lassen, nennt man planar. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 5 von 39 DEFINITION 8: Ein Graph G heißt vollständig, wenn je zwei verschiedene Knoten i und j des Graphen G durch mindestens eine Kante (i, j) bzw. durch mindestens einen Pfeil [i, j] sowie einen entgegengesetzt gerichteten Pfeil [j, i] miteinander verbunden sind. DEFINITION 9: Ein gerichteter Graph D heißt symmetrisch, falls für alle Pfeile von D gilt [i, j] ∈ E ⇒ [j, i] ∈ E . DEFINITION 10: Die Adjazenzmatrix A(D) eines Digraphen D = [V,E] mit V = {1, ..., n} ist eine n x n - Matrix mit den Elementen 1 , falls [i,j] ∈ E aij := 0 , sonst . DEFINITION 11: Die einem bewerteten Digraphen D = [V,E,c] zugeordnete n x n - Matrix C(D) mit den Elementen 0 , falls i = j cij := c ([i,j]) , falls e=[i,j] ∈ E ∞ , sonst heißt Bewertungsmatrix von D. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 6 von 39 DEFINITION 12: Sei D = [V,E,c] ein bewerteter Digraph mit E = {e1, ..., em}. Dann heißen die Vektoren anf1 ... anfm anf := end 1 ... end m end := Anfangsknotennummernvektor bzw. Endknotennummernvektor, wobei anfi (endi) die Knotennummer des Anfangsknotens (Endknotens) des Pfeiles ei ist. Der Vektor c := c1 ... cm wird Bewertungsvektor genannt. DEFINITION 13: Eine Numerierung der Pfeile eu = [anfu, endu] (anfu, endu ∈ V), u = 1, ..., m eines Digraphen D = [V,E] mit E = {e1, ..., em}, für die u>w ⇒ anfu ≥ anfw gilt, heißt Pfeilsortierung von D, nummernvektor ist aufsteigend sortiert. D:\IUT-Strasbourg\doc\graph_iut_d.doc d.h. 27.04.2003 19:52 (1 ≤ w < u ≤ m) der Anfangsknoten- Seite 7 von 39 DEFINITION 14: Sei D = [V,E] ein pfeilsortierter Digraph mit V = {1, ..., n} und E = {e1, ..., em}. Dann wird der Vektor pn1 pn := ... pnn+1 Pfeilnummernvektor von D genannt, wobei pni die Pfeilnummer desjenigen Pfeiles ist, der unter allen von Knoten i ausgehenden Pfeilen die kleinste Pfeilnummer hat (i = 1, ..., n). Ist ein Knoten j eine Senke, so wird pnj := pnj+1 gesetzt. Zweckmäßigerweise ist pnn+1 := m + 1 festgelegt. Definition 15: Sei D = [V,E,c] ein bewerteter Digraph ohne Zyklen negativer Länge und c*(w) die Länge des kürzesten Weges w = [i, ..., j] von i nach j, dann heißt die Größe 0 , falls i = j kij := c*(w) , w = [i, ..., j] ∞ , falls j von i aus nicht erreichbar Entfernung von i nach j und die n x n - Matrix K(D) mit den Elementen kij Entfernungsmatrix von D. Definition 16: Sei D = [V,E] ein Digraph. Dann heißt die n x n - Matrix P(D) mit den Elementen i , falls i = j oder [i,j] ∈ E pij := 0 , sonst Vorgängermatrix von D. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 8 von 39 Definition 17: Ein Graph G heißt zusammenhängend, wenn jeder Knoten in G von jedem anderen Knoten aus erreichbar ist. Definition 18: Sei G = (V,E) ein zusammenhängender Graph. Der zusammenhängende Graph G' = (V,E') mit E' ⊂ E heißt dann spannender Baum oder Gerüst von G, wenn G' keinen Zyklus enthält. Ein Gerüst enthält m = n-1 Kanten. Definition 19: Sei G = (V,E,c) ein zusammenhängender, bewerteter Graph. Ein Gerüst G' = (V,E',c') mit c'(e) = c(e) für alle e ∈ E' heißt Minimalgerüst von G, wenn ∑ c'(e) → MIN e∈E' gilt. Definition 20: Eine Numerierung der Knoten eines zyklenfreien Digraphen D = [V,E] mit j ∈ Si ⇒ i<j ( 1 ≤ i,j ≤ n ) heißt Topologische Sortierung von D, d.h. die Knotennummer des Anfangsknotens eines jeden Pfeiles von D ist kleiner als die Knotennummer des Endknotens. Insbesondere ist in einem topologisch sortierten Digraphen Knoten 1 eine Quelle und Knoten n eine Senke. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 9 von 39 1.2 DARSTELLUNG VON PROBLEMEN DURCH GRAPHEN 1.2.1 Orgastruktur eines Unternehmens: Direktor Kaufm. Abteilung Techn. Abteilung Konstr. Abt. Prod. Abt. Einkauf Prod. A 1.2.2 Verkauf Prod. B Prod. C Verkehrsnetz, Weg, Rundreise 2 7 5 1 1 1 1 4 3 1 9 5 5 a) b c) Kürzester Weg 1 ->3: w = (1, 4, 3) c(w) = 2 1-4-3 Länge: 2 Kürzeste Rundreise derart, daß jeder Knoten mindestens einmal durchfahren wird: 1-4-2-4-3-4-5-4-1 Kürzeste Rundreise derart, daß jede Kante mindestens einmal durchfahren wird: 1-4-5-4-3-4-2-4-1-2-3-5-1 D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 10 von 39 d) Königsberger Brückenproblem: C g c d e A D f a B b Problem: Existiert eine Rundreise (Rundweg) - von einem beliebigen Startpunkt ausgehend - derart, daß jede Brücke genau einmal benutzt wird ? Darstellung als Graph: C c g d e A D b a f B oder e A d a c C g f D B b Das Problem ist nicht zu lösen, da nicht jeder Knoten eine von einer geraden Anzahl von Kanten berührt wird. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 11 von 39 e) ‚Das Haus vom Nikolaus‘ ‚Die Kirche vom Nikolaus‘ Probleme: können diese Formen gezeichnet werden, ohne den Zeichenstift während der Zeichnung abzuheben und ohne eine Linie mehrfach zu zeichnen ? Graphentheoretisch: Existiert eine Rundreise derart, daß jede Kante genau einmal benutzt wird (Start- und Endpunkt sind identisch) ?Existiert ein Weg derart, daß jede Kante genau einmal benutzt wird (Start- und Endpunkt sind nicht identisch) ? D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 12 von 39 ANMERKUNG: Regeln in ungerichteten Graphen G: Ist der Grad eines jeden Knotens in einem Graphen G gerade, so ist ein geschlossener Weg (Rundreise) w, der jede Kante von G genau einmal enthält (geschlossene Eulerlinie), in G möglich. Ist der Grad von genau 2 Knoten in einem Graphen G ungerade und der Grad aller übrigen Knoten in G gerade, so ist ein offener Weg w, der jede Kante von G genau einmal enthält (offene Eulerlinie), in G möglich. Anfangs- und Endknoten des Weges w sind dabei die beiden Knoten mit ungeradem Grad. 1.2.3 Sympathieproblem: n = 8 Gäste Sympathien : A-B B-A C-D A-F B-E C-G A-G B-H Problem: D-C D-E E-D E-B E-F F-A F-H F-E G-A G-H G-C A,B,C,D,E,F,G,H H-B H-G H-F Ist eine Sitzordnung an einem runden Tisch derart möglich, daß nur Personen nebeneinander sitzen, die sich sympathisch finden ? Darstellung als Graph: C A D B E H F G Graphentheoretisch: Bestimmung einer Rundreise (Startpunkt = Endpunkt) derart, daß jeder Knoten genau einmal benutzt wird Mögliche Lösung: F A E B D H C G D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 13 von 39 1.2.4 Reihenfolge von Einzelarbeiten: Netzplantechnik, Projektmanagement 4 Steckdosen verlegen 1 1 Mauerdurchbrüche 5 Klimakanäle verlegen 4 START 1 1 Klimaanlage bestellen Stromversorgung bestellen 1.2.5 1 Lieferung Klimaanlage 6 Klimaanlage montieren 5 Klimaanlage testen 1 ENDE 1 Erneuerungsproblem: Planungszeitraum: Betriebskosten im i-ten Jahr: Beschaffungskosten zu Beginn des i-ten Jahres: Verkaufswert nach i Jahren: i 1 2 3 4 ci 5 10 15 20 Bi 100 120 100 105 i = 4 Jahre ci Bi Si Si 70 55 30 20 Problem: Bestimmung des optimalen Erneuerungszeitpunktes Graphentheoretisch: Darstellung einer jeden Möglichkeit durch einen mit den entsprechenden Kosten bewerteten Pfeil. Die Knoten stellen die Zeitpunkte dar. Bestimmung des kürzesten Weges von 1 (Startzeitpunkt) nach 5 (Endzeitpunkt) 60 1 35 2 130 100 55 3 35 40 4 5 60 80 120 D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 14 von 39 1.2.6 Umfüllproblem: 3 Behälter: 7 Einheiten: 3 Einheiten: 1 Einheit: Vorgabe Ziel voll (7) 5 leer (0) 1 leer (0) 1 Problem: Ist es möglich durch Umfüllen vom Zustand 700 in den Zustand 511 zu gelangen (die Behälter sind nicht mit Maßstriche gekennzeichnet !) ? Graphentheoretisch: Darstellung aller möglichen Zustandsveränderungen, die mit einmaligem Umschütten erreicht werden können, durch Pfeile. Die Knoten stellen die Zustände dar. Existiert ein Weg von Knoten 700 nach Knoten 511 ? Zustand: 700 Ziel: 511 Möglichkeiten: 700 601 430 601 700 610 331 430 700 331 421 610 700 601 430 511 331 601 430 421 430 520 331 601 511 610 601 331 520 520 421 511 700 430 700 601 Lösung: Problemvariante: Graphentheoretisch : Problemvariante: 610 511 Die Zustandsveränderung soll durch möglichst wenig Umschüttungen erfolgen. Bewertung aller Pfeile mit 1; Bestimmung des kürzesten Weges von Knoten 700 nach 511 Die Zustandsveränderung soll durch möglichst wenig Gewichthochheben erreicht werden Gewicht: 7 EH Gefäß: 4 kg 3 EH Gefäß: 2 kg 1 EH Gefäß: D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 1 kg Seite 15 von 39 Graphentheoretisch: Bewertung der Pfeile mit den entsprechenden Gewichten. 700 Alte Lösung: 7+4 601 1+1 610 6+4 511 430 3+2 421 1+1 520 = 23 kg 700 Optimale Lösung: 7+4 2+2 = 22 kg 1.2.7 Überführungsproblem: F --> W --> Z --> K --> Fährmann Wolf Ziege Kohl - Boot kann nur 2 Objekte transportieren - bei Abwesenheit vom Fährmann frißt der Wolf die Ziege und die Ziege den Kohl F, W, Z, K Ziel: möglichst wenig Überfahrten Zustände vor bzw. nach den Überfahrten. FWZ K WK W FZW FWK K FZK Z Z FZW W FWK FZ FZK D:\IUT-Strasbourg\doc\graph_iut_d.doc FZ WK FWZ K K 27.04.2003 19:52 Seite 16 von 39 511 1.2.8 Transportplanung Hausmüllentsorgung: Die Gemeinde G hat die Möglichkeit den Hausmüll direkt zu den Deponien D1 und D2 oder über die Umladestationen U1 und U2 zu entsorgen. Die dabei entstehenden Transportkosten/Mengeneinheit (TK/ME) sind folgender Tabelle zu entnehmen: U1 15 G U1 U2 1) U2 18 D1 29 6 4 D2 23 3 6 Die Entsorgungsstruktur mit minimalen Transportkosten ist zu ermitteln. Stellen Sie dazu dieses Problem als Graph dar und führen Sie die Lösung des Problems auf eine graphentheoretische Problemstellung zurück. 29 U1 6 D1 3 15 G 4 18 U2 6 D2 23 D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 17 von 39 2) Die Deponierungskosten/ME betragen: D1: 20, D2: 24. Die Entsorgungsstruktur mit minimalen Transport- und Deponierungskosten ist zu ermitteln 29 U1 D1 6 20 3 15 S G 4 18 24 6 U2 D2 23 3) Die Umladekosten/ME betragen: U1: 6, Die Entsorgungsstruktur mit minimalen Umladekosten ist zu ermitteln U2: 4. Transport-, Deponierungs- und 29 U1 6 6 U1' D1 3 15 20 4 G 18 U2 4 U2' S 6 D2 24 23 D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 18 von 39 1.3 Speicherung von Graphen Digraph D1 (siehe oben) a) Adjazenzmatrix: A(D1) 1 0 0 0 0 0 1 2 3 4 5 b) 2 1 0 0 0 1 3 1 0 0 0 1 4 0 1 1 0 0 5 0 1 1 0 0 Bewertungsmatrix: C(D1) 1 2 3 4 5 1 0 ∞ ∞ ∞ ∞ c) Vektorform e1 e2 e3 e4 e5 e6 e7 e8 2 3 0 oo oo 3 3 2 ∞ 0 ∞ 1 4 ∞ 6 2 0 ∞ 5 ∞ 2 1 ∞ 0 d) Vektorform - pfeilsortiert anf end c alt neu 1 1 5 2 5 3 2 3 2 3 2 5 3 5 4 4 3 2 3 2 1 1 6 2 e1 e2 e4 e7 e6 e8 e3 e5 Pfeilnummernvektor: end c 1 1 2 2 3 3 5 5 2 3 5 4 5 4 2 3 3 2 2 6 1 2 3 1 PN 1 2 3 4 5 6 D:\IUT-Strasbourg\doc\graph_iut_d.doc e1 e2 e3 e4 e5 e6 e7 e8 anf 1 3 5 7 7 9 27.04.2003 19:52 Seite 19 von 39 Speicherbedarf Speicherform Anzahl Speicherelemente Beispiel vollständiger Digraph n=100 m=n*(n-1) = 9900 p=1.0 Beispiel Straßennetz SL FL n=800 m=2800 Beispiel Straßennetz BW n=8500 m=25000 p=0.004 p=0.0004 10.000 640.000 72.250.000 29.700 8.400 75.000 19.901 6.401 58.501 Bewertungsmatrix C(D) n*n Pfeilorientiert Anfangsknotenvektor Endknotenvektor Bewertungsvektor pfeilorientiert pfeilsortiert Endknotenvektor Bewertungsvektor Pfeilnummernvektor n: m: p: m m m ∑=3*m m m n+1 ∑=2*m +n+1 Anzahl Knoten Anzahl Pfeile Pfeildichte: m/(n*(n-1)) D:\IUT-Strasbourg\doc\graph_iut_d.doc SL FL: BW: 27.04.2003 19:52 Landkreis Schleswig-Flensburg Baden-Württemberg Seite 20 von 39 2. ALGORITHMEN 2.1-a Bestimmung der Nachfolger eines Knotens i bei vektororientierter Speicherung eines pfeilsortierten Digraphen D Aufbau des Pfeilnummernvektors PN: S1: für i = 1 .. n führe aus: setze PN[n+1] := m+1 setze PN[i] := 0 S2: für alle Pfeile ej in der Reihenfolge j = 1 .. m führe aus: falls ein neuer Anfangsknoten i auftritt, setze PN[i] := j S3: Überprüfung auf Senken (alle Knoten i mit PN[i]=0 sind Senken): für alle PN[i] in der Reihenfolge i = n .. 1 führe aus: falls PN[i]=0, setze PN[i] := PN[i+1] Bestimmung der Nachfolger eines Knoten i: für j = PN[i] .. PN[i+1] - 1 führe aus : der Endknoten des Pfeiles mit Pfeilnummer j ist Nachfolger von i D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 21 von 39 2.1-b Bestimmung der Vorgänger eines Knotens i bei vektororientierter Speicherung eines Digraphen D Benutzung folgender ganzzahliger linearer Felder: ANF_ZEIGER [1..n] TEMP [1..n] VORGÄNGER [1..m] Vorbereitungsschritt: S1: S2: alle Datenknoten der Felder ANF_ZEIGER und VORGÄNGER auf Null setzen Betrachtung der Endknoten aller Pfeile in der Reihenfolge e1, e2, ..., em : Fall 1: Endknoten i tritt zum ersten Male auf: sei j die Pfeilnummer des Pfeiles mit Endknoten i ; setze ANF_ZEIGER [i] := TEMP [i] := j Fall 2: Endknoten i tritt nicht erstmalig auf: die weiteren Pfeilnummern mit Endknoten i werden im Feld VORGÄNGER gespeichert; sei j die Pfeilnummer eines solchen Pfeiles, setze VORGÄNGER [TEMP [i] ] := j TEMP [i] := j Bestimmung der Vorgänger eines Knotens i: j := ANF_ZEIGER [i] solange j <> 0 führe aus : der Anfangsknoten des Pfeiles mit Pfeilnummer j ist Vorgänger von i j := VORGÄNGER [j] D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 22 von 39 2.2-a Bestimmung eines kürzesten Weges (Länge und Verlauf) von einem Startknoten a zu allen anderen Knoten in einem bewerteten Digraphen D = [V,E,c] mit dem Algorithmus von DIJKSTRA Eingabe: a: c[i,j]: Ausgabe: kw_dist[i]: pre[i]: Startknoten Bewertung (Länge) des Pfeiles von i nach j kürzeste Wegelänge von Startknoten a nach i Vorgänger von i auf dem kürzesten Weg von Startknoten a nach i Voraussetzung: D darf keine negativen Bewertungen enthalten S1: Initialisierung: Markiere Startknoten a: sei R die Menge der markierten Knoten, dann gilt a ∈ R (R={a}). Setze für Knoten a: kw_dist[a] := 0, pre[a] := 0. Setze für alle anderen Knoten i (∀i ≠a): kw_dist[i] := ∞, pre[i] := 0. S2: Falls ein oder mehrere Knoten markiert sind (R ≠ ∅): wähle einen Knoten aus mit MIN kw_dist[j], j∈R dieser Knoten sei i; sonst (R = ∅): ENDE Dijkstra-Algorithmus. S3: Für alle Nachfolger j ∈ Si , die noch nicht aus der Markierung entfernt worden sind, führe aus: falls kw_dist[i] + c[i,j] < kw_dist[j]: (1) setze kw_dist[j] := kw_dist[i] + c[i,j], (2) setze pre[j] := i, (3) markiere j (j ∈ R). Entferne die Markierung bei i (i ∉ R). Gehe zu S2. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 23 von 39 2.2-b Bestimmung eines kürzesten Weges (Länge und Verlauf) von einem Startknoten a zu allen anderen Knoten in einem bewerteten Digraphen D = [V,E,c] mit dem Algorithmus von FORD Eingabe: a: c[i,j]: Ausgabe: kw_dist[i]: pre[i]: Startknoten Bewertung (Länge) des Pfeiles von i nach j kürzeste Wegelänge von Startknoten a nach i Vorgänger von i auf dem kürzesten Weg von Startknoten a nach i Voraussetzung: D darf keine negativen Zyklen enthalten S1: Initialisierung: Markiere Startknoten a: sei R die Menge der markierten Knoten, dann gilt a ∈ R (R={a}). Setze für Knoten a: kw_dist[a] := 0, pre[a] := 0. Setze für alle anderen Knoten i (∀i ≠a): kw_dist[i] := ∞, pre[i] := 0. S2: Falls ein oder mehrere Knoten markiert sind (R ≠ ∅): wähle den Knoten aus, der am längsten (kürzesten) in R enthalten ist. dieser Knoten sei i; sonst (R = ∅): ENDE Dijkstra-Algorithmus. S3: Für alle Nachfolger j ∈ Si führe aus: falls kw_dist[i] + c[i,j] < kw_dist[j]: (1) setze kw_dist[j] := kw_dist[i] + c[i,j], (2) setze pre[j] := i, (3) markiere j (j ∈ R). Entferne die Markierung bei i (i ∉ R). Gehe zu S2. D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 24 von 39 2.2-c Bestimmung eines kürzesten Weges von jedem Knoten zu allen anderen Knoten eines bewerteten Digraphen D = [V,E,c], d,h. Erstellung der Entfernungsmatrix K(D) mit dem TRIPEL-Algorithmus Eingabe: C(D): P(D): Bewertungsmatrix Vorgängermatrix Ausgabe: K(D): P(D): Entfernungsmatrix (entstanden aus C(D)) pij: Vorgänger des Knotens j auf dem kürzesten Weg von i nach j Voraussetzung: D darf keine negativen Zyklen enthalten Schritte 1,...,n: Berechne im z-ten (z:=1,..,n) Schritt für alle Elemente cij, die nicht Element der z-ten Zeile, der z-ten Spalte oder der Hauptdiagonalen sind: neu cij alt alt alt : = MIN (cij , ciz + czj ) sowie neu pij := alt neu pzj , falls cij < alt cij alt pij , sonst nach n Schritten: ENDE Tripel-Algorithmus D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 25 von 39 2.3 Tourenplanungsverfahren – Saving Algorithmus Definition: Eindepot-Tourenplanungsproblem (ETP): Gegeben: 1) anzufahrende Auftragsknoten i = 1,2,...,n 2) Depot (Start- und Rückkehrknoten einer Tour) 3) Symmetrisches Straßennetz mit räumlichen oder zeitlichen Entfernungen - zwischen den Auftragsknoten d ij und - Depotentfernungen der Auftragsknoten dpi 4) Liefer- und Sammelmengen q i 5) Standzeit ti 6) einheitliche Kapazität von Q Transporteinheiten (TE) 7) Maximale Tourenlänge T Gesucht: Menge von Touren (Tourenplan) minimaler Gesamtlänge unter Berücksichtigung: - Kapazität Q - Maximale Tourenlänge T - Jeder Auftragsknoten i wird in genau einer Tour angefahren SAVING-Verfahren (Clarke + Wright 1964) S1: Einzelanfahrten für alle Aufträge S2: Berechnung der SAVING-Werte i j dpi dp j D Sij i d ij j dpj dp i D Sij = dpi + dpj - d ij für alle Auftragsknotenpaare n * ( n − 1) Möglichkeiten 2 S3: Absteigende Sortierung der SAVING-Werte S4: Aufbau der Touren mit dem größten SAVING-Wert beginnend ... Lege die Touren, in denen sich i und j befinden durch Verbindung von i und j zusammen, falls 1. Kapazität Q eingehalten wird 2. max. Tourenlänge T eingehalten wird 3. i und j in unterschiedlichen Touren 4. i und j „Endknoten“ (erster oder letzter Auftragsknoten) einer Tour sind D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 26 von 39 Beispiel Savingverfahren T=∞ Q = 18 6 7 29 5 4 6 22 20 8 5 22 38 38 22 3 7 35 2 9 Menge 1 56 38 42 Länge D Entfernungsmatrix (Entfernungstabelle) 1 2 3 1 0 35 22 2 0 57 3 0 4 5 6 D 4 57 22 49 0 5 38 51 20 29 0 6 73 38 71 22 51 0 D 38 42 56 64 76 80 Savingmatrix 1 1 2 3 4 5 6 2 45 D:\IUT-Strasbourg\doc\graph_iut_d.doc 3 72 41 4 45 84 71 27.04.2003 19:52 5 76 67 112 111 6 45 84 65 122 105 Seite 27 von 39 S1: Ausgangslösung D-1-D D-2-D D-3-D D-4-D D-5-D D-6-D Summe: Menge Länge 7 76 9 84 8 112 7 128 6 152 5 160 42 712 S2: Berechnung der SAVING-Werte: Sij = dpi + dpj - d ij S12 = dp1 + dp2 - d12 = 38 + 42 - 35 = 45 S46 = dp4 + dp6 - d46 = 64 + 80 - 22 = 122 S3: Absteigende Sortierung der Savingwerte S4: Aufbau der Touren: mit dem größten Savingwert beginnend: Lege die Touren, in denen sich i und j befinden durch Verbindung von i und j zusammen, falls 1. Kapazität Q eingehalten wird 2. max. Tourenlänge T eingehalten wird 3. i und j in unterschiedlichen Touren 4. i und j „Endknoten“ einer Tour sind Saving-Wert bei (4/6) = 122 1. 2. 3. 4. Q = 18, erfüllt T = oo , erfüllt erfüllt erfüllt ==> D-1-D D-2-D D-3-D D-4- 6-D D-5-D Summe: Saving-Wert bei (3/5) = 112 D:\IUT-Strasbourg\doc\graph_iut_d.doc 1. 2. 3. 4. Menge Länge 7 76 9 84 8 112 12 166 6 152 42 590 Q erfüllt T erfüllt erfüllt erfüllt 27.04.2003 19:52 Seite 28 von 39 ==> Menge Länge D-1-D 7 76 D-2-D 9 84 D-3- 5-D 14 152 D-4- 6-D 12 166 Summe: 42 478 Saving-Wert bei (4/5) = 111 1. Q nicht erfüllt Saving-Wert bei (5/6) = 105 1. Q nicht erfüllt ... ... Saving-Wert bei (1/2) = 45 1. 2. 3. 4. Q erfüllt T erfüllt erfüllt erfüllt ==> D-1- 2-D D-3- 5-D D-4- 6-D Summe: Menge Länge 16 115 14 152 12 166 433 42 Für Q = 22 Saving-Wert bei (4/6) = 122 1. 2. 3. 4. Q erfüllt T erfüllt erfüllt erfüllt ==> D-1-D D-2-D D-3-D D-4- 6-D D-5-D Summe: Saving-Wert bei (3/5) = 112 D:\IUT-Strasbourg\doc\graph_iut_d.doc 1. 2. 3. 4. Menge Länge 7 76 9 84 8 112 12 166 6 152 42 590 Q erfüllt T erfüllt erfüllt erfüllt 27.04.2003 19:52 Seite 29 von 39 ==> D-1-D D-2-D D-3- 5-D D-4- 6-D Summe: Menge Länge 7 76 9 84 14 152 12 166 42 478 Saving-Wert bei (4/5) = 111 1. Q nicht erfüllt Saving-Wert bei (5/6) = 105 1. Q nicht erfüllt 1. 2. 3. 4. Q erfüllt T erfüllt erfüllt erfüllt ... Saving-Wert bei (2/4) = 84 ... ==> D-1-D D-2- 4-6D D-3- 5-D Summe: Saving-Wert bei (1/5) = 76 1. 2. 3. 4. Menge Länge 7 76 21 166 14 42 152 394 Q erfüllt T erfüllt erfüllt erfüllt ==> D-3- 5-1-D D-2- 4-6-D Summe: D:\IUT-Strasbourg\doc\graph_iut_d.doc Menge Länge 21 152 21 166 318 42 27.04.2003 19:52 Seite 30 von 39 Darstellung von Verkehrsknoten mit Fahrtrichtungsvorschriften: Straßenkreuzung 2 als Digraph 2 2 3 2 5 2 1 4 3 5 3 5 3 2 4 2 3 2 2 4 Kreuzung + 1 Schild 2 Einführung von 5A , (geographisch identisch mit 5) 2 2 3 2 2 5 4 1 5A 5 0 3 3 5 4 3 2 3 2 2 2 4 D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 31 von 39 Übung P 3.1 Gegeben ist ein bewerteter Digraph D3_1a = [V,E,c] mit V = {1,2,...,7} und E = {e1,e2,...,e12} (siehe Datei d3_1a.net ): 2 e1 2 1 7 4 e2 1 e4 3 2 e6 1 4 e10 2 7 e7 3 e5 e3 6 e11 5 e8 1 1 3 e9 e12 7 Erstellen Sie ein PASCAL-Programm: a) Speichern Sie den Digraphen D3_1a in einer Bewertungsmatrix C(D) und geben Sie die Bewertungsmatrix C(D) aus. b) Speichern Sie den Digraphen D3_1a in Vektorform (pfeilsortiert) und geben Sie die einzelnen Vektoren aus. c) Bestimmen Sie die Nachfolger z.B. der Knoten 1,6,7 in beiden Speicherungsformen. d) Bestimmen Sie die Vorgänger z.B. der Knoten 1,3,5 in beiden Speicherungsformen. e) Führen Sie die Aufgaben a) - d) ebenfalls für den folgenden Digraphen D3_1b durch (siehe Datei d3_1b.net) 4 1 2 e2 3 2 D:\IUT-Strasbourg\doc\graph_iut_d.doc 1 e1 3 e3 4 e4 5 27.04.2003 19:52 Seite 32 von 39 Anmerkungen: 1) Verwenden Sie auch zukünftig folgende Konstanten, Datentypen und Variablen: const nmax nmax_plus_1 nmax_matrix mmax unendlich type matrix = knotenfeld knoten_plus_1_feld pfeilfeld stringfeld = = = = var n : Graphen} m : c : anfknoten : endknoten : cbewertung: pn : anf_zeiger : temp : vorgaenger : datei_name: ort : = = = = = word; 380; 381; 140; 1500; 15000; array [1..nmax_matrix,1..nmax_matrix] of word; array [1..nmax] of word; array[1..nmax_plus_1] of word; array [1..mmax] of word; array [1..nmax] of string[30]; {Anzahl Knoten des aktuellen word; {Anzahl Pfeile des aktuellen Graphen} matrix; {Bewertungsmatrix} pfeilfeld; {Anfangsknotennummernvektor} pfeilfeld; {Endknotennummernvektor} pfeilfeld; {Bewertungsvektor} knoten_plus_1_feld; {Pfeilnummernvektor} knotenfeld;{siehe Algorithmus 2.1b} knotenfeld;{siehe Algorithmus 2.1b} pfeilfeld; {siehe Algorithmus 2.1b} string; stringfeld; {Ortsnamenvektor} 2) Verwenden Sie zum Einlesen der Digraphen die Einleseprozedur READNETDATEI (datei_name, anfknoten, endknoten, cbewertung, n, m) zum Lesen der *.net-Dateien (siehe Programmdatei readnet.inc). 3) Verwenden Sie zur Pfeilsortierung der Digraphen die Sortierprozedur QUICKERSORT (anfknoten, endknoten, cbewertung, 1,m) (siehe Programmdatei qsort3.inc). D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 33 von 39 Übung 3.2 Implementierung des Dijkstra-Algorithmus a) auf der Basis der Bewertungsmatrix C(D) b) auf der Basis der pfeilorientierten Speicherung Benutzen Sie den Digraphen D3_1a und die folgenden Straßennetze zum Testen: Region Bad Dürkheim (dh.net) n=69 m=226 Region Cleebourg (elsass_n.net) n=101 m=322 Deutschland (brd.net) n=584 m=2218 Baden Württemberg (bw.net) n=8494 m=24844 Benutzen Sie zum Einlesen der Knotennamen die Prozedur READKDNDATEI (datei_name, ort, n) (siehe readkdn.inc) Übung 3.3 Implementierung des Ford-Algorithmus a) auf der Basis der Bewertungsmatrix C(D) b) auf der Basis der pfeilorientierten Speicherung Testdaten wie Übung 3.2 Übung 3.4 Implementierung des Tripel-Algorithmus Benutze als Testdaten D:\IUT-Strasbourg\doc\graph_iut_d.doc D3_1a.net dh.net elsass_n.net 27.04.2003 19:52 Seite 34 von 39 Projekt 3.5 Erstellen Sie ein Pascal-Programm zur Ermittlung eines Tourenplanes für das Ein-Depot-Tourenplanungsproblem unter Benutzung des Savingverfahrens. Straßennetz: n Knoten Auftragsknoten: Knoten 1,...,n-1 Depotknoten: Knoten n Anmerkungen: 1) Verwenden Sie folgende Konstanten, Typen und Variablen: const nmax = nmax_plus_1= mmax = svmax = unendlich = 140; 141; 500; 9730; (* svmax:=nmax*(nmax-1)/2 *) 15000; type knotenfeld knoten_plus_1_feld pfeilfeld stringfeld svfeld indexfeld index var n m anzKunden anzKnotenpaare : : : : anzTouren anzKundenTour depot anfknoten endknoten cbewertung pn dist : : : : : : : : pre : sv : D:\IUT-Strasbourg\doc\graph_iut_d.doc = = = = = = = array[1..nmax] of word; array[1..nmax_plus_1] of word; array[1..mmax] of word; array[1..nmax] of string[25]; array[1..svmax] of integer; array[1..svmax] of byte; word; word; word; word; word; (* Anzahl Knoten des aktuellen Graphen *) (* Anzahl Pfeile des aktuellen Graphen *) (* Anzahl anzufahrender Knoten = n-1 *) (* Anzahl moeglicher Knotenpaare (nur *) (* Kndenknoten) = anzKunden*(ankunden *) (* -1)/2 *) word; (* Anzahl der Touren *) word; (* Anzahl Kunden in der aktuellen Tour *) word; (* Depotknoten = n *) pfeilfeld; (* Anfangsknotenvektor *) pfeilfeld; (* Endknotenvektor *) pfeilfeld; (* Bewertungsvektor *) knoten_plus_1_feld; (* Pfeilnummernvektor *) knotenfeld; (* dist(i) enthaelt die Laenge des kuerzesten Weges vom Starknoten a zu Knoten i *) knotenfeld; (* pre(i) enthaelt den Vorgaenger von Knoten i auf dem kuerzesten Weg von Startknoten a nach i *) svfeld; (* untere Dreiecksmatrix der Savingmatrix ohne Haupdiagonale - zeilenweise *) 27.04.2003 19:52 Seite 35 von 39 dp : knotenfeld; (* dp(i) enthaelt die kuerzeste Entfernung vom Depot zum Knoten i *) menge : knotenfeld; (* menge(i) enthaelt die beim Kundenknoten i auszuliefernde bzw. einzusammelnde Menge *) standzeit : knotenfeld; (* standzeit(i) enthaelt die beim Kundenknoten i zur Auslieferung bzw. zur Einsammlung benoetigte Aufenthaltszeit *) z : knotenfeld; (* z(i) enthaelt die Tournummer, in der Knoten i liegt *) r : array[1..nmax,1..2] of byte; (* r(i,j) : Knoten i liegt in der Tour z(i) zwischen den Knoten r(i,1) und r(i,2); r(i,j)=0 entspricht dabei dem Depot *) kapazitaet : word; max_Tourenlaenge: word; iindex, jindex : indexfeld; (* iindex(i), jindex(i) enthalten die Knoten, die zum Savingwert sv(i) gehoeren *) ort : stringfeld; (* ort(i) enthaelt den Ortsnamen des Knotens i ) gesamtmenge : word; gesamtzeit : word; x : real; datei_name : string; 2. Verwenden Sie zum Einlesen der Straßennetze die Prozedur READNETDATEI (datei_name, anfknoten, endknoten, cbewertung, n, m) (siehe readnet.inc) Dateien: p4_8.net(Vorlesungsbeispiel), angeln1.net, dh1.net, dh2.net 3. Verwenden Sie zum Einlesen der Auftragsdaten die Prozedur READKDNDATEI (datei_name,menge,standzeit,ort,n) (siehe readkdns.inc) Dateien: p4_8.kdn, angeln1.kdn, dh1.kdn, dh2.kdn 4. Verwenden Sie zum Sortieren der Savingwerte die Prozedur QUICKERSORT_SV(sv,iindex,jindex,1,anzKnotenpaare) (siehe qsort3sv.inc) Beachten Sie, daß QUICKERSORT_SV aufsteigend sortiert ! D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 36 von 39 ANHANG Borland Pascal 7.0 Programmaufbau Programmkopf Deklarationsteil (Vereinbarungsteil) CONST, VAR-> Reservierung von entsprechendem Speicherplatz im Hauptspeicher Programmkörper (Anweisungsteil) PROGRAM <Name> ; [USES <Name> ;] [CONST <Name > = <Wert> ;] [TYPE <Name> ;] [VAR <Name> : <Datentyp>;] [PROCEDURE ... ;] [FUNCTION ... ;] BEGIN Anweisung 1 ; ... Anweisung n ; END. Regeln für Namen (Bezeichner): 1. gültige Zeichen: A,...,Z, a,...,z (keine Umlaute, kein ‘ß’) 0,...,9 Sonderzeichen nur ‘_’ 2. 1. Zeichen muß Buchstabe sein 3. Zeichen 1-63 signifikant (alle weiteren Zeichen werden ignoriert) Beispielprogramm: PROGRAM Mein_erstes_Pascal_Programm; VAR a, b : INTEGER; BEGIN WRITE(‘A, B eingeben (A, B ganzzahlig): ‘); READLN (a,b); {Eingabe} a := a + b; {Berechnung} WRITELN (‘A = ‘,a:5); {Ausgabe} END. Erläuterungen: VAR ... WRITE(...); READLN(...); a:= a+b; WRITELN(...); ; Speicherplatzreservierung im Hauptspeicher Ausgabe Bildschirm (Text in ‘...’) Eingabe über Tastatur := ist Zuweisungsoperator (kein ‘ist gleich’ !!!) wie WRITE, jedoch mit Zeilenvorschub nach Ausgabe Begrenzer D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 37 von 39 Datentypen A) Ganze Zahlen (z.B. 3, -10, 678) INTEGER Speicherbedarf: 2 Byte Wertebereich: - 32 768,..., + 32 767 LONGINT Speicherbedarf: 4 Byte Wertebereich: - 2 147 483 648,..., + 2 147 483 647 BYTE Speicherbedarf: 1 Byte Wertebereich: 0,.., + 255 SHORTINT Speicherbedarf: 1 Byte Wertebereich: -128,..., +127 WORD Speicherbedarf 2 Byte Wertebereich: 0,..., + 65 535 B) Reelle Zahlen (z.B. 1.27 0.5678) REAL Speicherbedarf: 6 Byte Wertebereich: ±1.7*1038,...,±2.9*10 -39 Genauigkeit: 11-12 Stellen C) Zeichenketten (Strings) (z.B. ‘Guten Morgen’, ‘A107’, ‘24beta’) CHAR Speicherbedarf: 1 Byte Zeichenbereich: ASCII-Zeichen Zeichenanzahl: 1 STRING Speicherbedarf: 256 Byte Zeichenbereich: ASCII-Zeichen Zeichenanzahl: 255 STRING[n] Speicherbedarf: (n+1) Byte Zeichenbereich: ASCII-Zeichen Zeichenanzahl: n D) Boolean (Wahrheitswerte) BOOLEAN Speicherbedarf: 1 Byte Wertebereich: true, false D:\IUT-Strasbourg\doc\graph_iut_d.doc 27.04.2003 19:52 Seite 38 von 39 OPERATOREN Arithmetische Operatoren Operation Operator Operation Addition + Subtraktion - a+b m+n a-b m-n a*b m*n a/b (b≠0) m/n (n≠0) m DIV n Multiplikation * Division / IntegerDivision Modulo DIV a+b m+n a-b m-n a*b m*n a/b m/n Datentyp Ergebnis REAL INTEGER REAL INTEGER REAL INTEGER REAL REAL 4 DIV 3 -> 1 INTEGER 11 DIV 2 -> 5 m MOD n m-(m DIV n)*n INTEGER 10 MOD 3 -> 1 m,n: INTEGER MOD a,b: REAL Vergleichs- und logische Operatoren Operation Operator Gleich = Ungleich <> Größer > Kleiner < größer gleich >= kleiner gleich <= Oder OR Und AND Verneinung NOT a, b : INTEGER; a := 5; b := 10; D:\IUT-Strasbourg\doc\graph_iut_d.doc Wert Beispiel Ergebnis a=b false a <> b true a>b false a<b true a >= b false a <= b true u OR u true u OR v true v OR u true v OR v false u AND u true u AND v false v AND u false v AND v false NOT u false NOT v true u, v : BOOLEAN; u := true; v := false; 27.04.2003 19:52 Seite 39 von 39