130 likes | 243 Views
Combinatorial Functions. Recursion for problem solving. Enumerating Initial segments ( prefixes ). inits [ 1 ,2,3] = [ [] ,[ 1 ],[ 1 ,2],[ 1 ,2,3]] inits [2,3] = [ [], [2], [2,3] ] fun inits [] = [[]] | inits (x::xs) = []:: (map (fn ys => x::ys)
E N D
Combinatorial Functions Recursion for problem solving L14Comb
Enumerating Initial segments (prefixes) inits [1,2,3] = [[],[1],[1,2],[1,2,3]] inits [2,3] = [ [], [2], [2,3] ] fun inits [] = [[]] | inits (x::xs) = []:: (map (fn ys => x::ys) (inits xs) ); fun inits [] = [[]] | inits xs = (inits (init xs))@[xs]; L14Comb
Enumerating Subsequences subseq [2,3] = [[],[2],[3],[2,3]]; subseq [1,2,3] = [[], [1],[2],[3], [1,2],[1,3],[2,3],[1,2,3] ]; fun subseq [] = [[]] | subseq (x::xs) = letval ss = subseq xs in ss@(map (fn ys => x::ys) ss) end; L14Comb
Enumerating permutations perms [2] = [[2]] perms [1,2] = [[1,2], [2,1]] perms [0,1,2] = [[0,1,2],[1,0,2],[1,2,0], [0,2,1],[2,0,1],[2,1,0]] fun interleave x [] = [[x]] | interleave x (y::ys) = (x::y::ys) :: (map(fn xs=>y::xs)(interleave x ys)); fun perms [] = [[]] | perms (x::xs) = foldr (op @) [] (map (interleave x) (perms xs)) ; L14Comb
List partitions • The list of non-empty lists [L1,L2,…,Lm] forms a list-partition of a list Liff concat [L1,L2,…,Lm] = L [1,2] -> [[[1,2]], [[1],[2]]] [0,1,2] -> [ [[0,1,2]], [[0,1],[2]], [[0],[1,2]], [[0],[1],[2]] ] L14Comb
Counting problem fun cnt_lp 0 = 0 | cnt_lp 1 = 1 | cnt_lp n = 2 * (cnt_lp (n-1)); (* cnt_lp n = 2^(n-1) for n > 0 *) Property: cnt_lp (length xs) = (length (list_partition xs)) L14Comb
Constructing List Partitions fun lp [] = [] | lp (x::[]) = [ [[x]] ] | lp (y::x::xs) = letval aux = lp (x::xs) in (map (fn ss => [y]::ss) aux) @ (map (fn ss => (y::(hd ss)) :: (tl ss)) aux) end; L14Comb
Set partition • The set of (non-empty) sets [s1,s2,…,sm] forms a set partition of siff the sets si’s are collectively exhaustive and pairwise-disjoint. • E.g., set partitions of{1,2,3} -> { {{1,2,3}}, { {1}, {2,3}}, {{1,2}, {3}}, {{2}, {1,3}}, { {1},{2},{3}} } (Cf. list partition, number partition, etc.) L14Comb
Divide and Conquer m-partition of {1,2,3} 1occurring with with a part in m-partition of {2,3} (m-1)-partition of {2,3} solitary part{1}:: 2-partitions of {1,2,3} = {{ {1},{2,3}} } U {{{1,2},{3} } , { {2},{1,3} }} L14Comb
Counting problem fun cnt_m_sp 1 n = 1 | cnt_m_sp m n = if m > n then 0 elseif m = n then 1 else (cnt_m_sp (m-1) (n-1)) + (m * (cnt_m_sp m (n-1))); • Dependency (visualization) • Basis: Row 1 and diagonal (Half-plane inapplicable) • Recursive step: Previous row, previous column L14Comb
(cont’d) upto 3 6 = [3,4,5,6] fun upto m n = if (m > n) then [] else if (m = n) then [m] else m:: upto (m+1) n; fun cnt_sp n = foldr (op +) 0 (map (fn m => cnt_m_sp m n) (upto 1 n)); L14Comb
Constructing set partitions fun set_parts s = foldr (op@) [] ( map (fn m => (m_set_parts m s)) (upto 1 (length s)) ); fun ins_all e [] = [] | ins_all e (s::ss) = (((e::s)::ss) :: ( map (fnts => s :: ts) (ins_all e ss))); L14Comb
fun m_set_parts 1 s = [[s]] | m_set_parts m (s as hs::ts)= letval n = (length s) in if m > n then [] else if m = n then [foldr (fn (e,ss)=>[e]::ss ) [] s] elselet val p1 = (m_set_parts (m-1) ts) val p2 = (m_set_parts m ts) in (map (fn ss => [hs]::ss) p1) @ (foldr (op@) [](map (ins_all hs) p2 )) end end; L14Comb