Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Introduction to Algorithms

CS 4820, Spring 2010

Reference Solution (Problem 4, Chapter 6)

Introduction

This reference solution is for problem 4, chapter 6 from our textbook. I shall describe two
different algorithms that solve the given problem efficiently. The last section was intended for
explanation of my thought process.

Solution 1: Dynamic Programming

2.1

Algorithm

My dynamic programming solution keeps two tables with the following definition:
OPTN Y (i): the optimal operating costs of running the business from month 1 to i, inclusive,
where we run the business out of NY in the ith month
OPTSF (i): the optimal operating costs of running the business from month 1 to i, inclusive,
where we run the business out of SF in the ith month
Notice that min (OPTN Y (n), OPTSF (n)) would give us the optimal operating cost for the main
problem. Similarly, in the case of the ith month, we have two options for the previous month, so
we could find a recurrence relation for OPTN Y (i) (and similarly for OPTSF (i)). Also, our base
case would be when i = 1, and it is easy to see that OPTN Y (1) = N1 and OPTSF (1) = S1 . In
summary heres the recurrence relation and base case for my algorithm:

OPTN Y (i) = Ni
i=1

OPT (i) = S
i=1
SF
i

OPTN Y (i) = min (OPTN Y (i 1), OPTSF (i 1) + M ) + Ni i 2

OPTSF (i) = min (OPTN Y (i 1) + M, OPTSF (i 1)) + Si i 2


As argued earlier, our final answer could be computed by taking the minimum value of OPTN Y (n)
and OPTSF (n).

2.2

Runtime Analysis

It is clear that we have O(n) entries for the two tables and to fill in one entry, we need O(1) time
to look up two previous entries, so the overall running time should be O(n).

2.3

Proof of Correctness

Proof. Let us first show that our recurrence for OPTN Y (i) is correct. We considered two options
for the (i 1)th month, given that we run the business out of NY in the ith month.
If we ran the business out of NY in (i 1)th month, our optimal operating costs up to the
(i 1)th month would be OPTN Y (i 1)
So, if we were to choose this option, our net costs up to the ith month would be:
OPTN Y (i 1) + Ni
If we ran the business out of SF in (i 1)th month, our optimal operating costs up to the
(i 1)th month would be OPTSF (i 1)
So, if we were to choose this option, our net costs up to the ith month would be:
OPTSF (i 1) + M + Ni
note that we now have to pay the fixed moving cost given by M
Hence, recurrence for OPTN Y (i) is correct for i 2, and similarly, OPTSF (i) is correct. If i = 1,
we already argued that OPTN Y (1) and OPTSF (1) are optimal and thus correct.
Finally, we can prove our algorithm is correct by induction as follows:
Base case) i = 1
It is obvious that OPTN Y (1) = N1 and OPTSF (1) = S1 as there is no other costs
involved for the first month.
Induction Hypothesis) we assume that OPTN Y (k 1) and OPTSF (k 1) are computed
correctly for some k 2
Inductive Step) we prove our statement for k, that is, OPTN Y (k) and OPTSF (k) are
computed correctly, given our induction hypothesis above
For the case of OPTN Y (k) when we run the business out of NY in the k th month, our
operating costs for the given k th month depends only on three things:
operating costs up to the (k 1)th month
operating cost of the k th month itself
and the moving cost (if any)
There are only two different cases we need to consider: one in which we ran the business
out of NY in the (k 1)th month and another in which we ran the business out of SF in
the (k 1)th month. We showed that our recurrence for OPTN Y (k) is correct, and thus our
OPTN Y (k) is optimal for k, if OPTN Y (k 1) and OPTSF (k 1) are optimal. Similarly,
our OPTSF (k) is optimal for k.
Hence, our algorithm finds the optimal operating costs

Solution 2: Reduction to Shortest Path

Another way to solve this problem is to reduce the problem to a shortest-path problem.

3.1

Reduction

Given an input instance of the business problem (namely, n, Ni , Si , M ) my algorithm constructs


a (directed) graph G = (V, E) in the following way.
V consists of 2n + 2 nodes as following:
V = {vi,N Y : 1 i n} {vi,SF : 1 i n} {start, end}
where start and end specify start/end nodes for our shortest path problem and vi,c
represents where we run the business in the ith month (c is either N Y or SF )
E consists of 4n (directed) edges with costs
an edge from start to v1,N Y with cost N1
an edge from start to v1,SF with cost S1
an edge from vi,N Y to vi+1,N Y with cost Ni+1 (1 i < n)
an edge from vi,N Y to vi+1,SF with cost M + Si+1 (1 i < n)
an edge from vi,SF to vi+1,SF with cost Si+1 (1 i < n)
an edge from vi,SF to vi+1,N Y with cost M + Ni+1 (1 i < n)
an edge from vn,N Y to end with cost 0
an edge from vn,SF to end with cost 0
Note that G is a DAG (directed acyclic graph) with no negative-cost edges. Hence, we could use
classic shortest path finding algorithms, such as Dijkstra and Bellman-Ford, to find the shortest
path from start to end.

3.2

Running Time

I created O(n) nodes and O(n) edges. To create an edge, we simply assign costs to edges and
we did not have any other complicated computations. Hence, the construction subroutine of our
algorithm runs in polynomial time, in O(n).
Using Dijkstra algorithm as a sub-routine (which takes O(|E| log |V |) = O(n log n) in our case),
the overall time complexity of this algorithm is O(n + n log n) = O(n log n).

3.3

Proof of Correctness

Proof. To prove correctness of my algorithm, I shall prove the following two statements:
1. the optimal operating cost the shortest path (in our reduction)
2. the optimal operating cost the shortest path (in our reduction)

3.3.1

Proof of Claim 1

Let us denote the optimal solution for the original solution that costs us d units of money as
OPT = {c1 , c2 , . . . , cn } where each ci is either N Y or SF , denoting the city out of which we ran
the business in the ith month. For convenience, let us define a function f (i) for i = 1, 2, . . . , n as
follows:
(
(
f (i) = Ni + i if ci = N Y
0
if i = 1 or ci = ci1
where i =
f (i) = Si + i if ci = SF
M if i 2 and ci 6= ci1
In words, f (i) denotes the cost of running the business in the ith month atP
office ci and i is the
moving cost between the months i 1 and i, if any. Hence, cost(OPT) = ni=1 f (i).
Now, consider a path from start to end in our constructed graph. It is clear that we can find a
path that costs us precisely cost(OPT):
namely, the path P :: (start) (v1,c1 ) (v2,c2 ) (vn1,cn1 ) (vn,cn ) (end).
Note that f (i) agrees with the cost of an edge in the path P that is into the node vi,ci (and the
edge going out of vn,cn has cost 0), and thus the overall cost of the path P is equal to cost(OPT).
I do not claim that P is the shortest path, but the shortest path in G would cost no more than
cost(OPT) because we found a path that costs cost(OPT).
3.3.2

Proof of Claim 2

The proof is almost the same as what we did for the previous claim.
Now, let us denote any path P in G as an ordered list of nodes such that: P :: (start)
(v1,c1 ) (v2,c2 ) (vn1,cn1 ) (vn,cn ) (end) where ci s are either N Y or SF . Note
that the shortest path must be of this form, according to our construction of the graph. Let us
denote the corresponding assignment of offices to months as AP = {c1 , c2 , . . . , cn }.
th
Using
Pn AP, we are running the business out of ci in the i month. This will cost us: cost(AP) =
i=1 f (ci ); we are using the same function f that was defined earlier.

Using the very same argument from previous step (comparing f (i) with the edge going into vi,ci
in path P ), we know that cost(AP) = cost(P ). In particular, if P is the shortest path in G, then
the claim implies that we can find a valid assignment of offices to months, whose cost is equal to
cost(P ) (there may or may not be a better assignment).
3.3.3

Conclusion

Combining the two claims above, we conclude that the shortest path is equal to the costs of
operating the business, and this completes the proof of correctness (note that a b and a b
implies a = b).

Explanation of Thought Process

This section explains my thought process when I was working on this problem. These comments
are supplementary, and I recommend you read the comments and the reference solution side-byside.

4.1
4.1.1

Thought Process - Dynamic Programming


Comments for Section 2.1

In each month i, we have two options: run the business out of NY or out of SF. Hence, it seems
natural to have the two tables OPTN Y and OPTSF as I described in Section 2.1.
Notice that, if we already computed the correct values for i = n, then the optimal solution is
precisely min (OPTN Y (n), OPTSF (n)); in the nth month, we either run the business out of NY
or out of SF, and this simple expression considers both cases. Hence, all we need to do is to
compute the two tables (this shows you how you can try to define your own subproblems that
make it easier to solve the main problem given).
Now let us focus on how to solve OPTN Y (i) and OPTSF (i) for any i between 1 and n, inclusive.
First, consider how to compute OPTN Y (i). Recall that we must run the business out of NY in
the ith month, in the case of OPTN Y (i). However, we have two options for the (i 1)th month:
run the business out of NY or out of SF (now things sound familiar, or recursive, because we
keep thinking of our only two choices over and over again).
Again, these two are the only options and our OPTN Y (i) does not depend on any other variables
than OPTN Y (i 1), OPTSF (i 1), Ni , and M [I shall revisit this statement in the proof of
correctness section]. Now we could write OPTN Y (i) formally:
OPTN Y (i) = min (OPTN Y (i 1) + Ni , OPTSF (i 1) + M + Ni )
= min (OPTN Y (i 1), OPTSF (i 1) + M ) + Ni
We could take Ni out of the min() function as it appears in both terms (and what is remaining
in the min() function is more important than Ni ).
Now what? We solved OPTN Y (i) and OPTSF (i) for i, but what happens if i = 1? In both
equations above, we have OPTN Y (i 1) and OPTSF (i 1) terms, which are not defined when
i = 1. Yes, we need a base case here. Most of the time, base cases are trivial, but they are still
important, so do NOT forget to specify your base case.
It is easy to see that OPTN Y (1) = N1 because we do not have any moving cost for the first
month; similarly, OPTSF (1) = S1 . In conclusion, our algorithm is to compute the following:

OPTN Y (i) = Ni
i=1

OPT (i) = S
i=1
SF
i

OPTN Y (i) = min (OPTN Y (i 1), OPTSF (i 1) + M ) + Ni i 2

OPTSF (i) = min (OPTN Y (i 1) + M, OPTSF (i 1)) + Si i 2


This looks like any typical dynamic programming problems we covered in class (using onedimensional DP table), except we have two tables.

4.1.2

Comments for Section 2.3

In general, your description of algorithm would have covered some details of why the algorithm
is correct, in the case of dynamic programming. Recall that I claimed that OPTN Y (i) only
depends on OPTN Y (i 1), OPTSF (i 1), Ni , and M so that if OPTN Y (i 1) and OPTSF (i 1)
are optimal, then OPTN Y (i) must be optimal.
This is somewhat straightforward, but you still need to prove it (usually by induction, in the
case of DP).
We described our dynamic programming algorithm, analyzed the running time of the algorithm,
and proved its correctness, and we are done.

4.2
4.2.1

Thought Process - Reduction to Shortest Path


Comments for Section 3.1

In case you are not sure what reduce means here, we shall cover this material in later chapters, but
this guideline is meant for people who feel more comfortable when solving [some] DP problems
using shortest-path algorithms. Informally, reduction simply means you reduce a given problem
to another problem (that you know how to solve, perhaps easily).
The following paragraphs describe how I came up with the reduction I described in Section 3.1.
First thing we should do is to reduce the given problem to a shortest path problem, by constructing a graph. In general, you can think of this step as creating nodes that represent some
sort of states (which are somewhat equivalent to the table entries of dynamic programming)
and assign right costs on edges between nodes so that shortest path from one (special) node to
another (special) node is essentially the optimal solution of the original problem.
I would first create 2n nodes, each of which represents the following: in the ith month, we run the
business out of NY or out of SF. There are n months and we have two choices for each month, so
it is quite natural to think of creating 2n nodes representing those choices. Also, I would like to
have two special nodes for the starting node and the destination node. Since we are reducing a
problem into another, it is in generally helpful to illustrate how an instance to the shortest path
problem is created:

The top row shows my n nodes represented as vi,N Y and the bottom row shows my n nodes
represented as vi,SF ; the left-most node is the starting node and the right-most node is the
destination node. I have not created any edges yet.
When I add egges to the graph, I should make sure that the shortest path from start to end
should be equal to the minimum operating costs of running the business for n months in the
original problem (so that we can claim that our reduction is correct). That means, my edges

somehow should take monthly costs (Ni s and Si s) and fixed moving costs (M ) into account.
First thought comes into my mind is that, what happens if n = 1 or n = 2 (e.g. simplest cases)?
In the case of n = 1, there are precisely two choices for me: either run the business out of NY or
out of SF, and the optimal operating costs should be min(N1 , S1 ). In the case of n = 2, things
are a bit different as I also need to worry about the moving costs. However, for the first month,
there is still no moving costs involved, so I am convinced that I should draw one edge from start
to v1,N Y with cost N1 and another edge from start to v1,SF with cost S1 . Similarly, at the end of
the nth month, I do not need to spend any more money, so it would make sense for me to create
an edge from vn,N Y to end with no cost (zero) and same for vn,SF . Having edges with zero costs
means that we could go from one vertex to another at no costs, but this is different from having
no edge between two vertices as we cannot go from one to another if there is no edge between
them.
Now my graph would look like the following:

Also, if we were to run the business out of NY in (i + 1)th month after running it out of NY in
the ith month, it would not cost us any moving costs, and this leads me to creating an edge from
vi,N Y to vi+1,N Y with cost equal to Ni+1 for i = 1, 2, . . . , n 1. Same for the nodes that represent
the San Francisco office. The following figure takes this account.

Finally, the last thing I need to consider is when I happen to switch bewteen the two offices. So
if I run the business out of NY in the ith month and then switch to the SF office in the (i + 1)th
month, the cost for operating (i + 1)th month should be equal to M + Si+1 . This can easily
represented if we add an edge from vi,N Y to vi+1,SF with cost equal to M + Si+1 . Similarly, from
SF nodes to NY nodes. Finally, our graph will look like the following:

Some edges are omitted, not to make the figure too complicated (and my apology for using
mspaint as it was the best tool available for me at the time of writing).

4.2.2

Comments for Section 3.2

It is important to mention that our construction of a graph, given an input instance of the
business problem, runs in polynomial time (this sounds trivial, but it is important that you
mention [and prove] this.
We run polynomial time shortest path finding algorithm once (so it runs in polynomial time
overall); it is trivial in this particular problem, but in some cases, you might find an algorithm
that solves a given problem by running other (trivial) polynomial time algorithm many times
and the number of times you use the other algorithm might be non-polynomial - this will be
covered later in class, so do not worry too much about this now.
I used Dijkstra as a subroutine in my solution, but we could have used Bellman-Ford instead. If
we use Bellman-Ford, it would be O(n + (|V | + |E|)) (in the case of our directed acyclic graph),
which is O(n) as |E| = O(n); in the case of Bellman-Ford, it is acceptable if you say your
algorithm runs in O(|V ||E|) = O(n2 ) time (ignoring the fact that our graph is acyclic, so the
actual running time is much less) as we are not looking for tightest bound here.
4.2.3

Comments for Section 3.3

Even if the reduction above looks trivial to you, you need to provide a proof to deserve a full mark.
Usually, proving correctness of reduction consists of two ways (as shown below); sometimes, one
direction is much easier than the other, and sometimes proving two ways at the same time is
easy. I chose to prove two directions separately, to show how your proof should look like.
Can We Shorten the Proof ?
Actually, we could have shortened our proof by combining the two claims (as you noticed, I even
copy and pasted more than half of what I wrote for the proof of Claim 2). One way to prove it at
one shot is to show a one-to-one correspondence between a plan of operating the business and a
path in the graph. That is, we show that there is a one-to-one correspondence between any path
P from start to end and for any assignment of where we run the business out of. To give you an
idea, there are precisely 2n different paths in our graph from start to end, and it is obvious that
there are 2n assignments of offices to months (as we have 2 choices for each month and they are
independent). If this sounds easier (sometimes it is easier, sometimes not), you could do this,
and you are basically proving P Q instead of showing P Q and also P Q. But keep it
in mind that sometimes proving equivalence directly might not be too easy.

Questions, Typos, Errors, etc.

If you have any questions, found typos or errors, etc., please contact me at hl364[at]cornell[dot]edu.

You might also like