|
| 1 | +Hello and welcome, |
| 2 | +My name is William, we're still talking about Network Flow, and today's topic is |
| 3 | +one or my all time favorite flow problems which is called elementary math. This |
| 4 | +problem is so interesting because its solution uses flow, but it really doesn't |
| 5 | +hit you as a flow problem to begin with. One of the hardest things about network |
| 6 | +flow is beleive it or not first identifying that the problem is a flow problem |
| 7 | +and then setting it up as so. This is why I'm spending a few videos solving some |
| 8 | +flow problems so you really start understanding the approach in how they are |
| 9 | +solved. |
| 10 | + |
| 11 | +Let's dive into the elementary math problem. This problem is actually on Kattis |
| 12 | +should you want to attempt it, the link is at the bottom of this slide and also |
| 13 | +in the description. Here's the problem statement: |
| 14 | +"Ellen is a math teacher who is preparing n (1 ≤ n ≤ 2500) questions for her math |
| 15 | +exam. In each question, the students have to add (+), subtract (−) or multiply |
| 16 | +(*) a pair of numbers." |
| 17 | +"Ellen has already chosen the n pairs of numbers. All that remains is to decide |
| 18 | +for each pair which of the three possible operations the students should |
| 19 | +perform. To avoid students getting bored, Ellen wants to make sure that the n |
| 20 | +correct answers to her exam are all different." |
| 21 | + |
| 22 | +"For each pair of numbers (a,b) in the same order as in the input, output a line |
| 23 | +containing a valid equation. Each equation should consist of five parts: a, one |
| 24 | +of the three operators, b, an equals sign (=), and the result of the expression. |
| 25 | +All the n expression results must be different. |
| 26 | +If there are multiple valid answers, output any of them. If there is no valid |
| 27 | +answer, output a single line with the string “impossible” instead." |
| 28 | + |
| 29 | +Let's have a look at an example. So Ellen goes and she picks 4 pairs of numbers, |
| 30 | +say: 1 and 5, 3 and 3, 4 and 5 and lastly -1 and -6. She wants to assign |
| 31 | +operators either plus, minus or multiply to yield unique answers on the right |
| 32 | +hand side of the equation. |
| 33 | + |
| 34 | +One assignment might be the following operators. |
| 35 | + |
| 36 | +However, this assignment of operators doesn't quite work because the answers are |
| 37 | +not unique on the right hand side. |
| 38 | + |
| 39 | +Here's another way of assigning operators to the same pairs of numbers. |
| 40 | + |
| 41 | +This assignment works because the answers are unique. |
| 42 | + |
| 43 | +So we just saw that not all assignment of operators yields a valid answer, but |
| 44 | +it's also possible for no answer to exist. Consider the following pairs of |
| 45 | +numbers: |
| 46 | + |
| 47 | +In this case there can be no solution because not enough unique answers can be |
| 48 | +generated using only the operators plus, minus and multiply. |
| 49 | + |
| 50 | +This problem presents itself as a network flow problem, even though that might |
| 51 | +not be obvious at first. Take a moment, and attempt to set up a flow graph that |
| 52 | +can solve this problem, it's actually a really great exercise. |
| 53 | + |
| 54 | +Along the way while you're doing this, there are a few questions you should ask |
| 55 | +yourself, or at least that I ask myself, this first is: |
| 56 | +1) Is there a way that this problem can be simplified as a bipartite graph? |
| 57 | +- I ask myself this because I know that solving a flow problem with a bipartite |
| 58 | +graph can be done efficiently, and also because bipartite graphs are easy to |
| 59 | +setup. |
| 60 | + |
| 61 | +2) Then I ask myself, how am I going to detect impossible sets of pairs? Will my |
| 62 | +flow graph be able to handle that, or do I need to do some pre or post |
| 63 | +processing to determine that. |
| 64 | + |
| 65 | +3) Another question is thinking about edge cases, like how do I handle multiple |
| 66 | +repeated input pairs, how is that going to change the flow graph. |
| 67 | + |
| 68 | +- These are all super important questions you need to ask yourself when solving |
| 69 | +this problem. This slide deck explains the first two, the third is left as an |
| 70 | +exercise; I don't want to give away a full solution to this awesome problem. |
| 71 | + |
| 72 | +Thinking about how we're going to solve this problem a little more, a key |
| 73 | +realization to make is that for every input pair, at most three unique solutions |
| 74 | +are produced. |
| 75 | +Think about the input pair, 2 and 3. Well for that pair, we can either: |
| 76 | +add 2 and 3, subtract 2 and 3, or multiply 2 and 3, so there will be at most |
| 77 | +three unique results. There may be less if there are collisions, think of the |
| 78 | +input pair: zero zero, zero plus zero is zero and zero multiplied by zero is |
| 79 | +also zero, so we may end up with less than 3 unique solutions but that's fine. |
| 80 | +The great thing about this is that we can easily set this up as a bipartite flow |
| 81 | +graph, with input pairs on one side and solutions on the other. |
| 82 | + |
| 83 | +Let’s see if we can setup the flow graph to solve this set of input pairs. We |
| 84 | +have the pairs: 1, 5; 3, 3; -1, -6; and 2, 2 |
| 85 | + |
| 86 | +We're going to setup the bipartite graph with input pair nodes on the left and |
| 87 | +answer nodes on the right. |
| 88 | + |
| 89 | +For our first input pair 1, 5; if we compute 1 - 5, 1 + 5 and 1 * 5 we get -4, 6 |
| 90 | +and 5 which become our answer nodes on the right. Attach and edge between the |
| 91 | +input pair and the answer. |
| 92 | + |
| 93 | +Do the same thing for the next input pair: make an input pair node and attach |
| 94 | +edges to the answer nodes. However, don't create another answer node if there |
| 95 | +already exists one with the value needed. In this example for instance, 3 + 3 is |
| 96 | +6, and we already have an answer node for 6, so attach an edge to the 6 node, do |
| 97 | +not create another one. This is the ensure that our answers are unique. |
| 98 | + |
| 99 | +Do the same thing for the two other remaining input pairs. |
| 100 | + |
| 101 | +<press> |
| 102 | + |
| 103 | +You'll notice that the last input pair only produced two outgoing edges and not |
| 104 | +three, this is because there was a collision; in particular 2 + 2 equal 4, but |
| 105 | +2 multiplied by 2 is also 4. |
| 106 | + |
| 107 | +Then like every bipartite graph you're trying to find a matching for, you'll |
| 108 | +want to add a source s and a sink t; and a matching is really what we're after |
| 109 | +here. If we can match input pairs to answers, then we've solved the problem. |
| 110 | + |
| 111 | +The next step after adding the source and the sink is to actually assign |
| 112 | +capacities to the edges of the flow graph. |
| 113 | +Let's start on the right side; the capacities from the answer nodes to sink |
| 114 | +should all have a capacity of one since answers need to be unique, and limiting |
| 115 | +the edge capacity to 1 ensures that. |
| 116 | + |
| 117 | +Capacities from input pairs to answers also have capacity one since only one of |
| 118 | +‘+’, ‘-‘ or ‘*' operators can be matched with an answer. |
| 119 | + |
| 120 | +Capacities from source to input pairs should reflect the frequency of the input |
| 121 | +pair. In this example, all frequencies are 1, but as we know, this isn’t always the case. |
| 122 | + |
| 123 | +And finally the capacity on the edges from the source to the input pairs should |
| 124 | +reflect the frequency of the input pair. By this I mean how many times that input |
| 125 | +pair is present in the input. In this example, all frequencies are 1, but as we |
| 126 | +know, this isn’t always the case. |
| 127 | + |
| 128 | +Now the flow graph is set up, so let's run a max-flow algorithm on it! |
| 129 | + |
| 130 | +The flow algorithm does its thing and some edges are filled with flow. These are |
| 131 | +the edges that were selected to be part oft he maximum flow. From this we can |
| 132 | +derive what the matching was. |
| 133 | + |
| 134 | +More specifically, we're interested in the middle edges, those are the edges |
| 135 | +which give us information about the matching. Every edge in the middle, with one |
| 136 | +unit of flow represents a matching from an input pair (a,b) to its answer. |
| 137 | +For example, the input pair 1,5 was matching with the answer node 6. |
| 138 | + |
| 139 | +From this we can even deduce the operator used for each matching (which is needed |
| 140 | +for final output). This can be done by trying which of (+, -, or *) results in |
| 141 | +the found matching. Basically we first solve the problem by figuring out which |
| 142 | +answers we get and then work backwards to figure out which operator was used. In |
| 143 | +theory we could tag each middle edge with the operator used, but I didn't bother. |
| 144 | + |
0 commit comments