Introduktion till algoritmer - Lektion 1 Matematikgymnasiet, Läsåret 2014-2015. Lektion 1



Relevanta dokument
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

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Algoritmer, datastrukturer och komplexitet

Föreläsning 11. Giriga algoritmer

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

C++ Slumptalsfunktioner + switch-satsen

Ekvationer och system av ekvationer

POLYNOM OCH POLYNOMEKVATIONER

Övningshäfte 3: Polynom och polynomekvationer

Givet två naturliga tal a och b, som inte båda två är 0, hur räknar man ut största gemensamma delaren av a och b?

Föreläsning 5. Rekursion

Problemlösning. Veckodagsproblemet Gissa talet Siffersumman

Introduktion till algoritmer - L0 - Grunder i C++ Matematikgymnasiet, Läsåret L0 - Grunder i C++

Föreläsning 11. Giriga algoritmer

a = a a a a a a ± ± ± ±500

MA2047 Algebra och diskret matematik

Inledning. Vad är ett datorprogram, egentligen? Olika språk. Problemlösning och algoritmer. 1DV433 Strukturerad programmering med C Mats Loock

Matematisk kommunikation för Π Problemsamling

Matematisk kommunikation för Π Problemsamling

Repetera snabbt vad du lärde dig förra veckan. Du är nu redo att kasta dig in i nästa fas, teorin om villkor.

OBS! All teori i detta och följande dokument kompletteras med genomgångar på lektionerna. Så det är viktigt att närvara och göra egna anteckningar.

Hela tal LCB 1999/2000

Gamla tentemensuppgifter

TDIU01 - Programmering i C++, grundkurs

TATM79: Föreläsning 1 Notation, ekvationer, polynom och olikheter

Problemlösning. Veckodagsproblemet Gissa talet Siffersumman

TDIU01 - Programmering i C++, grundkurs

Lite om räkning med rationella uttryck, 23/10

Inledande programmering med C# (1DV402) Summera med while"-satsen

29 Det enda heltalet n som satisfierar båda dessa villkor är n = 55. För detta värde på n får vi x = 5, y = 5.

TDDI16: Datastrukturer och algoritmer

Uppsala Universitet Matematiska Institutionen Thomas Erlandsson

Bakgrund och motivation. Definition av algoritmer Beskrivningssätt Algoritmanalys. Algoritmer. Lars Larsson VT Lars Larsson Algoritmer 1

Föreläsning 5 Innehåll

Kvalificeringstävling den 30 september 2008

Högstadiets matematiktävling 2016/17 Finaltävling 21 januari 2017 Lösningsförslag

5B1146 med Matlab. Laborationsr. Laborationsgrupp: Sebastian Johnson Erik Lundberg, Ann-Sofi Åhn ( endst tal1-3

Teori :: Diofantiska ekvationer v1.2

TATM79: Föreläsning 1 Notation, ekvationer, polynom och summor

UPPGIFT 1 V75 FIGUR 1.

Läsanvisning till Discrete matematics av Norman Biggs - 5B1118 Diskret matematik

Sidor i boken f(x) = a x 2 +b x+c

Några satser ur talteorin

International Olympiad in Informatics July 2011, Pattaya City, Thailand Tävlingsuppgifter Dag 2 Svenska 1.3. Papegojor

, S(6, 2). = = = =

Programmeringsolympiaden 2011 Kvalificering

Material till kursen SF1679, Diskret matematik: Lite om kedjebråk. 0. Inledning

kl Tentaupplägg

6 Derivata och grafer

Explorativ övning 4 ÄNDLIGT OCH OÄNDLIGT. Övning A

TDIU01 - Programmering i C++, grundkurs

Delbarhet och primtal

Finaltävling i Uppsala den 24 november 2018

Laboration 1. "kompilera"-ikonen "exekvera"-ikonen

Grundläggande programmering med C# 7,5 högskolepoäng

varandra. Vi börjar med att behandla en linjes ekvation med hjälp av figur 7 och dess bildtext.

TDIU01 (725G67) - Programmering i C++, grundkurs

Polynomekvationer (Algebraiska ekvationer)

Bisektionsalgoritmen. Kapitel Kvadratroten ur 2

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 19 oktober 2016, kl 14 18

Föreläsning 9: Talteori

TATA42: Föreläsning 9 Linjära differentialekvationer av ännu högre ordning

Bakgrund. Bakgrund. Bakgrund. Håkan Jonsson Institutionen för systemteknik Luleå tekniska universitet Luleå, Sverige

Induktion, mängder och bevis för Introduktionskursen på I

Problem: BOW Bowling. Regler för Bowling. swedish. BOI 2015, dag 1. Tillgängligt minne: 256 MB

Algoritmer, datastrukturer och komplexitet

Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.

Datorprogram, algoritmer och Turing-maskiner

Lösandet av ekvationer utgör ett centralt område inom matematiken, kanske främst den tillämpade.

1. Inledning, som visar att man inte skall tro på allt man ser. Betrakta denna följd av tal, där varje tal är dubbelt så stort som närmast föregående

18 juni 2007, 240 minuter Inga hjälpmedel, förutom skrivmateriel. Betygsgränser: 15p. för Godkänd, 24p. för Väl Godkänd (av maximalt 36p.

Läsanvisning till Discrete matematics av Norman Biggs - 5B1118 Diskret matematik

x2 6x x2 6x + 14 x (x2 2x + 4)

Diskret matematik, lektion 2

1. Ange samtliga uppsättningar av heltal x, y, z som uppfyller båda ekvationerna. x + 2y + 24z = 13 och x 11y + 17z = 8.

Linjära ekvationer med tillämpningar

Tentamen: Programutveckling ht 2015

Sats 2.1 (Kinesiska restsatsen) Låt n och m vara relativt prima heltal samt a och b två godtyckliga heltal. Då har ekvationssystemet

Diagnostiskt Prov. Antaganden Om förutsättningar saknas I en uppgift skall rimliga antaganden göras och nedtecknas.

8-4 Ekvationer. Namn:..

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

Lösningar och kommentarer till uppgifter i 3.1

Sidor i boken , , 3, 5, 7, 11,13,17 19, 23. Ett andragradspolynom Ett tiogradspolynom Ett tredjegradspolynom

Sortering. Om du följt dessa steg korrekt så ska böckerna nu vara sorterade.

Tentamen i Objektorienterad Programmering 5p, Au, D, Fri, Pr,

Algoritmer, datastrukturer och komplexitet

Manipulationer av algebraiska uttryck

EXTRA UPPGIFTER I C++ PROGRAMMERING-A

n (log n) Division Analysera skolboksalgoritmen för division (trappdivision). Använd bitkostnad.

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

Laboration 1 Introduktion till Visual Basic 6.0

MATEMATIK GU. LLMA60 MATEMATIK FÖR LÄRARE, GYMNASIET Analys, ht Block 5, översikt

CS - Computer science. Datateknik Informationsbehandling Datalogi Datavetenskap (ÅA 2008)

kl Tentaupplägg

Inlämningsuppgift, LMN100

729G04 - Diskret matematik. Lektion 4

Rekursion och induktion för algoritmkonstruktion

Linjära differentialekvationer av andra ordningen

Transkript:

Kattis Lektion 1 I kursen används onlinedomaren Kattis (från http://kattis.com) för att automatiskt rätta programmeringsproblem. För att få ett konto på Kattis anmäler du dig på Programmeringsolympiadens hemsida, http://progolymp.se/elev/anmal. Den instans av Kattis vi kommer använda hittar du på https://po.kattis.com. Där finns också dokumentation om hur du skickar in lösningar till problem. Du ska också anmäla dig till kursen Algoritmer 2014-2015 (Matematikgymnasiet) under Kurser i menyn. En Kattisövning är en övningsuppgift som du kan skicka in din lösning till på Kattis. En Kattisinlämning är en inlämingsuppgift som du får betygspoäng på beroende på hur mycket poäng din lösning fick på Kattis (en lösning kan ge olika mycket poäng beroende på hur bra den var). Varje Kattisproblem har ett problem-id. För att se problemet kan du antingen söka efter det eller skriva in https://po.kattis.com/problems/problemid. I Kattis får ska ditt program läsa all indata från standard in (scanf/cin/system.in/stdin/etc) och skriva utdatan till standard out (printf/cout/system.out/stdout). På din egen dator kommer detta vanligtvis vara samma sak som att läsa in och skriva ut data till terminalen. Algoritmer och problem En algoritm är en metod som tar emot någon mängd värden (det som kallas för indata) för att producera nya värden, den så kallade utdatan. Oftast använder vi algoritmer för att lösa olika sorters problem som uppkommer inom datavetenskapen. indata algoritm utdata Figur 1: indata kommer in, utdata kommer ut Ett problem kan exempelvis vara att beräkna den största gemensamma delaren av två heltal A och B, som betecknas gcd(a, B) (greatest common divisor på engelska). Ett tal N är ett delare till ett tal A om kvoten A N är lika med ett heltal, dvs A = N x för något heltal x. Vi beskriver problemet formellt: Exempel 1. Största gemensamma delaren Indata: två positiva heltal B A > 0. Utdata: den största gemensamma delaren av A och B, dvs gcd(a, B). Lösning För att en algoritm ska lösa ett problemet behöver den uppfylla två villkor: 1. Algoritmen får inte köra oändligt länge (dvs den måste terminera) 2. När algoritmen terminerar måste den ha beräknat den korrekta utdatan Till problemet Största gemensamma delaren finns en tämligen enkel algoritm som redan den gamle greken Euklides kom på, den så kallade Euklides algoritm.

Euklides algoritm tar två positiva heltal A och B. Sedan, ända tills ett av talen blir 0, subtraherar man det mindre av talen från det större. När ett av talen blir 0 kommer det andra talet vara gcd(a, B). Vi kan specifiera algoritmen mer exakt med hjälp av psuedokod: Algoritm 1 Euklides algoritm Antagande: B A 0 1: Funktion Gcd(heltal A, heltal B) 2: så länge A > 0 3: B B A Subtrahera det mindre talet från det större 4: om A är större än B 5: byt plats på A och B Vi vill att B A alltid ska vara sant 6: returnera B Det är fortfarande långt ifrån uppenbart varför algoritmen faktiskt fungerar, eller om den ens terminerar. Vi kan prova att exekvera algoritmen för oss själva, t.ex. med talen 15 och 6. B = 15, A = 6 B = 9, A = 6 B = 3, A = 6 B = 6, A = 3 B = 3, A = 3 B = 0, A = 3 B = 3, A = 0 gcd(15, 6) = 3 (start) (byt plats) (byt plats) (terminera) Algoritmen fungerade onekligen för vårt lilla exempel - 3 är det största heltal som delar både 15 och 6. Eftersom vi är matematiker nöjer vi oss såklart inte med detta, men kanske har vi nu fått ett hum om varför algoritmen är korrekt: 1. Betrakta summan A + B. Efter en körning av loopen kommer summan minska med A. Men A > 0, eftersom loopen inte ännu avslutats. Alltså kommer summan A + B bli strikt mindre. Men inget av talen är någonsin negativt, så A + B 0. Summan kan alltså inte minska i all oändlighet, och för eller senare måste därför A vara 0 så att loopen avbryts. 2. Vi noterar först att gcd(b, 0) = B. Vidare måste vi inse att ett tal D är en gemensam delare till A och B om och endast om D är en gemensam delare till talen A och B A. Detta innebär rent konkret att efter varje steg i vår algoritm kommer de gemensamma delarna till talen vara oförändrade. I synnerhet kommer den största gemensamma delaren vara densamma. Vi vet att variabeln A förr eller senare kommer bli 0 i vår algoritm måste, vi vet att gcd(b, 0) = B, samt att vi har samma gemensamma delare i början av algoritmen som i slutet. Vår slutledningsförmåga konstaterar då att talens största gemensamma delaren helt enkelt är variabeln B:s slutvärde. Vi har alltså konstaterat dels att algoritmen terminerar, men också att den gör så med rätt svar - algoritmen är alltså korrekt. Den uppmärksamma läsaren kanske ifrågasatte att vi betraktade problemet som löst utan att ta någon som helst hänsyn till hur lång tid algoritmen tar innan den terimerar. Vår algoritm kanske är så ineffektiv att det tar flera dagar att beräkna svaret när A och B är stora. Under nästa lektion kommer vi behandla de verktyg man använder för att beskriva hur effektiv en algoritm är. Övning 1. Formulera problemet Polynomrötter, som går ut på att finna alla reella nollställen till ett polynom.

Övning 2. Bevisa att D är en gemensam delare till A och B om och endast om D är en gemensam delare till talen A och B A. Övning 3. Bevisa att Euklides algoritm terminerar efter högst A + B iterationer av loopen. Kattisövning (ID: gcd). Implementera Euklides algoritm. Implementationsproblem I den enklaste sortens problem är problemlydelsen så pass specifik att det svåra inte är att komma på lösningen, utan att faktiskt implementera den. Ofta handlar implementationsproblem om att simulera något tidsförlopp. Exempel 2. Receptet (Programmeringsolympiadens skolkval 2011) Du har bestämt dig för att laga mat. För att laga maten behöver du N ingredienser. För varje ingrediens vet du hur mycket du redan har hemma, hur mycket du behöver totalt samt kostnaden för ingrediensen om du måste köpa den. Du skall alltså köpa den mängd av varje ingrediens som du saknar. Uppgiften är att beräkna kostnaden för att laga maten. Kattisövning (ID: receptet). Lös Receptet. Problemet är inte särskilt svårt: för varje ingrediens beräknar hur mycket av varje ingrediens vi måste köpa. Sedan multiplicerar vi detta med priset för ingrediensen, Till slut summerar vi kostnaden för varje ingrediens. Bara för att lösningen till ett implementationsproblem är uppenbar behöver den absolut inte vara enkel! Att implementera en algoritm kan vara extremt invecklat och öppnar upp för många buggar i ditt program. Bruteforce Många problem går ut på att prova en stor mängd möjligheter i lösningen. Om uppgiften är att man ska skriva ut antalet heltalslösningar till en ekvation kan det tänkta tillvägagångssättet helt enkelt vara att prova alla möjliga värden på ekvationens variabler och se om dessa uppfyller ekvationen. Detta kallas för bruteforce. Man använder här att en dator är väldigt snabb, så att man behöver tänka mindre i själva lösningen. Ibland är användningen av bruteforce inte så uppenbar. Det kan t.ex. vara en del i ett problem. Ekvationen vi letar heltalslösningar till kanske blir mycket lättare att lösa så länge vi känner till en av ekvationens variabler för att de övriga faller ut på ett naturligt sätt. Exempel 3. där Finn alla heltal 0 < x < 10 9 som uppfyller x = a s(x) b + c a 10 000 1 b 5 c 10 000 är givna heltal, och s(x) är siffersumman av talet x. För att lösa ekvationen enklast använder man bruteforce. Det vi gör bruteforce över är inte x, som man skulle kunna tro. x kan nämligen anta alldeles för många värden för att programmet ska bli snabbt nog (en dator klarar av ungefär 10 8 små operatoner per sekund). Istället inser vi att ett tal med högst 9 siffror inte kan ha en större siffersumma än 81, nämligen då alla siffror är 9. Det vi

ska bruteforca över är alltså siffersumman s(x). Givet en viss siffersumma är x entydigt bestämt eftersom vi kan beräkna högerledet. Då återstår bara att kontrollera om x faktiskt har samma siffersumma som vi antog att talet hade. Att lösa ett problem med ren bruteforce, det vill säga utan att kombinera med någon mer avancerad teknik eller ytterligare insikter (som ovan, där det svåra var att komma fram till rätt variabel) brukar oftast bara vara möjligt på enklare problem. Generellt blir programmet alldeles för långsamt.

Lösningar till övningarna Övning 1: Indata: Koefficienterna a i till ett polynom p(x) = a n x n + a n 1 x n 1 +... + a 0. Utdata: Alla reella tal x sådana att p(x) = 0. Övning 2: Om D är en delare i A och B så kan vi skriva A = DN och B = DM för några heltal N och M. B A = D(M N), vilket såklart är delbart med D. Åt andra hållet, om D är en delare i B och B A kan vi skriva B = DN och B A = DM. Detta ger A = B DM = DN DM = D(N M), vilket även det är delbart med D. Övning 3: Varje iteration av loopen minskar summan A + B. Detta kan bara hända A + B gånger, eftersom summan är icke-negativ. Händer det fler gånger måste minst ett av talen bli 0, och då kommer loopen ha terminerat. Kattisövning gcd: 1 #include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 6 int gcd(int A, int B){ 7 while(a > 0){ 8 B = B - A; 9 if(a > B){ 10 swap(a, B); // swap finns i <algorithm> 11 } 12 } 13 return B; 14 } 15 16 int main(){ 17 int A, B; 18 cin >> A >> B; 19 cout << gcd(a, B) << endl; 20 }

Inlämningsproblem Kattisinlämning 1 (ID: bijektion). 1/0/0 Kattisinlämning 2 (ID: fullsatt). 2/0/0 Kattisinlämning 3 (ID: kalkylator). 0/1/0 Kattisinlämning 4 (ID: schackmatt). 0/0/1 Teoriuppgift 1. 2/1/0 a) Formulera Sorteringsproblemet som går ut på att sortera en lista av heltal. b) Skriv en lösning till Sorteringsproblemet i pseudokod. c) Bevisa att din lösning är korrekt och terminerar. d) Nämn några tillämpningar av Sorteringsproblemet. Teoriuppgift 2. 1/1/0 När vi vill bevisa att en algoritm inte är korrekt försöker vi hitta ett motexempel till algoritmen. Det räcker med ett enda fall där algoritmen inte fungerar för att den ska vara felaktig, oavsett hur många exempel den faktiskt klarar. Följande problem (Biblioteket) kommer från Programmeringsolympiadens onlinekval 2009, i lite modifierad form: Du jobbar på ett bibliotek och vill ställa tillbaka ett antal böcker i hyllorna. Hyllorna är placerade längs x-axeln. Givet i vilken hylla varje bok ska stå (en x-koordinat a i mellan 0 och 1000) och det maximala antalet böcker som du kan bära samtidigt, bestäm den kortaste sträckan du måste gå för att ställa tillbaka alla böcker. Du och böckerna som ska ställas tillbaka befinner sig ursprungligen på position 0. Du behöver inte gå tillbaka efter att ha återställt den sista boken. Det finns total n böcker, och du kan bära k böcker samtidigt. Mårten föreslår följande lösning: Börja med att lägga tillbaka de k böcker som ska placeras närmast utgångspunkten. Sedan tar du de nästa k närmsta böckerna, och fortsätter så tills du placerat ut alla böcker. Visa att Mårtens lösning är felaktig genom att konstruera ett motexempel.