The question is originated from Hackerrank.
Suppose there are
1 to N
stores in a city which are connected by bidirectional roads associated with traveling times. Each store sells some types of fishes (0 <= type_of_fish_store_i < K
), in totalK
types of fishes are selling in the city. A cat starts at store1
and traveling along some path puchases fishes at each store on the path.Calculate minimum time that satisfies the constraints
- the cat has to end at a specified store
X
- the cat has to end with specified types of fishes in the basket
Note: a store including the final destination can be visited more than once
Shop and fish types selling at that shop (
{shop:fish_type}
):{1: {1}, 2: {2}, 3: {3}, 4: {4}, 5: {5}}
Adjacency matrix with cells filled with time cost (referring to
cost_matrix
):[[0, 10, 10, 0, 0], [10, 0, 0, 10, 0], [10, 0, 0, 0, 10], [0, 10, 0, 0, 10], [0, 0, 10, 10, 0]]
Approach I've implemented:
def dijkstra(cost_matrix, start, wanted, end):
"""
:param cost_matrix: adjacency matrix filled with time costs
:param start: the store where the cat starts at
:param wanted: types of fishes the cat wants at the end of journey
:param end: the store where the cat ends at
:return:
"""
fish_basket = shop_and_fish[start]
accum = 0
h =[]
visited = [start]
while not (wanted.issubset(fish_basket) and start == end):
for i, dist in enumerate(cost_matrix[start - 1]):
if dist > 0:
heapq.heappush(h, [ accum + dist, i + 1, fish_basket | shop_and_fish[i + 1], visited + [i + 1]])
# print("heap: ", h)
accum, start, fish_basket, visited = heapq.heappop(h)
print("Total time: ", accum, ", End store:", start, ", Fish types collected: ", fish_basket, ", Path: ", visited)
return accum
Execute:
dijkstra(cost_matrix, 1, {1,2,3,4,5}, 5)
# this is saying the final accepted state is the cat
# at 5th store with {1,2,3,4,5} types of fishes in hand
Returns
50
# Total time: 50 , End store: 5 , Fish types collected: {1, 2, 3, 4, 5} , Path: [1, 2, 4, 5, 3, 5]
Problem
Efficiency. Expanding unnecessary nodes such as [1,2,1,2,1,2]
, in some other cases [1,2,3,4,3,2,1,2,3,4..]
, maybe some other unforeseen patterns. Any thoughts on how to eliminate them? I've tried palindrome, but it seems to add a lot of complexity as it examines every path and every subpath of that path. Moreover, if you've identified any other improvements, feel free to add to answer.