167 lines
5.2 KiB
Plaintext
167 lines
5.2 KiB
Plaintext
CS 325, Algorithms, Fall 2019
|
|
HW9 - Graphs (part 2), DP (part 4)
|
|
|
|
Due Monday Nov 25, 11:59pm.
|
|
No late submission will be accepted.
|
|
|
|
Include in your submission: report.txt, dijkstra.py, nbest.py.
|
|
dijkstra.py will be graded for correctness (1%).
|
|
|
|
Textbooks for References:
|
|
[1] CLRS Ch. 22 (graph)
|
|
[2] my DP tutorial (up to page 16):
|
|
http://web.engr.oregonstate.edu/~huanlian/slides/COLING-tutorial-anim.pdf
|
|
[3] DPV Ch. 3, 4.2, 4.4, 4.7, 6 (Dasgupta, Papadimitriou, Vazirani)
|
|
https://www.cs.berkeley.edu/~vazirani/algorithms/chap3.pdf
|
|
https://www.cs.berkeley.edu/~vazirani/algorithms/chap4.pdf
|
|
https://www.cs.berkeley.edu/~vazirani/algorithms/chap6.pdf
|
|
[4] KT Ch. 6 (DP)
|
|
http://www.aw-bc.com/info/kleinberg/assets/downloads/ch6.pdf
|
|
[5] KT slides: Greedy II (Dijkstra)
|
|
http://www.cs.princeton.edu/~wayne/kleinberg-tardos/
|
|
|
|
***Please answer time/space complexities for each problem in report.txt.
|
|
|
|
1. [WILL BE GRADED]
|
|
Dijkstra (see CLRS 24.3 and DPV 4.4)
|
|
|
|
Given an undirected graph, find the shortest path from source (node 0)
|
|
to target (node n-1).
|
|
|
|
Edge weights are guaranteed to be non-negative, since Dijkstra doesn't work
|
|
with negative weights, e.g.
|
|
|
|
3
|
|
0 ------ 1
|
|
\ /
|
|
2 \ / -2
|
|
\/
|
|
2
|
|
|
|
in this example, Dijkstra would return length 2 (path 0-2),
|
|
but path 0-1-2 is better (length 1).
|
|
|
|
For example (return a pair of shortest-distance and shortest-path):
|
|
|
|
1
|
|
0 ------ 1
|
|
\ / \
|
|
5 \ /1 \6
|
|
\/ 2 \
|
|
2 ------ 3
|
|
|
|
>>> shortest(4, [(0,1,1), (0,2,5), (1,2,1), (2,3,2), (1,3,6)])
|
|
(4, [0,1,2,3])
|
|
|
|
If the target node (n-1) is unreachable from the source (0),
|
|
return None:
|
|
|
|
>>> shortest(5, [(0,1,1), (0,2,5), (1,2,1), (2,3,2), (1,3,6)])
|
|
None
|
|
|
|
Another example:
|
|
|
|
1 1
|
|
0-----1 2-----3
|
|
|
|
>>> shortest(4, [(0,1,1), (2,3,1)])
|
|
None
|
|
|
|
Tiebreaking: arbitrary. Any shortest path would do.
|
|
|
|
Filename: dijkstra.py
|
|
|
|
Hint: please use heapdict from here:
|
|
https://raw.githubusercontent.com/DanielStutzbach/heapdict/master/heapdict.py
|
|
|
|
>>> from heapdict import heapdict
|
|
>>> h = heapdict()
|
|
>>> h['a'] = 3
|
|
>>> h['b'] = 1
|
|
>>> h.peekitem()
|
|
('b', 1)
|
|
>>> h['a'] = 0
|
|
>>> h.peekitem()
|
|
('a', 0)
|
|
>>> h.popitem()
|
|
('a', 0)
|
|
>>> len(h)
|
|
1
|
|
>>> 'a' in h
|
|
False
|
|
>>> 'b' in h
|
|
True
|
|
|
|
You don't need to submit heapdict.py; we have it in our grader.
|
|
|
|
|
|
2. [Redo the nbest question from Midterm, preparing for HW10 part 3]
|
|
|
|
Given k pairs of lists A_i and B_i (0 <= i < k), each with n sorted numbers,
|
|
find the n smallest pairs in all the (k n^2) pairs.
|
|
We say (x,y) < (x', y') if and only if x+y < x'+y'.
|
|
Tie-breaking: lexicographical (i.e., prefer smaller x).
|
|
|
|
You can base your code on the skeleton from the Midterm:
|
|
|
|
from heapq import heappush, heappop
|
|
def nbest(ABs): # no need to pass in k or n
|
|
k = len(ABs)
|
|
n = len(ABs[0][0])
|
|
def trypush(i, p, q): # push pair (A_i,p, B_i,q) if possible
|
|
A, B = ABs[i] # A_i, B_i
|
|
if p < n and q < n and ______________________________:
|
|
heappush(h, (________________, i, p, q, (A[p],B[q])))
|
|
used.add((i, p, q))
|
|
h, used = ___________________ # initialize
|
|
for i in range(k): # NEED TO OPTIMIZE
|
|
trypush(______________)
|
|
for _ in range(n):
|
|
_, i, p, q, pair = ________________
|
|
yield pair # return the next pair (in a lazy list)
|
|
_______________________
|
|
_______________________
|
|
|
|
|
|
But recall we had two optimizations to speed up the first for-loop (queue initialization):
|
|
|
|
(1) using heapify instead of k initial pushes. You need to implement this (very easy).
|
|
|
|
(2) using qselect to choose top n out of the k bests. This one is OPTIONAL.
|
|
|
|
Analyze the time complexity for the version you implemented.
|
|
|
|
>>> list(nbest([([1,2,4], [2,3,5]), ([0,2,4], [3,4,5])]))
|
|
|
|
[(0, 3), (1, 2), (0, 4)]
|
|
|
|
>>> list(nbest([([-1,2],[1,4]), ([0,2],[3,4]), ([0,1],[4,6]), ([-1,2],[1,5])]))
|
|
[(-1, 1), (-1, 1)]
|
|
|
|
>>> list(nbest([([5,6,10,14],[3,5,10,14]),([2,7,9,11],[3,8,12,16]),([1,3,8,10],[5,9,10,11]),([1,2,3,5],[3,4,9,10]),([4,5,9,10],[2,4,6,11]),([4,6,10,13],[2,3,5,9]),([3,7,10,12],[1,2,5,10]),([5,9,14,15],[4,8,13,14])]))
|
|
|
|
[(1, 3), (3, 1), (1, 4), (2, 3)]
|
|
|
|
>>> list(nbest([([1,6,8,13],[5,8,11,12]),([1,2,3,5],[5,9,11,13]),([3,5,7,10],[4,6,7,11]),([1,4,7,8],[4,9,11,15]),([4,8,10,13],[4,6,10,11]),([4,8,12,15],[5,10,11,13]),([2,3,4,8],[4,7,11,15]),([4,5,10,15],[5,6,7,8])]))
|
|
|
|
[(1, 4), (1, 5), (1, 5), (2, 4)]
|
|
|
|
This problem prepares you for the hardest question in HW10 (part 3).
|
|
|
|
Filename: nbest.py
|
|
|
|
|
|
|
|
Debriefing (required!): --------------------------
|
|
|
|
0. What's your name?
|
|
1. Approximately how many hours did you spend on this assignment?
|
|
2. Would you rate it as easy, moderate, or difficult?
|
|
3. Did you work on it mostly alone, or mostly with other people?
|
|
4. How deeply do you feel you understand the material it covers (0%-100%)?
|
|
5. Any other comments?
|
|
|
|
This section is intended to help us calibrate the homework assignments.
|
|
Your answers to this section will *not* affect your grade; however, skipping it
|
|
will certainly do.
|