Rekursion. Koffman & Wolfgang kapitel 5

Relevanta dokument
Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Föreläsning 6 Innehåll. Rekursion. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursiv problemlösning. Rekursion. Rekursivt tänkande:

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Föreläsning 5. Rekursion

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

Rekursion och induktion för algoritmkonstruktion

Föreläsning 13. Rekursion

Föreläsning 11: Rekursion

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Föreläsning 8 Innehåll

Exempel: Förel Rekursion III Nr 14. Uno Holmer, Chalmers,

Föreläsning 6. Rekursion och backtracking

F11 - Rekursion. ID1004 Objektorienterad programmering Fredrik Kilander

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Föreläsning 1, vecka 7: Rekursion

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Objektorienterad programmering E. Back to Basics. En annan version av printtable. Ett enkelt exempel. Föreläsning 10

Föreläsning 6. Rekursion och backtracking

Rekursion och induktion för algoritmkonstruktion

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Föreläsning 6: Introduktion av listor

Sökning och sortering

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Föreläsning 5. Rekursion

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Rekursion och induktion för algoritmkonstruktion

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Föreläsning 11 Datastrukturer (DAT037)

Föreläsning 9 Datastrukturer (DAT037)

Föreläsning 8: Exempel och problemlösning

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

Föreläsning 7. Träd och binära sökträd

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Algoritmer. Två gränssnitt

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Lösningsförslag till tentamen Datastrukturer, DAT037,

Datastrukturer. föreläsning 3. Stacks 1

Lösningsförslag: Instuderingsfrågor, del D

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

Lösning av några vanliga rekurrensekvationer

Föreläsning 2 Datastrukturer (DAT037)

Typkonvertering. Java versus C

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

Tentamen i Algoritmer & Datastrukturer i Java

Lösningsförslag till exempeltenta 1

Tentamen ID1004 Objektorienterad programmering May 29, 2012

Tentamen, Algoritmer och datastrukturer

Programmering för språkteknologer II, HT2014. Rum

Tommy Färnqvist, IDA, Linköpings universitet. 2 Rekursion i C Implementation av rekursion Svansrekursion En till övning...

Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016

Föreläsning 3. Stack

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Lägg uppgifterna i ordning. Skriv uppgiftsnummer och din kod överst i högra hörnet på alla papper.

Föreläsning 3. Stack

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Föreläsning Datastrukturer (DAT036)

Arrayer (fält)

DAI2 (TIDAL) + I2 (TKIEK)

Generiska konstruktioner. Kursbokens kapitel 13

Tentamen OOP

Föreläsning 2, vecka 8: Repetition

Den som bara har en hammare tror att alla problem är spikar

Repetition av OOP- och Javabegrepp

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Medan ni väntar. 2. Skriv metoden. 3. Skriv metoden. Naturligtvis rekursivt och utan användning av Javas standardmetoder.

Objektorienterad programmering Föreläsning 9. Copyright Mahmud Al Hakim Agenda (halvdag)

DAT043 Objektorienterad programmering för D, DIT011 Objektorienterad programvaruutveckling för GU

Repetition i Python 3. Exemplen fac. Exemplen fac motivering. Exemplen fac i Python

Föreläsning 12: Exempel och problemlösning

Föreläsning 3-4 Innehåll

Repetition av OOP- och Javabegrepp

Föreläsning 4 Datastrukturer (DAT037)

TENTAMEN OOP

Idag. Exempel, version 2. Exempel, version 3. Ett lite större exempel

Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Procedurer och villkor

1 Comparator & Comparable

TDDC74 Lab 02 Listor, sammansatta strukturer

Länkade strukturer, parametriserade typer och undantag

Lösningsförslag till tentamen Datastrukturer, DAT037 (DAT036), Tiden det tar att utföra en iteration av loopen är oberoende av värdet på

I ett program hantera man ofta samlingar av objekt av samma typ.

Tentamen TEN1 HI

Att skriva till och läsa från terminalfönstret

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Tentamen Datastrukturer D DAT 035/INN960 (med mycket kortfattade lösningsförslag)

Tentamen. Programmeringsmetodik, KV: Java och OOP. 17 januari 2002

Föreläsning 2 Datastrukturer (DAT037)

Kungl. Tekn. Högskolan Förel 1, bild 1 Föreläsning 1: Introduktion ffl Kursinnehåll ffl Javarepetition ffl Referenser ffl Nyckelordet static ffl Klass

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 4 Om rekursion. PK1&PM1 HT-06 moment 4 Sida 1 Uppdaterad

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Föreläsning REPETITION & EXTENTA

Exempel på listor (klassen ArrayList). Ett exempel med fält. Avbildning är en speciell typ av lista HashMap.

Transkript:

Rekursion Koffman & Wolfgang kapitel 5 1

Rekursivt tänkande Rekursion reducerar ett problem till en eller flera enklare versioner av samma problem. med enklare menas att underproblemen måste vara mindre, enligt något sätt att räkna t.ex. genom storleken på indata kallas också divide-and-conquer 2

Stegen i en rekursiv algoritm Det måste finnas ett eller flera fall som kan lösas direkt: basfall, för små värden på n För alla större n-värden måste problemet kunna reduceras till en eller flera delproblem: rekursionsfall delproblemen är mindre versioner av samma problem alla delproblem måste vara mindre än huvudproblemet (mindre n-värden) det måste gå att kombinera delproblemens lösningar till en lösning av huvudproblemet 3

Enkla rekursiva definitioner De enklaste rekursionerna är lite meningslösa: public static int length(linkedlist<e> list) { if (list == null) return 0; else return 1 + length(list.next); för de kan lika gärna definieras med en loop: public static int length(linkedlist<e> list) { int len = 0; while (list!= null) { len++; list = list.next; return len; 4

En till enkel rekursiv definition Fakulteten är definierad som: n! = n (n-1)!, om n>0 0! = 1 Den rekursiva definitionen är snarlik: public static int factorial(int n) { if (n == 0) return 1; else return n * factorial(n 1); men den iterativa versionen är inte så komplicerad den heller: public static int factorial(int n) { int fac = 1; for (int i = 1; i <= n; i++) fac *= i; return fac; 5

Att bevisa korrekthet Korrekthet för rekursiva algoritmer bevisas med induktion: visa att alla basfall täcks av implementationen, och löses korrekt visa att varje rekursivt anrop minskar n visa att om varje delproblem (n < n) är löst korrekt, så blir också huvudproblemet (n) korrekt löst 6

7 Att spåra (trace) rekursion

Oändlig rekursion Om du anropar factorial med ett negativt värde, så kommer rekursionen inte att terminera: till slut kommer du få ett StackOverflowError factorial saknar alltså ett basfall Var alltid noga med att täcka alla möjliga basfall, även de felaktiga: t.ex. negativa värden om argumentet är felaktigt så kan du kasta ett IllegalArgumentException 8

Största gemensamma delaren Greatest common divisor (gcd) gcd(m, n) är det största heltal som delar både m och n gcd(20, 15) = 5 gcd(36, 24) = 12 gcd(38, 18) = 2 gcd(17, 97) = 1 dvs, 17 och 97 är relativt prima 9

Euklides algoritm för gcd För att beräkna gcd(m, n), där m n gcd(m, 0) = m gcd(m, n) = gcd(n, m % n) Om m < n, så vänder vi bara på argumenten. 10

Euklides algoritm (forts.) Rekursiv version: public static long gcd(long m, long n) { if (n == 0) return m; else return gcd(n, m % n); eller iterativ: public static long gcd(long m, long n) { while (n!= 0) { long temp = m % n; m = n; n = temp; return m; 11

Euklides algoritm (forts.) Rekursiv version: public static long gcd(long m, long n) { if (n == 0) return m; else return gcd(n, m % n); eller iterativ: public static long gcd(long m, long n) { while (n!= 0) { long temp = m % n; m = n; n = temp; return m; OBS! detta förutsätter att m n det är en invariant, som vi måste visa alltid är sann vilket den är eftersom n (m % n) 11

Rekursion vs iteration Rekursion och iteration är lika kraftfulla: det går alltid att översätta en rekursiv lösning till en iterativ enklare rekursioner översätts till iterativa loopar mer komplexa rekursioner kräver en eller flera stackar det går alltid att översätta en iterativ lösning till en rekursiv loopar översätts till svansrekursiva funktioner Vilket som är bäst är en fråga om tycke och smak 12

Fibonacciserien Definition: fib0 = 0 fib1 = 1 fibn = fibn-1 + fibn-2 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 13

En dum implementation public static long fibonacci(long n) { if (n <= 1) return n; else return fibonacci(n 1) + fibonacci(n 2); 14

En dum implementation public static long fibonacci(long n) { if (n <= 1) return n; else return fibonacci(n 1) + fibonacci(n 2); 14

En dum implementation public static long fibonacci(long n) { if (n <= 1) return n; else return fibonacci(n 1) + fibonacci(n 2); 14 dubbelarbete!

En dum implementation public static long fibonacci(long n) { if (n <= 1) return n; else return fibonacci(n 1) + fibonacci(n 2); 14 dubbelarbete!

En dum implementation public static long fibonacci(long n) { if (n <= 1) return n; else return fibonacci(n 1) + fibonacci(n 2); 14 dubbelarbete!

En bättre implementation public static long fibonacci(long n) { return fibo(1, 0, n); fibk fibk-1 static long fibo(long current, long previous, int n) { if (n == 1) return current; else return fibo(current + previuos, current, n 1); fibk+1 = fibk + fibk-1 fibk 15

En iterativ implementation public static long fibonacci(long n) { long previous = 0; long current = 1; for (var i = 2; i <= n; i++) { long temp = previous; previous = current; current += temp; return current; 16

Binärsökning i ett sorterat fält Antag att vi ska leta efter ett objekt i ett sorterat fält: då kan vi jämföra vårt objekt med mittelementet om de inte är lika så fortsätter vi leta, antingen i elementen till vänster eller till höger om mittelementet istället för att fortsätta leta bland n 1 element, så letar vi bland n/2 element 17

Binärsökning (forts.) Rekursiv algoritm för att söka efter ett objekt i ett fält: om fältet är tomt: returnera 1 annars, om målobjektet är lika med mittelementet: returnera mittelements position annars, om målobjektet är mindre än mittelementet: sök rekursivt bland elementen som ligger före mittelementet annars är målobjektet större än mittelementet: sök rekursivt bland elementen som ligger efter mittelementet 18

Comparable-gränssnittet Comparable-gränssnittet deklarerar metoden compareto() Metodanropet obj1.compareto(obj2) ska returnera ett heltal med följande värden: negativt om obj1 < obj2 noll om obj1 == obj2 positivt om obj1 > obj2 19

20 Binärsökning i ett fält

Binärsökning, exempel Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 21

Binärsökning, exempel target = Dustin Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 21

Binärsökning, exempel target = Dustin Första anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 21

Binärsökning, exempel target = Dustin Första anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Första anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Andra anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Andra anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Andra anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Tredje anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 first middle last 21

Binärsökning, exempel target = Dustin Tredje anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 last middle first 21

Binärsökning, exempel target = Dustin Tredje anropet Caryn Debbie Dustin Elliot Jacquie Jonathon Rich 0 1 2 3 4 5 6 last middle first 21

Binärsökning, iterativt Binärsökning är fortfarande enkelt att implementera iterativt. Iterativ algoritm binarysearch(e[] A, E target): first = 0, last = A.length 1 repetera ända tills first > last: middle = (first + last) / 2 om A[middle] == target: return middle om A[middle] < target: last = middle 1 om A[middle] > target: first = middle + 1 return 1 22

Förvillkor och invariant Binärsökning har ett viktigt förvillkor: fältet måste vara sorterat, annars blir resultatet odefinierat sådana förvillkor måste skrivas i dokumentationen för en metod/funktion Under förutsättning att fältet är sorterat så kan vi formulera en invariant för binärsökningen: first middle last, och A[first] target A[last] Att formulera bra invarianter och förvillkor är nödvändigt för att kunna bevisa att algoritmer är korrekta 23

Binärsökning, effektivitet Vid varje rekursivt anrop (iterativ loop) eliminerar vi halva fältet O(log n) Ett fält med 16 element kommer alltså att söka igenom delfält med storlekarna 16, 8, 4, 2 och 1 fem jämförelser i värsta fall: 16 = 2 4 5 = log2 16 + 1 Ett dubbelt så stort fält kräver endast 6 jämförelser i värsta fall: 32 = 2 5 6 = log2 32 + 1 Ett fält med 32 768 element kräver endast 16 jämförelser! 16 = log2 32768 + 1 24

Arrays.binarySearch Javas API-klass Arrays innehåller en binärsökning i fält: java.util.arrays.binarysearch(e[], E) anropas med sorterade fält om elementen inte är jämförbara, eller om fältet inte är sorterat, så är resultatet odefinierat dvs, det kastar inte ett Exception! om det finns flera kopior av samma objekt, så vet vi inte vilken som kommer att hittas 25

Avancerad rekursion Hittills har vi tittat på enkla rekursioner med precis lika enkla (eller enklare) iterativa alternativ de rekursiva anropen motsvarar loopar Mer komplexa rekursiva algoritmer är inte lika enkla att översätta iterativt de behöver en stack (eller någon annan datastruktur) för att lagra de rekursiva anropen (eller flera stackar, eller en stack av stackar ) 26

En stack istället för rekursion Medelkomplex rekursion kräver en explicit stack för att kunna översättas iterativt: push() motsvaras av ett rekursivt anrop pop() motsvaras av att returnera rekursionen använder sig av Javas egen call stack, medan den iterativa varianten måste använda en egen stack Vilket sätt som är enklast är en fråga om tycke och smak: iteration med en explicit stack en implicit stack genom rekursiva anrop Det finns rekursiva algoritmer där det inte räcker med en enda stack, utan det istället behövs en trädstruktur 27

Balanserade parenteser, iterativt private static final String PARENS = "()[]{"; public static void parseparensiterative(string str) throws ParseException { Stack<Integer> parenstack = new Stack<Integer>(); for (int i = 0; i < str.length(); i++) { char c = str.charat(i); int paren = PARENS.indexOf(c); if (paren >= 0) { if (paren % 2 == 0) { parenstack.push(paren); else { if (parenstack.empty()) throw new ParseException("Too many close parentheses", i); int openparen = parenstack.pop(); if (paren!= openparen + 1) throw new ParseException("Unbalanced parentheses", i); if (!parenstack.empty()) throw new ParseException("Too many open parentheses", str.length()); 28

Balanserade parenteser, rekursivt public static void parseparensrecursive(string str) throws ParseException { parseparensrecursive(str, 0, -1); 29 private static int parseparensrecursive(string str, int i, int openparen) throws ParseException { Stack<Integer> parenstack = new Stack<Integer>(); for (int i = 0; i < str.length(); i++) { char c = str.charat(i); int paren = PARENS.indexOf(c); if (paren >= 0) { if (paren % 2 == 0) { i = parseparensrecursive(str, i+1, paren); else { if (!parenstack.empty()) if (openparen < 0) throw new ParseException("Too many close parentheses", i); int openparen = parenstack.pop(); if (paren!= openparen + 1) throw new ParseException("Unbalanced parentheses", i); return i; if (!parenstack.empty()) if (openparen >= 0) throw new ParseException("Too many open parentheses", i); return i;

Tornen i Hanoi Du ska flytta alla brickor till en annan pinne: endast en bricka i taget (den översta) får flyttas en större bricka får inte placeras på en mindre 30

Algoritm för tornen i Hanoi Lösning till 3-bricksproblemet: att flytta de tre brickorna från pinne L till pinne R. (1) flytta de två översta brickorna från pinne L till pinne M (2) flytta den understa brickan från pinne L till pinne R (3) flytta de två översta brickorna från pinne M till pinne R 31

Algoritm för tornen i Hanoi Dellösning till 3-bricksproblemet: att flytta de två brickorna från pinne M till pinne R. (1) flytta den översta brickan från pinne M till pinne L (2) flytta den understa brickan från pinne M till pinne R (3) flytta den översta brickan från pinne L till pinne R 32

Algoritm för tornen i Hanoi Lösning till 4-bricksproblemet: att flytta de fyra brickorna från pinne L till pinne R. (1) flytta de tre översta brickorna från pinne L till pinne M (2) flytta den understa brickan från pinne L till pinne R (3) flytta de tre översta brickorna från pinne M till pinne R 33

Tornen i Hanoi, rekursivt Rekursiv algoritm för n-bricksproblement, att flytta n brickor från pinne A till pinne B, med mellanpinne C. Om n = 1: (1) flytta bricka nr 1 (den minsta brickan) från A till B Annars: (2) flytta de n 1 översta brickorna från A till C (3) flytta bricka n från A till B (4) flytta de n 1 översta brickorna från C till A 34

Backtracking Backtracking är ett sätt att leta efter en lösning genom systematiskt pröva alla möjligheter T.ex. när du letar efter en väg genom en labyrint: när du stöter på en vägkorsning så prövar du först det ena alternativet om det misslyckas prövar du nästa alternativ fortsätt så för varje vägkorsning i labyrinten 35

Hitta en stig genom en labyrint Problembeskrivning: labyrinten är en matris med färgade celler startpunkten är övre vänstra hörnet (0, 0) utgången är nedre högra hörnet (n 1, m 1) alla öppna celler har färgen ÖPPEN alla väggar har färgen VÄGG Lösningsskiss: vi prövar rekursivt alla grannar celler som vi har besökt får färgen BESÖKT om cellen är en vägg eller redan besökt så misslyckas vi och backtrackar genom att pröva en tidigare granne om vi hittar en stig så ger vi den färgen STIG 36

Rekursiv algoritm för att hitta genom en labyrint Rekursiv algoritm hittastig(cell) om cell är utanför labyrinten, eller har färgen VÄGG eller BESÖKT: return false om cell är labyrintens utgång: ge cell färgen STIG return true ge cell färgen BESÖKT för varje granne till cell: om hittastig(granne): ge cell färgen STIG return true return false 37

Rekursiv algoritm för att hitta genom en labyrint Rekursiv algoritm hittastig(cell) om cell är utanför labyrinten, eller har färgen VÄGG eller BESÖKT: return false om cell är labyrintens utgång: ge cell färgen STIG return true ge cell färgen BESÖKT för varje granne till cell: om hittastig(granne): ge cell färgen STIG return true return false rekursivt anrop 37

Rekursiv algoritm för att hitta genom en labyrint Rekursiv algoritm hittastig(cell) om cell är utanför labyrinten, eller har färgen VÄGG eller BESÖKT: return false om cell är labyrintens utgång: ge cell färgen STIG return true ge cell färgen BESÖKT för varje granne till cell: om hittastig(granne): ge cell färgen STIG return true return false backtracking rekursivt anrop 37

n-queens puzzle Problembeskrivning: att ställa ut n schackdamer på ett n n-bräde, så att ingen dam hotar någon annan dam http://en.wikipedia.org/wiki/eight_queens_puzzle Lösningsförslag: för att fylla rad k: placera drottningen på någon kolumn försök fylla rad k+1 (rekursivt) om det misslyckas, placera ut drottningen på en ny kolumn (backtracking) 38

damproblemet i Java private int[] queens; public int[] solvequeens(int N) { queens = new int[n]; solvequeensrow(0, N); return queens; private boolean solvequeensrow(int n, int N) { if (n == N) { return true; else { for (int i = 0; i < N; i++) { queens[n] = i; if (isconsistent(queens, n)) if (solvequeensrow(n+1, N)) return true; return false; 39 kod lånad från: http://introcs.cs.princeton.edu/java/23recursion/queens.java.html

damproblemet i Java private int[] queens; public int[] solvequeens(int N) { queens = new int[n]; solvequeensrow(0, N); return queens; private boolean solvequeensrow(int n, int N) { if (n == N) { return true; else { for (int i = 0; i < N; i++) { queens[n] = i; if (isconsistent(queens, n)) if (solvequeensrow(n+1, N)) return true; return false; rekursivt anrop 39 kod lånad från: http://introcs.cs.princeton.edu/java/23recursion/queens.java.html

damproblemet i Java private int[] queens; public int[] solvequeens(int N) { queens = new int[n]; solvequeensrow(0, N); return queens; private boolean solvequeensrow(int n, int N) { if (n == N) { return true; else { for (int i = 0; i < N; i++) { queens[n] = i; if (isconsistent(queens, n)) if (solvequeensrow(n+1, N)) return true; return false; backtracking rekursivt anrop 39 kod lånad från: http://introcs.cs.princeton.edu/java/23recursion/queens.java.html

damproblemet i Java (forts.) public boolean isconsistent(int[] queens, int n) { for (int i = 0; i < n; i++) { if (queens[i] == queens[n]) return false; if (queens[i] queens[n] == n i) return false; if (queens[i] queens[n] == i n) return false; return true; public void printqueens(int[] q) { int N = queens.length; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (queens[i] == j) System.out.print("Q "); else System.out.print(" "); System.out.println(); System.out.println(); 40

damproblemet i Java (forts.) public boolean isconsistent(int[] queens, int n) { for (int i = 0; i < n; i++) { if (queens[i] == queens[n]) return false; if (queens[i] queens[n] == n i) return false; if (queens[i] queens[n] == i n) return false; return true; public void printqueens(int[] q) { int N = queens.length; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (queens[i] == j) System.out.print("Q "); else System.out.print(" "); System.out.println(); System.out.println(); samma kolumn 40

damproblemet i Java (forts.) public boolean isconsistent(int[] queens, int n) { for (int i = 0; i < n; i++) { if (queens[i] == queens[n]) return false; if (queens[i] queens[n] == n i) return false; if (queens[i] queens[n] == i n) return false; return true; public void printqueens(int[] q) { int N = queens.length; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (queens[i] == j) System.out.print("Q "); else System.out.print(" "); System.out.println(); System.out.println(); samma kolumn ena diagonalen 40

damproblemet i Java (forts.) public boolean isconsistent(int[] queens, int n) { for (int i = 0; i < n; i++) { if (queens[i] == queens[n]) return false; if (queens[i] queens[n] == n i) return false; if (queens[i] queens[n] == i n) return false; return true; public void printqueens(int[] q) { int N = queens.length; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (queens[i] == j) System.out.print("Q "); else System.out.print(" "); System.out.println(); System.out.println(); andra diagonalen samma kolumn ena diagonalen 40