CS4102 Algorithms Summer 2020 Warm Up

How many arithmetic operations are required to multiply a 푛 × 푚 Matrix with a 푚 × 푝 Matrix? (don’t overthink this)

푝 푚

푛 × 푚

1 Warm Up

How many arithmetic operations are required to multiply a 푛 × 푚 Matrix with a 푚 × 푝 Matrix? (don’t overthink this)

푝 푝 푚

푛 × 푚 = 푛

• 푚 multiplications and additions per element • 푛 ⋅ 푝 elements to compute • Total cost: 푚 ⋅ 푛 ⋅ 푝 2 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the (optimal) solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

3 Matrix Chaining

• Given a sequence of Matrices (푀1, … , 푀푛), what is the most efficient way to multiply them?

푐4 푐2 푐 1 푐3

푟 × 푟 푀 × 푀 푟1 푀1 × 2 푀2 3 3 푟4 4

4 Order Matters! 푐2 푐3 푐1 = 푟2 푐1 푐2 = 푟3 푟 × 푟 푟1 푀1 × 2 푀2 3 푀3

푐2

푟1

• 푀1 × 푀2 × 푀3 – uses 푐1 ⋅ 푟1 ⋅ 푐2 + c2 ⋅ 푟1 ⋅ 푐3 operations

5 Order Matters! 푐2 푐3 푐1 = 푟2 푐1 푐2 = 푟3 푟 × 푟 푟1 푀1 × 2 푀2 3 푀3

푐3

푟2

• 푀1 × (푀2 × 푀3) – uses c1 ⋅ r1 ⋅ 푐3 + (c2 ⋅ 푟2 ⋅ 푐3) operations

6 Order Matters! 푐1 = 푟2 푐2 = 푟3

• 푀1 × 푀2 × 푀3 – uses 푐1 ⋅ 푟1 ⋅ 푐2 + c2 ⋅ 푟1 ⋅ 푐3 operations 푀 = 7 × 10 – 10 ⋅ 7 ⋅ 20 + 20 ⋅ 7 ⋅ 8 = 2520 1 푀2 = 10 × 20 • 푀1 × (푀2 × 푀3) 푀3 = 20 × 8

– uses 푐1 ⋅ 푟1 ⋅ 푐3 + (c2 ⋅ 푟2 ⋅ 푐3) operations 푐1 = 10 푐 = 20 – 10 ⋅ 7 ⋅ 8 + 20 ⋅ 10 ⋅ 8 = 2160 2 푐3 = 8 푟1 = 7 푟2 = 10 푟3 = 20

7 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

8 1. Identify the Recursive Structure of the Problem

퐵푒푠푡 1, 푛 = cheapest way to multiply together 푀1 through 푀푛

푐4 푐2 푐 1 푐3

푟 푀 × 푟 푀 × 푀 푟1 푀1 × 2 2 3 3 푟4 4

9 1. Identify the Recursive Structure of the Problem

퐵푒푠푡 1, 푛 = cheapest way to multiply together 푀1 through 푀푛

퐵푒푠푡 2,4 + 푟1푟2푐4 퐵푒푠푡 1,4 = min 푐4

푟2

푐4 푐2 푐 1 푐3

푟 푀 × 푟 푀 × 푀 푟1 푀1 × 2 2 3 3 푟4 4

10 1. Identify the Recursive Structure of the Problem

퐵푒푠푡 1, 푛 = cheapest way to multiply together 푀1 through 푀푛

퐵푒푠푡 2,4 + 푟1푟2푐4 퐵푒푠푡 1,4 = min 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 4 + 푟1푟3푐4

푐 푐2 4

푟3 푟1

푐4 푐2 푐 1 푐3

푟 푀 × 푟 푀 × 푀 푟1 푀1 × 2 2 3 3 푟4 4

11 1. Identify the Recursive Structure of the Problem

퐵푒푠푡 1, 푛 = cheapest way to multiply together 푀1 through 푀푛

퐵푒푠푡 2,4 + 푟1푟2푐4 퐵푒푠푡 1,4 = min 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 4 + 푟1푟3푐4 퐵푒푠푡 1,3 + 푟1푟4푐4

푐3

푟1

푐4 푐2 푐 1 푐3

푟 푀 × 푟 푀 × 푀 푟1 푀1 × 2 2 3 3 푟4 4

12 1. Identify the Recursive Structure of the Problem

• In general:

퐵푒푠푡 푖, 푗 = cheapest way to multiply together 푀푖 through 푀푗 푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 퐵푒푠푡 푖, 푖 = 0

퐵푒푠푡 2, 푛 + 푟1푟2푐푛 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 푛 + 푟1푟3푐푛

퐵푒푠푡 1,3 + 퐵푒푠푡 4, 푛 + 푟1푟4푐푛 퐵푒푠푡 1, 푛 = min 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 푛 + 푟1푟5푐푛 …

퐵푒푠푡 1, 푛 − 1 + 푟1푟푛푐푛 13 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

14 2. Save Subsolutions in Memory

• In general:

퐵푒푠푡 푖, 푗 = cheapest way to multiply together 푀푖 through 푀푗 푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 퐵푒푠푡 푖, 푖 = 0 Read from M[i,j] if present

Save to M[i,j] 퐵푒푠푡 2, 푛 + 푟1푟2푐푛 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 푛 + 푟1푟3푐푛

퐵푒푠푡 1,3 + 퐵푒푠푡 4, 푛 + 푟1푟4푐푛 퐵푒푠푡 1, 푛 = min 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 푛 + 푟1푟5푐푛 …

퐵푒푠푡 1, 푛 − 1 + 푟1푟푛푐푛 15 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

16 3. Select a good order for solving subproblems

• In general:

퐵푒푠푡 푖, 푗 = cheapest way to multiply together 푀푖 through 푀푗 푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 퐵푒푠푡 푖, 푖 = 0 Read from M[n] if present

Save to M[n] 퐵푒푠푡 2, 푛 + 푟1푟2푐푛 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 푛 + 푟1푟3푐푛

퐵푒푠푡 1,3 + 퐵푒푠푡 4, 푛 + 푟1푟4푐푛 퐵푒푠푡 1, 푛 = min 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 푛 + 푟1푟5푐푛 …

퐵푒푠푡 1, 푛 − 1 + 푟1푟푛푐푛 17 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 1

0 2

0 3

0 4

0 5

0 6 18 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 1

0 2

0 3

0 4

0 5 퐵푒푠푡 1,2 = min 퐵푒푠푡 1,1 + 퐵푒푠푡 2, 2 + 푟1푟2푐2 0 6 19 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 1

0 2625 2

0 3

0 4

0 5 퐵푒푠푡 2,3 = min 퐵푒푠푡 2,2 + 퐵푒푠푡 3, 3 + 푟2푟3푐3 0 6 20 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 1

0 2625 2

0 750 3

0 1000 4

0 5000 5

0 6 21 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 7875 1

0 2625 2 푟1푟2푐3 = 30 ⋅ 35 ⋅ 5 = 5250 푟1푟3푐3 = 30 ⋅ 15 ⋅ 5 = 2250 0 750 3

0 1000 4 0 2625 0 5000 5 퐵푒푠푡 1,3 = min 퐵푒푠푡 1,1 + 퐵푒푠푡 2, 3 + 푟1푟2푐3 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 3 + 푟1푟3푐3 0 6 15750 0 22 3. Select a good order for solving subproblems

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 7875 1

0 2625 2

To find 퐵푒푠푡(푖, 푗): Need all preceding 0 750 3

terms of row 푖 and column 푗 0 1000 4 Conclusion: solve in order of diagonal 0 5000 5 0 6 23 1 2 3 4 5 6 0 15750 7875 1

0 2625 2

0 750 3

0 1000 4 1 2 3 4 5 6 0 5000 5 0 15750 7875 1 0 6 0 2625 2

0 750 3

0 1000 4

0 5000 5

0 6 Matrix Chaining

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 7875 9375 11875 15125 1

0 2625 4375 7125 10500 2

0 750 2500 5375 3 퐵푒푠푡 1,1 + 퐵푒푠푡 2, 6 + 푟1푟2푐6 0 1000 3500 4 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 6 + 푟1푟3푐6 퐵푒푠푡 1,6 = min 퐵푒푠푡 1,3 + 퐵푒푠푡 4, 6 + 푟1푟4푐6 0 5000 5 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 6 + 푟1푟5푐6 0 6 퐵푒푠푡 1,5 + 퐵푒푠푡 6, 6 + 푟1푟6푐6 25 Run Time

1. Initialize 퐵푒푠푡[푖, 푖] to be all 0s 2. Starting at the main diagonal, working to the upper-right, fill in each cell using: Θ(푛2) cells in the Array 1. 퐵푒푠푡 푖, 푖 = 0 푗−1 2. 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 Each “call” to Best() is a Θ(푛) options for each cell O(1) memory lookup

Θ(푛3) overall run time 26 Backtrack to find the best order

“remember” which choice of 푘 was the minimum at each cell

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 7875 9375 11875 15125 1 1 3 0 2625 4375 7125 10500 2

0 750 2500 5375 3 퐵푒푠푡 1,1 + 퐵푒푠푡 2, 6 + 푟1푟2푐6 0 1000 3500 4 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 6 + 푟1푟3푐6 5 퐵푒푠푡 1,6 = min 퐵푒푠푡 1,3 + 퐵푒푠푡 4, 6 + 푟1푟4푐6 0 5000 5 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 6 + 푟1푟5푐6 0 6 퐵푒푠푡 1,5 + 퐵푒푠푡 6, 6 + 푟1푟6푐6 27 27 Matrix Chaining

35 15 5 10 20 25

푀4 푀3 푀5 30 푀1 × 35 × 15 × 5 × 10 × 20 푀6 푀2

푗−1 퐵푒푠푡 푖, 푗 = min 퐵푒푠푡 푖, 푘 + 퐵푒푠푡 푘 + 1, 푗 + 푟푖푟푘+1푐푗 푘=푖 푗 = 1 2 3 4 5 6 퐵푒푠푡 푖, 푖 = 0 0 15750 7875 9375 11875 15125 1 1 3 0 2625 4375 7125 10500 2

0 750 2500 5375 3 퐵푒푠푡 1,1 + 퐵푒푠푡 2, 6 + 푟1푟2푐6 0 1000 3500 4 퐵푒푠푡 1,2 + 퐵푒푠푡 3, 6 + 푟1푟3푐6 5 퐵푒푠푡 1,6 = min 퐵푒푠푡 1,3 + 퐵푒푠푡 4, 6 + 푟1푟4푐6 0 5000 5 퐵푒푠푡 1,4 + 퐵푒푠푡 5, 6 + 푟1푟5푐6 0 6 퐵푒푠푡 1,5 + 퐵푒푠푡 6, 6 + 푟1푟6푐6 28 Storing and Recovering Optimal Solution

• Maintain table Choice[i,j] in addition to Best table

– Choice[i,j] = k means the best “split” was right after Mk – Work backwards from value for whole problem, Choice[1,n] – Note: Choice[i,i+1] = i because there are just 2 matrices • From our example:

– Choice[1,6] = 3. So [M1 M2 M3] [M4 M5 M6] – We then need Choice[1,3] = 1. So [(M1) (M2 M3)] – Also need Choice[4,6] = 5. So [(M4 M5) M6] – Overall: [(M1) (M2 M3)] [(M4 M5) M6]

29 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

30 In Season 9 Episode 7 “The Slicer” of the hit 90s TV show , George discovers that, years prior, he had a heated argument with his new boss, Mr. Kruger. This argument ended in George throwing Mr. Kruger’s boombox into the ocean. How did George make this discovery? https://www.youtube.com/watch?v=pSB3HdmLcY4 31

Seam Carving

• Method for image resizing that doesn’t scale/crop the image

33 Seam Carving

• Method for image resizing that doesn’t scale/crop the image

34 Seam Carving

• Method for image resizing that doesn’t scale/crop the image

Cropped Scaled Carved

35 Cropping

• Removes a “block” of pixels

Cropped

36 Scaling

• Removes “stripes” of pixels

Scaled

37 Seam Carving • Removes “least energy seam” of pixels • http://rsizr.com/

Carved

38 Seattle Skyline

39 Energy of a Seam

• Sum of the energies of each pixel – 푒 푝 = energy of pixel 푝 • Many choices – E.g.: change of gradient (how much the color of this pixel differs from its neighbors) – Particular choice doesn’t matter, we use it as a “black box”

40 Identify Recursive Structure

Let 푆 푖, 푗 = least energy seam from the bottom of the image up to pixel 푝푖,푗

푝푖,푗

41 Finding the Least Energy Seam

Want the least energy seam going from bottom to top, so delete: 푚 min 푆(푛, 푘) 푘=1

푝푛,푘

푚 42 Computing 푆(푛, 푘)

Assume we know the least energy seams for all of row 푛 − 1 (i.e. we know 푆(푛 − 1, ℓ) for all ℓ) 푝푛,푘

Known through 푛 − 1

푚 43 Computing 푆(푛, 푘)

Assume we know the least energy seams for all of row 푛 − 1 (i.e. we know 푆(푛 − 1, ℓ) for all ℓ)

푝푛,푘

S(n,k)

S(n-1,k-1) S(n-1,k) S(n-1,k+1)

44 Computing 푆(푛, 푘)

Assume we know the least energy seams for all of row 푛 − 1 (i.e. we know 푆(푛 − 1, ℓ) for all ℓ) 푆 푛 − 1, 푘 − 1 + 푒(푝 ) 푆 푛, 푘 = 푚푖푛 푛,푘 푆 푛 − 1, 푘 + 푒(푝푛,푘) 푝푛,푘 푆 푛 − 1, 푘 + 1 + 푒(푝푛,푘) S(n,k)

S(n-1,k-1) S(n-1,k) S(n-1,k+1)

45 Bring It All Together

Start from bottom of image (row 1), solve up to top

Initialize 푆 1, 푘 = 푒(푝1,푘) for each pixel in row 1

푛 Energy of the seam initialized to the energy of that pixel 푚 46 Bring It All Together

Start from bottom of image (row 1), solve up to top

Initialize 푆 1, 푘 = 푒(푝1,푘) for each pixel 푝1,푘

푆 푖 − 1, 푘 − 1 + 푒(푝푖,푘) 푚 For 푖 > 2 find 푆 푖, 푘 = min 푆 푖 − 1, 푘 + 푒(푝푖,푘) 푘=1 푆 푖 − 1, 푘 + 1 + 푒(푝푖,푘)

푛 Energy of the seam initialized to the energy of that pixel 푚 47 Bring It All Together

Start from bottom of image (row 1), solve up to top

Initialize 푆 1, 푘 = 푒(푝1,푘) for each pixel 푝1,푘

푆 푖 − 1, 푘 − 1 + 푒(푝푖,푘) 푚 For 푖 > 2 find 푆 푖, 푘 = min 푆 푖 − 1, 푘 + 푒(푝푖,푘) 푘=1 푆 푖 − 1, 푘 + 1 + 푒(푝푖,푘) Pick smallest from top row, backtrack, removing those pixels

푛 Energy of the seam initialized to the energy of that pixel 푚 48 Run Time?

Start from bottom of image (row 1), solve up to top

Initialize 푆 1, 푘 = 푒(푝1,푘) for each pixel 푝1,푘 Θ(푚)

푆 푖 − 1, 푘 − 1 + 푒(푝푖,푘) 푚 Θ(푛 ⋅ 푚) For 푖 ≥ 2 find 푆 푖, 푘 = min 푆 푖 − 1, 푘 + 푒(푝푖,푘) 푘=1 푆 푖 − 1, 푘 + 1 + 푒(푝푖,푘) Pick smallest from top row, backtrack, removing those pixels Θ(푛 + 푚)

푛 Energy of the seam initialized to the energy of that pixel 푚 49 Repeated Seam Removal Only need to update pixels dependent on the removed seam 2푛 pixels change Θ(2푛) time to update pixels Θ(푛 + 푚) time to find min+backtrack

푚 50 51 Virginia Congressional Districts would be drawn by: • An 16-member panel • 2 members from each of the two political parties with the most representatives in the Senate and General assembly • 8 members are citizens selected by a committee of 5 retired circuit court judges

52 Gerrymandering

• Manipulating electoral district boundaries to favor one political party over others • Coined in an 1812 Political cartoon • Governor Elbridge Gerry signed a bill that redistricted Massachusetts to benefit his Democratic- Republican Party The Gerrymander

53 According to the Supreme Court

• Gerrymandering cannot be used to: – Disadvantage racial/ethnic/religious groups • It can be used to: – Disadvantage political parties

54 VA 5th District

55 VA 5th District

2018 Election

56 Gerrymandering Today • Computers make it really effective

57 Gerrymandering Today • Computers make it really effective

58 Gerrymandering Today

59 How does it work? • States are broken into precincts • All precincts have the same size • We know voting preferences of each precinct • Group precincts into districts to maximize the number of districts won by my party

Overall: R:217 D:183

R:65 R:45 D:35 D:55 vs R:60 R:47 D:40 D:53 60 How does it work? • States are broken into precincts • All precincts have the same size • We know voting preferences of each precinct • Group precincts into districts to maximize the number of districts won by my party

Overall: R:217 D:183 R:125 R:92 R:112 R:105

R:65 R:45 R:65 R:45 R:65 R:45 D:35 D:55 D:35 D:55 D:35 D:55

R:60 R:47 R:60 R:47 R:60 R:47 D:40 D:53 D:40 D:53 D:40 D:53 61 Gerrymandering Problem Statement

• Given: – A list of precincts: 푝1, 푝2, … , 푝푛 – Each containing 푚 voters • Output: – Districts 퐷1, 퐷2 ⊂ {푝1, 푝2, … , 푝푛} – Where 퐷1 = |퐷2| 푛 푚푛 • precincts per district (so voters) Successful 2 2 푚푛 푚푛 Gerrymandering! – 푅 퐷 > and 푅 퐷 > 1 4 2 4 • 푅(퐷푖) gives number of “Regular Party” voters in 퐷푖 mn • 푅 퐷 > means 퐷 is majority “Regular Party” 푖 4 푖 – “failure” if no such solution is possible

62 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

63 Dynamic Programming

• Requires Optimal Substructure – Solution to larger problem contains the solutions to smaller ones • Idea: 1. Identify the recursive structure of the problem • What is the “last thing” done? 2. Save the solution to each subproblem in memory 3. Select a good order for solving subproblems • “Top Down”: Solve each recursively • “Bottom Up”: Iteratively solve smallest to largest

64

Consider the last precinct After assigning the 퐷1 first 푛 − 1 precincts 푘 + 1 precincts 퐷1 푝1, 푝2, … , 푝푛−1 푥 + 푅(푝 ) voters for R 푘 + 1 precincts 푛 If we assign 퐷 퐷1 푥 + 푅(푝푛) voters for R 2 푝푛to 퐷1 푛 − 푘 − 1 precincts 푘 precincts Valid gerrymandering if: 푦 voters for R 푛 푥 voters for R 푘 + 1 = , 2 푝푛 푚푛 World One 푥 + 푅 푝푛 , 푦 > 퐷2 4 푛 − 푘 − 1 precincts 퐷1 퐷2 푦 voters for R If we assign 푘 precincts 푛 − 푘 precincts 푥 voters for R 푝 to 퐷 푛 2 푦 + 푅(푝 ) voters for R 푛 퐷 2 푛 − 푘 precincts Valid gerrymandering if: 푛 푦 + 푅(푝 ) voters for R n − 푘 = , 푛 2 푚푛 푥, 푦 + 푅 푝 > 푛 4 World Two 65 Define Recursive Structure

푆 푗, 푘, 푥, 푦 = True if from among the first 풋 precincts: 풌 are assigned to 퐷1 푛 × 푛 × 푚푛 × 푚푛 exactly 풙 vote for R in 퐷1 exactly 풚 vote for R in 퐷2

4D Dynamic Programming!!!

66 Two ways to satisfy 푆 푗, 푘, 푥, 푦 : 퐷1 푆 푗, 푘, 푥, 푦 = True if: 푘 − 1 precincts from among the first 푗 precincts 푥 − 푅(푝푗) voters for R 푝푗 푘 are assigned to 퐷1 exactly 푥 vote for R in 퐷 퐷 1 2 Then assign exactly 푦 vote for R in 퐷 푗 − 푘 precincts 2 푝푗to 퐷1 푦 voters for R 퐷1 OR 푘 precincts 퐷1 푥 voters for R 푘 precincts 퐷2 푥 voters for R 푗 − 푘 precincts 푝푗 퐷2 푦 voters for R 푗 − 1 − 푘 precincts Then assign 푦 − 푅(푝푗) voters for R 푝푗to 퐷2

푆 푗, 푘, 푥, 푦 = 푆 푗 − 1, 푘 − 1, 푥 − 푅 푝푗 , 푦 ∨ 푆 푗 − 1, 푘, 푥, 푦 − 푅 푝푗 67 Final Algorithm

푆 푗, 푘, 푥, 푦 = 푆 푗 − 1, 푘 − 1, 푥 − 푅 푝푗 , 푦 ∨ 푆 푗 − 1, 푘, 푥, 푦 − 푅 푝푗 Initialize 푆(0,0,0,0) = True for 푗 = 1, … , 푛: 푆 푗, 푘, 푥, 푦 = True if: 푛 from among the first 푗 precincts for 푘 = 1, … , min (푗, ): 푘 are assigned to 퐷 2 1 for 푥 = 0, … , 푗푚: exactly 푥 vote for R in 퐷1 exactly 푦 vote for R in 퐷2 for 푦 = 0, … , 푗푚: 푆 푗, 푘, 푥, 푦 =

푆 푗 − 1, 푘 − 1, 푥 − 푅 푝푗 , 푦 ∨ 푆 푗 − 1, 푘, 푥, 푦 − 푅 푝푗 푛 푚푛 푚푛 Search for True entry at 푆(푛, , > , > ) 2 4 4

68 Run Time

푆 푗, 푘, 푥, 푦 = 푆 푗 − 1, 푘 − 1, 푥 − 푅 푝푗 , 푦 ∨ 푆 푗 − 1, 푘, 푥, 푦 − 푅 푝푗 Initialize 푆(0,0,0,0) = True 푛 for 푗 = 1, … , 푛: 푛 푛 for 푘 = 1, … , min (푗, ): 2 2 Θ(푛4푚2) 푛푚 for 푥 = 0, … , 푗푚: 푛푚 for 푦 = 0, … , 푗푚: 푆 푗, 푘, 푥, 푦 =

푆 푗 − 1, 푘 − 1, 푥 − 푅 푝푗 , 푦 ∨ 푆 푗 − 1, 푘, 푥, 푦 − 푅 푝푗 푛 푚푛 푚푛 Search for True entry at 푆(푛, , > , > ) 2 4 4

69 Θ(푛4푚2)

• Input: list of precincts (size 푛), number of voters (integer 푚) • Runtime depends on the value of 푚, not size of 푚 – Run time is exponential in size of input – Input size is 푛 + 푚 = 푛 + log 푚 • Note: Gerrymandering is NP-Complete

70