Optimering Kruskal s Prim-Jarník s 0.7 1.3 0.5 0.3 2.1 0.7 1.3 0.5 0.3 2.1 Viktad graf raf där varje kant har en vikt Vikterna kan motsvara Kostnad Avstånd Tidsåtgång ur hittar man kortaste vägen från A till F? Ingen känd har bättre asymptotisk komplexitet än de som beräknar kortaste väg från A till alla
Kortaste avståndet i en viktad graf 1. Avståndsmarkera alla noder med + 2. Sätt startnodens avstånd till noll 3. Upprepa lika många gånger som antalet noder: För alla kanter: Uppdatera (vid behov) avståndet vid kantens slut def bellmanford ( g, s t a r t, g o a l ) : f o r x i n g. nodes : d [ x ] = f l o a t ( i n f ) d [ s t a r t ] = 0 f o r x i n g. nodes : f o r e i n g. edges : a = d [ e. b e g i n ] + e.w i f a < d [ e. end ] : d [ e. end ] = a return d [ g o a l ] Kortaste avståndet när alla vikter är positiva 1. Avståndsmarkera alla noder med + 2. Sätt startnodens avstånd till noll 3. Upprepa: Tag närmaste ännu ej behandlade nod Uppdatera (vid behov) avståndet till nodens grannar def d i j k s t r a ( g, s t a r t, g o a l ) : f o r x i n g. nodes : d [ x ] = f l o a t ( i n f ) d [ s t a r t ] = 0 q = s e t ( g. nodes ) while not q. isempty : u = f i n d S m a l l e s t ( q, d ) q. remove ( u ) f o r e i n u. outedges : a = d [ u ] + e.w i f a < d [ e. end ] : d [ e. end ] = a return d [ g o a l ]
Kruskal s Prim-Jarník s 1.3 0.5 0.3 0.7 2.1 0.7 Kruskal s Prim-Jarník s 1.3 0.5 0.3 2.1 Spanning Tree ivet en oriktad graf, ett spanning tree är en delgraf som utgör ett träd men fortfarande knyter ihop alla noder. Minimum Spanning Tree Det spanning tree som har minst total vikt. Kruskal s Prim-Jarník s Kruskal s Prim-Jarník s Kruskal s Prim-Jarník s Minimum Spanning Tree enligt Kruskal Agera som en snål kommunalpolitiker 1. Bygg billigaste vägen som inte är onödig 2. Upprepa detta tills inga fler vägar behövs Minimum Spanning Tree enligt Prim och Jarník Agera som en egocentrisk kommunalpolitiker 1. Utgå från godtycklig startnod 2. Bygg den billigaste vägen som gör att man når en ny plats 3. Upprepa detta tills alla platser kan nås
Rekursivt formulerat optimeringsproblem Samma delproblem dyker upp flera gånger Numrera dellösningarna Lös problemet bakifrån ur olika är två strängar? Edit Distance Antal ändringar som krävs för att transformera den ena strängen till den andra Tillåtna ändringar Byt ut ett tecken Tag bort ett tecken Sätt in ett tecken Exempel: Avståndet mellan mandelmassa och andelshus mandelmassa andelmassa andelmass andelmaus andelmhus andelshus Avståndet = 5 Är detta det kortaste sättet? Rekursivt ansats Utgå från att vi vet avståndet mellan alla kortare stängar Avståndet d mellan xblabla och y bläblä är det minsta av d( blabla, bläblä ) om x = y d( blabla, bläblä ) + 1 om x y d( xblabla, bläblä ) + 1 d( blabla, ybläblä ) + 1 Basfall En sträng är tom: d = andra strängens längd
def d i s t ( s1, s2 ) : i f s1 == : d = l e n ( s2 ) e l i f s2 == : d = l e n ( s1 ) e l s e : d = min ( d i s t ( s1 [ 1 : ], s2 [ 1 : ] ) + (1 i f s1 [ 0 ]!= s2 [ 0 ] e l s e 0 ), d i s t ( s1, s2 [ 1 : ] ) + 1, d i s t ( s1 [ 1 : ], s2 ) + 1) return d Tre grenar i rekursionen Arbetet växer med faktorn 3 för varje extra rekursionssteg O(3 n ) Samma delproblem dyker upp flera gånger Idé: spara redan uträknade dellösningar def d i s t ( s1, s2, cache ) : i f ( s1, s2 ) not i n cache : i f s1 == : d = l e n ( s2 ) e l i f s2 == : d = l e n ( s1 ) e l s e : d = min ( d i s t ( s1 [ 1 : ], s2 [ 1 : ], cache ) + (1 i f s1 [ 0 ]!= s2 [ 0 ] e l s e 0 ), d i s t ( s1, s2 [ 1 : ], cache ) + 1, d i s t ( s1 [ 1 : ], s2, cache ) + 1) cache [ ( s1, s2 ) ] = d ur ska man placera radbytena i ett stycke? Optimeringsproblem Minimera i (L i ) 2 L i är längden för rad i är den önskade radlängden return cache [ ( s1, s2 ) ] >> d i s t ( mandelmassa, a n d e l s h u s, {}) 5
Rekursiv ansats Utgå från att vi vet bästa sättet att bryta raderna för alla kortare stycken å igenom alla möjliga platser för första radbytet Lägg samman kostnaden för första raden och resten av stycket Returnera den minsta totala kostnaden def c o s t ( p ) : b e s t = f l o a t ( i n f ) f o r bp i n range ( 1, l e n ( p )+1): t h i s = l i n e C o s t ( p [ : bp ] ) r e s t = c o s t ( p [ bp : ] ) i f t h i s + r e s t < b e s t : b e s t = t h i s + r e s t progammering Numrera alla möjliga platser för radbrytning Beräkna platsernas kostnad från slutet return b e s t