tdt4120

Forelesning 1. oktober - Grådighet

Pensum

Læringsmål


1:4 Grådighet > Hva er det?

Annet perspektiv: Ser på “veien videre” heller enn “veien hit”.

Ting å identifisere

  1. Globalt optimalitetskriterium
  2. Lokalt optimalitetskriterium
  3. Konsktruksjonstrinn

Ting å vise

  1. Grådighetsegenskapen
    • Kan velge det som ser best ut her og nå uten å skyte oss i foten
  2. Optimal delstruktur
    • Kan fortsette på samme måte: Optimal løsning bygger på optimale delløsninger

Det vil si:

Grådig valg + optimal delløsning gir optimal løsning

Om vi ikke har…

  1. Grådighetsegenskapen vil et grådig valg kunne gjøre at vi ikke lenger har håp om optimalitet
  2. Optimal delstruktur vil vi kunne måtte løse ting på en helt annen måte etter første valg

  3. Formuler som opt-problem der vi tar et valg så ett delproblem gjenstår
  4. Vis at det alltid finnes en optimal løsning som tar det grådige valget
  5. Vis at optimal løsning på grådig valg

2:4 Eksempel: Ryggsekk

Input: Verdier v1…vn, vekter w1… wn og en kapasitet W.

Output: Indekser $i_1, \cdots , i_k$ og en fraksjon $0 ⩽ e ⩽ 1$ slik at $w_i1 + \cdots + w_ik-1 + e × w_ik ⩽ W$ og totalverdien $v_i1 + ⋯ + e × v_ik$ er maksimal

2:5 Eksempel: Aktivitetsutvalg

Input: Intervall $[s_1,f_1,\cdots:[s_n,f_n)$

Output: Flest mulig ikke-overlappende intervaller

function rec_act_sel(s, f, k, n)
 # S[i] start, a_i
 # f[i] slutt, a_i
 # a_k forrige
 # a_m neste
 # n antall
 m = k + 1
 while m <= n && s[m] < f[k]
  m = m + 1
 end
 if m <= n
  S = rec_act_sel(s, f, m , n)
  return union(a_m, S)
 end
 return nothing

Grådig versjon

function greedy_activity_selector(s, f)
 n = length(s)
 A = [a_1]
 k = 1
 for m = 2:n
  if s[m] >= f[k]
   push!(A, a_m) # A = union(A, a_m)
   k = m
  end
 end
 return A

Bevis ved forsprang

4:4 Eksempel: Huffman

Input: Alfabet $C = \{c,…\}$ med frekvenser $c.freq$

Output: Binær koding som minimerer forventet kodelengde $\sum_{c\;∈\;C}c.freq × length(code(c))$.

Prøver en grådig algoritme

 function huffman(C)
  #C Frekvenser
  # Q pri-kø
  n = length(C) # |C|
  Q = C
  for i = 1:n - 1
   # allocate a new node z
   x = extract_min(Q)
   y = extract_min(Q)
   z.left, z.right = x, y
   z.freq = x.freq + y.freq
   insert(Q, z)
 end
 return extract_min(Q)

Korrekthet