Sunday, February 18th, 2024

How far that little candle throws its beams! So shines a good deed in a naughty world.

— William Shakespeare

  • ECS165A Milestone 2 thoughts
    • Instead of storing page bytearray in Page objects, I’m more tempted to have Bufferpool act as a context manager that returns ReadonlyPage or ReadwritePage objects when read/write is requested.

ECS122A Lecture: DP continued

  • knapsack problem
    • input: Set of items with items 1 - n. Each item has a value v[i] and weight w[i].
    • output: set of items with maximum value such that the total weight of items is under capacity of knapsack
    • recurrence solution
      • For each item, we can either take it or not take it.
      • opt(n, W) = max(v[n] + opt(n-1, W - w[n]), opt(n-1, W))
        • either take the item (and subtract weight), or find the opt without taking the item (weight stays the same)
    • DP solution
      • general solution: for items 1 to with bag capacity
        • opt(i, j): max(v[i] + opt(i - 1, j - w[i]), opt(i - 1, j))
        • depends on previous solutions for subset of items and lesser bag capacities
      • we can calculate this from bottom-up (calculate from i=1 to i=n)
        • let m[i, j] store opt(i, j)
      • we don’t need traceback (unlike rod problem)
        • for example, if and , we can check if v[20] + m[19, W - w[20]] == m[20, W] to see if item 20 should be taken
      • code:
        • for j = 1 to W:
          • for i = 1 to n
            • `m[i, j] = max(v[i] + m[i - 1, j - w[i]], m[i-1, j])
  • longest common subsequence problem (LCS)
    • input: ,
    • output: longest subsequence that is part of both and (subsequences don’t have to be substrings and don’t have to be continuous; plus, each element’s position in and don’t have to be the same/aligned, though the order of elements has to be preserved); for example lcs(xatttab, aggae) = aa
    • cases given of length and of length
      • lcs(m, n) = (X[m] == Y[n]) + lcs(m - 1, n - 1) (ignore both, and only adds 1 to LCS if )
      • lcs(m, n) = lcs(m, n - 1) (ignore )
      • lcs(m, n) = lcs(m - 1, n) (ignore both and )
      • This can be calculated bottom up via a 2D matrix. Note the dependency between these 4 subproblems.
    • code:
      • m[i, j] = opt(i, j): length of longest common subsequence for and
      • m[0, j] = 0 for all j is 0, and m[i, 0] for all i is 0 (both needed due to the - 1’s)
      • for i = 1 to m
        • for j = 1 to n
          • `m[i, j] = max(m[i - 1, j - 1] + match(X[i], Y[i]), m[i, j - 1], m[i - 1, j])
    • traceback () needed to find actual LCS
      • repeatedly find and move to the max neighboring cell in m starting from bottom right
      • if you moved up or left, ignore one corresponding character
      • if you moved diagonally (towards top left), then either ignore both characters, or include the character in LCS if they match
  • pretty printing problem
    • input: words to in a paragraph in a single line. For any word , we know its length .
    • we know there will at least be spaces to delimit words
    • let be the max display length of a line
    • cost function for a line from words to : (cube it to heavily discourage unused space on the line)
    • output: a new array with line breaks inserted that minimizes the cost function for each line
    • we basically have to decide where the last line starts
    • opt(n) = min_x(cost(x, n) + opt(x - 1)): find the x that minimizes cost plus opt(x-1).
  • Note that optimal substructure proof only depends on the problem, not the algorithm.
  • optimal substructure proof revisited with pretty printing problem example
    • define optimal solution
      • opt = { set of lines such that words to are on the first line }
      • proof will also work if starting from the last line
    • prove words to on lines to has minimum cost
    • define A as opt without line 1 ( to )
    • Assume A is not an optimal way for the subproblem. Assume there exists a better way B to print to .
    • But the costs are the same. Contradiction.