Problemlösning TDDD73 Funktionell och imperativ programmering i Python Föreläsning 10 Peter Dalenius Institutionen för datavetenskap 2014-10-14
Översikt Problemlösningsprocessen Algoritmer Två strategier: top-down och bottom-up Ett längre exempel som löses top-down Algoritmkomplexitet Modeller 2
Några enkla problem Vad är 217 + 23? 240 3x + 5 = 45-2x x = 8 Definiera en funktion som summerar alla tal i en lista! def sum(sequence): # some code here... 3
Konsten att lösa problem 1. Förstå problemet. 2. Ta fram en plan. 3. Genomför planen. 4. Utvärdera lösningen. George Polya (1945) How to solve it 4
1. Förstå problemet Kan du formulera om problemet med dina egna ord? Förstår du alla ord och begrepp i problemformuleringen? Vad vet vi och vad är okänt? Finns det överhuvudtaget tillräckligt med information för att lösa problemet? Kan du rita en bild eller ett diagram som hjälper dig att förstå problemet? Vad är egentligen målet? Hur vet vi när vi är klara? Har du läst hela texten? 5
2. Ta fram en plan (algoritm) Gör ett försök och testa lösningen, och upprepa flera gånger Jämför med lösningar på andra, gärna likartade, problem Lös en mindre del eller en variant av problemet först Dela upp problemet i mindre delar och lös varje del för sig Formulera om problemet och ta fram en lösning som når målet, men inte på samma sätt som problemet är formulerat 6
7 3. Genomför (implementera) planen
4. Utvärdera lösningen Kontrollera att lösningen är korrekt genom att jämföra den med målet som det uttrycks i problemet. Fundera över om lösningen kan användas för att lösa andra problem, antingen rakt av eller med mindre ändringar. Fundera över vad du har lärt dig. Vilken ny kunskap har du? Hur har din problemlösningsförmåga utvecklats? 8
Algoritmer An algorithm is an ordered set of unambiguous, executable steps, that defines a terminating process. algoritm = 9 5 +32 Multiplicera grader Celsius med 9/5 och addera 32. def f(c): return 9*c/5+32 9
Flödesdiagram för TV-kväll* START SLÅ PÅ TV PÅ KANAL 1 BRA? Ja TITTA EN STUND Nej ÖKA KANAL BRUS? Ja STÄNG AV TV Nej SLUT * Som det funkade förr i tiden. 10
Pseudokod för TV-kväll Slå på TV:n på kanal 1 Så länge det inte brusar Så länge programmet är intressant Titta en stund Byt till nästa högre kanal Slå av TV:n 11
Övergripande lösningsmodeller Top-down (Stegvis förfining) Bottom-up ( Få in en fot ) 12
Programmering enligt top-down-modellen Börja med att titta på problemet som helhet. Försök dela upp det i mindre namngivna delproblem som kan lösas oberoende av varandra. Specificera delproblemen. Vad ska funktionen ta för indata och vad ska den returnera för utdata? Delegera uppgiften att lösa delproblemen till någon annan, eller till dig själv vid en senare tidpunkt. Med väl specificerade delproblem som är oberende av varandra får man också en bra struktur på programmet. En del av programmet behöver inte känna till eller bry sig om resten (inga globala variabler, alltså). Detta brukar på engelska kallas separation of concerns. 13
Exempel Vi vill ha ett program som kan simulera n slumpvandringar med k steg. Varje steg är en längdenhet och kan gå i en av fyra riktningar: vänster, höger, uppåt, nedåt. För varje slumpvandring ska längden mellan start- och slutpunkten beräknas, och i slutet ska genomsnittet av alla längderna beräknas. Detta är programmeringsövning 13 från kapitel 9 i läroboken och vi ska lösa detta problem steg för steg enligt top-down-modellen. 14
Slumpvandring 5 4 3 2 1 (1,3) = ( ) +( ) (3,2) -2-1 -1-2 1 2 3 4 5 15
Huvudprogrammet main tries steps tries steps result result inputparameters runtrials outputresult def main(): tries, steps = inputparameters() result = runtrials(tries, steps) outputresult(result) 16
Funktioner på andra nivån main tries steps tries steps result result inputparameters runtrials outputresult prompt integer inputinteger 17
Funktioner på andra nivån def inputparameters(): print("welcome to the Random Walk Simulation Program!") print("we will simulate n random walks of k steps on the blocks of") print("a city street and output the mean distance travelled.") print("-" * 50) tries = inputinteger("enter number of tries (n): ") steps = inputinteger("enter number of steps for each try (k): ") return tries, steps 18
Funktioner på andra nivån main tries steps tries steps result result inputparameters runtrials outputresult prompt integer length distance inputinteger makerandomwalk 19
Funktioner på andra nivån def runtrials(tries, steps): total = 0.0 for i in range(tries): length = makerandomwalk(steps) total += length return total / tries 20
Funktioner på andra nivån main tries steps tries steps result result inputparameters runtrials outputresult prompt integer length distance inputinteger makerandomwalk 21
Funktioner på andra nivån def outputresult(result): print("the mean distance in this simulation:", result) 22
Funktioner på tredje nivån main tries steps tries steps result result inputparameters runtrials outputresult prompt integer length distance inputinteger makerandomwalk 23
Funktioner på tredje nivån def inputinteger(prompt): while True: str = input(prompt) if str.isnumeric() and int(str) > 0: break print("please enter a positive integer!") return int(str) 24
Funktioner på tredje nivån main tries steps tries steps result result inputparameters runtrials outputresult prompt integer length distance inputinteger makerandomwalk 25
Funktioner på tredje nivån from random import randint import math def makerandomwalk(steps): x, y = 0, 0 delta = ((1, 0), (-1, 0), (0, 1), (0, -1)) for i in range(steps): direction = randint(0, 3) x += delta[direction][0] y += delta[direction][1] return math.sqrt(x * x + y * y) 26
Exempel på körning C:\python> python randomwalk.py Welcome to the Random Walk Simulation Program! We will simulate n random walks of k steps on the blocks of a city street and output the mean distance travelled. -------------------------------------------------- Enter number of tries (n): 100 Enter number of steps for each try (k): 15 The mean distance in this simulation: 3.142920319334164 27
Samma problem enligt bottom-up-modellen Börja med att konstruera en funktion som kan göra någonting som verkar ha med problemet att göra. Utforma enhetstester och testa (och korrigera) funktionen tills den funkar. Börja med det som verkar lättast, svårast, viktigast eller liknande. Bygg på med ytterligare funktioner, som också enhetstestas ordentligt, tills programmet löser hela problemet. 28
Algoritmkomplexitet Vi vill gärna konstruera en algoritm som är så effektiv som möjligt (går snabbt och använder lite minne). Vi kan naturligtvis testa detta med olika verktyg, men vi kan också teoretiskt beräkna algoritmens komplexitet. Många gånger handlar det om att det någonstans i algoritmen finns en kostsam operation som man vill göra så få gånger som möjligt. Vi ska analysera ett sådant exempel. 29
Algoritm för att sy ett lapptäcke Vi ska sy ett lapptäcke med 8 x 8 rutor som består av fyra olika färger arrangerade i mönstret till vänster. Hur kan vi göra det så rationellt som möjligt? Vad är det för kostsam grundoperation som vi vill minimera? Hur många gånger behöver vi utföra operationen för att skapa ett lapptäcke med n x n rutor? 30
Algoritm 1... 1. Sy ihop kvadraterna i en rad med varandra, så att vi får åtta rader. 2. Sy ihop de färdiga raderna med varandra. 31
Algoritm 2 klipp... 1. Konstruera fyra kvadrater av fyra remsor. 2. Skär isär dem till remsor på andra ledden. 3. Sy ihop remsorna. 32
Algoritm 3 klipp 8 remsor... 1. Sy ihop 8 remsor som är 8 kvadrater breda. 2. Sy ihop remsorna till ett rör. 3. Skär röret 7 gånger. 4. Sprätta en söm i varje cirkel, men på olika ställen. 5. Sy ihop de 8 olika remsorna. 33
Tidskomplexitet för lapptäcksalgoritmer 12000 10000 antal sömmar 8000 6000 4000 algoritm 1: n 2 2000 0 algoritm 3: n 0 10 20 30 40 50 60 70 80 90 100 antal lappar per sida 34
problemlösning formalisering implementation 35
Klassdiagram Being inventory strength inclination talk() fight() namn egenskaper beteenden arvsrelation Player experience tribe follow() Monster intelligence Pet pet() 36
ER-diagram attribute Namn Pnr relationship Namn Förkortn ANSTÄLLD ARBETAR_PÅ INSTITUTION entity EXAMINATOR ANSV_FÖR KURS Namn Kurskod 37
Tillståndsdiagram retur/1 retur/2 retur/3 mynt/-- mynt/-- mynt/-- beställ/kaffe tillstånd indata/utdata 38
Sekvensdiagram objekt s : Caller : Switch r : Caller liftreceiver() senddialtone() dialdigit(d) create c : Conversation tid ring() liftreceiver() connect(s) connect(s) meddelande 39
Exempel Problemet med bonden, vargen, lammet och kålhuvudena Alla ska över till andra sidan floden. Endast en sak får plats i båten, förutom bonden. Lammet äter kålhuvudena och vargen äter lammet, om de lämnas ensamma. 40
Utgångsläge Fyra saker man kan göra? 41
BVLK BV LK BL VK BK VL B VLK L BVK VL BK BVL K BLK V LK BV V BLK K BVL BVK L VK BL BVLK 42
Sammanfattning Det finns ingen enkel metod som löser alla problem, men det finns många tips på strategier som kan funka i många fall. Två övergripande strategier är top-down och bottom-up. Algoritmer är generella beskrivningar av hur program kan funka. De kan uttryckas på flera olika sätt, t.ex. med pseudokod eller flödesdiagram. Redan innan vi har implementerat algoritmerna kan vi analysera deras komplexitet. Som programutvecklare skriver vi inte bara kod. Vi gör ofta modeller för att bättre förstå struktur och beteende hos program. 43
Bildkällor: http://commons.wikimedia.org/wiki/file:djungarian_hamster_pearl_white_run_wheel.jpg http://commons.wikimedia.org/wiki/file:nordic_walking_on_treadmill.jpg http://commons.wikimedia.org/wiki/file:mining_coal_.jpg http://commons.wikimedia.org/wiki/file:%27the_mighty_orinoco%27_by_george_roux_36.jpg www.liu.se