vervolg C 1 Onderwerpen voor vandaag Backtracking Permutaties

  • Slides: 14
Download presentation
vervolg C 1 Onderwerpen voor vandaag • Backtracking: – Permutaties – Koninginnen • Opgave:

vervolg C 1 Onderwerpen voor vandaag • Backtracking: – Permutaties – Koninginnen • Opgave: frankeren Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 2 Backtracking Techniek voor het brute-force zoeken van oplossingen. 1. Begin met

vervolg C 2 Backtracking Techniek voor het brute-force zoeken van oplossingen. 1. Begin met een ‘lege’ oplossing 2. Doe een stap, hopelijk in de goede richting 3. Als je een oplossing gevonden hebt: mooi zo 4. Als het duidelijk is dat je fout zit dan doe je de laatste stap weer terug (daar komt de naam backtracking vandaan) 5. Als je niet fout zit en nog niet aan een complete oplossing bent: zie 2. Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 3 permutaties Probleem: Genereer alle mogelijke ordeningen (rijtjes) van de cijfers 0.

vervolg C 3 permutaties Probleem: Genereer alle mogelijke ordeningen (rijtjes) van de cijfers 0. . 9. Ieder cijfer mag maar 1 keer voorkomen. Oplossing: genereer alle rijtjes van 10 cijfers, maak je geen zorgen over duplicaten. Filter alleen wel de rijtjes eruit die duplicaten bevatten. Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 4 Permutaties 1 for( a[0] =0; a[0] <10; a[0]++ ) for( a[1]

vervolg C 4 Permutaties 1 for( a[0] =0; a[0] <10; a[0]++ ) for( a[1] =0; a[1] <10; a[1]++ ). . . for( a[9] = 0; a[9] <10; a[9]++ ) if( ! duplicates( a ) ) solution( a ); Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 5 Permutaties 2 void permutate( int a[10]; int i ){ if( i

vervolg C 5 Permutaties 2 void permutate( int a[10]; int i ){ if( i == 10 ){ if( ! duplicates( a )) solution( a ) return; } for( j = 0; j < 10; i++ ){ a[ i ] = j; permutate( a, i + 1 ); } } Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 6 Permutaties 3 void permutate( int a[10]; int i ){ if( duplicates(

vervolg C 6 Permutaties 3 void permutate( int a[10]; int i ){ if( duplicates( a )) return; if( i == 10 ){ solution( a ); return; } for( j = 0; j < 10; i++ ){ a[ i ] = j; permutate( a, i + 1 ); a[ i ] = -1; } } Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 7 Het koninginnen probleem Probleem: Plaats 8 koninginnen op een schaakbord, zodanig

vervolg C 7 Het koninginnen probleem Probleem: Plaats 8 koninginnen op een schaakbord, zodanig dat zij elkaar niet kunnen slaan. Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 8 Het koninginnen probleem Oplossing: Gegeven een schaakbord met N (<8) koninginnen

vervolg C 8 Het koninginnen probleem Oplossing: Gegeven een schaakbord met N (<8) koninginnen die elkaar niet kunnen slaan. Probeer voor ieder vrij veld of daar een koningin geplaatst kan worden zonder dat zij een van de anderen kan slaan. Voor iedere plek waar dat kan heb je een oplossing met N + 1 koninginnen. Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C typedef int board[8][8]; void queens( board b, int n ){ int i,

vervolg C typedef int board[8][8]; void queens( board b, int n ){ int i, j; if( n == 8 ){ print_board( b ); return; } for( i = 0; i < 8; i++ ) for( j = 0; j < 8; j++ ){ if( ! board[ i ][ j ] ){ board[ i ][ j ] = 1; if( valid_board( b, i, j )){ queens( b, n + 1 ); } board[ i ][ j ] = 0; } } } Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology 9

vervolg C 10 Opdracht ”frankeren” Ik heb postzegels van 44, 72 en 89 cent.

vervolg C 10 Opdracht ”frankeren” Ik heb postzegels van 44, 72 en 89 cent. Dat waren de standaard tarieven voor Nederland, Europa en Wereldwijd. Helaas zijn de tarieven voor buiten Nederland per 1 -1 -2008 iets verhoogd. Ik wil frankeren volgens de nieuwe tarieven, maar wel met de postzegels die ik in huis heb, en ik wil natuurlijk zo min mogelijk verspillen. Welke zegels moet ik plakken voor de volgende tarieven? (europa): 0. 75, 1. 50, 2. 25, 3. 00, 6. 00 (wereld): 0. 92, 1. 84, 2. 76, 5. 52, 10. 12 Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 11 Opdracht ”frankeren” #define N_ZEGELS 3 int zegels[ 3 ] = {

vervolg C 11 Opdracht ”frankeren” #define N_ZEGELS 3 int zegels[ 3 ] = { 44, 72, 89 }; . . . int main(int argc, char *argv[]){ frankeer( frankeer( frankeer( 75 ); 150 ); 225 ); 300 ); 600 ); 92 ); 184 ); 276 ); 552 ); 1012 ); system("PAUSE"); return 0; } Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 12 Opdracht ”frankeren” void frankeer( int porto ){ int i, beste; int

vervolg C 12 Opdracht ”frankeren” void frankeer( int porto ){ int i, beste; int lijstje[ N_ZEGELS ]; int beste_lijstje[ N_ZEGELS ]; for( i = 0; i < N_ZEGELS; i++ ){ lijstje[ i ] = 0; } beste = 999999; voeg_toe( porto, 0, -1, lijstje, &beste, beste_lijstje ); printf( "%-4 d kost %-4 d : ", porto, beste ); for( i = 0; i < N_ZEGELS; i++ ){ printf( "%2 d keer %2 d, ", beste_lijstje[ i ], zegels[ i ] ); } printf( "n" ); } Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 13 Opdracht ”frankeren” Maak een recursieve functie: void voeg_toe( int porto, int

vervolg C 13 Opdracht ”frankeren” Maak een recursieve functie: void voeg_toe( int porto, int totaal, int zegel, int lijstje[], int *beste, int beste_lijstje[] ); Porto is het bedrag dat geplakt moet worden, totaal het bedrag dat not nu toe geplakt is. Zegel is de index van de zegel die er bij geplakt gaat worden. Lijstje is voor iedere zegel het aantal dat tot nu toe geplakt is. Beste is het totaal bedrag van de tot nu toe beste keuze aan zegels. Beste_lijstje is het lijstje dat hoort bij beste. De functie moet zegel (mits niet -1) toevoegen aan lijstje en totaal. Als het totaal nu gelijk aan of hoger dan porto is dan hebben we een oplossing. Als het totaal ook nog eens kleiner is dan *beste dan hebben we een betere oplossing dan we tot nu toe hadden, en moeten we dus die (*beste en beste_lijstje) oplossing vervangen door de huidige. Als het totaal kleiner is dan porto dan roepen we de functie zelf weer aan voor alle mogelijke waarden (indexen) van zegel. Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology

vervolg C 14 Opdracht ”frankeren” Let op !! - Waarom is beste een pointer

vervolg C 14 Opdracht ”frankeren” Let op !! - Waarom is beste een pointer - Waarom zijn porto en totaal geen pointers? - Waarom zijn lijstje en beste_lijstje geen pointers? In de vorige sheet is het eigenlijke backtracken niet vermeld. - In welke twee parameters bouw je de oplossing op? - Wat moet je doen om te ‘backtracken’? Hogeschool van Utrecht / Institute for Computer, Communication and Media Technology