Minimum cost to visit museum - algorithm

I recently went for an hiring challenge and saw this question :
Given map of N museums with given entry fees and M weighted bidirectional roads connecting them. Starting from each museum, we need to find minimum cost to visit at least one museum. The cost will be an addition of sum of weights of roads travelled and visited museum entry fee.
Input format :
Number of museums N and number of roads M
Entry fees of each museum
Next M lines will have x, y, z where museum x and museum y are connected by road with weight z
Output Format :
N integers where ith integer denotes minimum cost to reach and enter any museum starting from ith museum.
Input :
5 4
1 2 3 1 5
1 2 1
2 3 1
3 4 1
4 5 1
Output :
1 2 2 1 2
Here, starting from museum 1, we can directly visit museum 1 with entry fee of 1.
Starting from museum 3, we can visit museum 4 with cost of 2.
I need optimized approach efficient than applying dijsktra from each node of graph. Constraints are high enogh to avoid floyd warshall algorithm.
Thanks in advance.

Your graph starts off with nodes of "outside Museum X" and edges roads between them.
You need a priority queue of entries that look like this:
{
cost: xxx,
outside_museum: xxx
}
You initialize it with entries that look like this:
{
cost: entry_fee_for_museum_x,
outside_museum: x
}
Keep a dictionary mapping museum to lowest cost named something like cost_to_museum.
And now your loop looks like this:
while queue not empty:
get lowest cost item from queue
if it's museum is not in cost_to_museum:
cost_to_museum[item.outside_museum] = item.cost
for each road connecting to museum:
add to queue an entry for traveling to here from there
(That is, location is the other museum, cost is road + current cost)
This should execute in time O((n+m) log(n+m)) where n is the number of museums and m is the number of roads.

Related

How to find an algorithm to find a point in a row that has a lower distance with others?

Imagine that we have n city in one row with the same distance and each of them has a population, we want to build a post office, and we want to choose a city that most people have to take a less route to that office, how to find the city?
The user should input the cities number(n) and their population and got the city that the post office should be built.
This is the example that was in the problem and I don't know why it has this result:
6 (number of cities (n))
3 1 0 0 2 2 (populations) ----> 2 (the city number 2 that have a 1 population)
The thing that I'm looking for is an algorithm or a formula to find the city, not the code. Any idea?
If you work out your example, you'll see a simple pattern. Let's say the total distance for index i is x. If we move to index i+1,
All cities in range [0, i] will now become further away from the post office by 1 unit.
All cities in range [i+1, n] will now become closer to the post office by 1 unit.
Using the example you have provided (assuming 0 based indexing):
Let the office be at index 1. Current total distance: 3 + (2*3) + (2*4) = 17
Let's shift it to index 2. Increase in distance for the cities on left of index 2 = 3+1=4. Decrease in distance for cities on the right = 2+2=4.
Simply put, if we move from index i to i+1,
new_distance = old_distance + sum(array[j] for j in range [0,i]) - sum(array[j] for j in range [i+1,n])
To make it more efficient, sum(array[j] for j in range [0,i]) is nothing but prefix sum. You can calculate that in one pass, then solve the distances for each city in another pass. That O(N) time and space complexity.

Minimal car refills on a graph of cities

There's a graph of cities.
n - cities count
m - two-ways roads count
k - distance that car can go after refill
Road i connects cities pi and qi and has length of ri. Between the two cities can be only one road.
A man is going from city u to city v.
There are a gas stations in l cities a1, a2, ..., al.
A car starts with a full tank. If a man gets in a city with a gas station, he can refill (full tank) a car or ignore it.
Return value is a minimal count of refills to get from a city u to city v or -1 if it's impossible.
I tried to do it using Dijkstra algorithm, so I have minimal distance and path. But I have no idea how to get minimal refills count
It is slightly subtle, but the following pseudo-code will do it.
First do a breadth-first search from v to find the distance from every city to the target. This gives us a distance_remaining lookup with distance_remaining[city] being the shortest path (without regards to fillup stations).
To implement we first need a Visit data structure with information about visiting a city on a trip. What fields do we need?
city
fillups
range
last_visit
Next we need a priority queue (just like Dijkstraa) for possible visits to consider. This queue should prioritize visits by the shortest possible overall trip that we might be able to take. Which is to say visit.fillups * max_range + (max_range - visit.range) + distance_remaining[visit.city].
And finally we need a visited[city] data structure saying whether a city is visited. In Dijkstra we only consider a node if it was not yet visited. We need to tweak that to only consider a node if it was not yet visited or was visited with a range shorter than our current one (a car that arrived on full may finish even though the empty one failed).
And now we implement the following logic:
make visit {city: u, fillups: 0, range: max_range, last_visit: None}
add to priority queue the visit we just created
while v = queue.pop():
if v.city == u:
return v.fillups # We could actually find the path at this point!
else if v not in visited or visited[v.city] < v.range:
for each road r from v.city:
if r.length < v.range:
add to queue {city: r.other_city, fillups: v.fillups, range:v.range - r.length, last_visit: v}
if v.city has fillup station:
add to queue {city: v.city, fillups: fillups + 1, range: max_range, last_visit: v}
return -1

Towers of Hanoi - Bellman equation solution

I have to implement an algorithm that solves the Towers of Hanoi game for k pods and d rings in a limited number of moves (let's say 4 pods, 10 rings, 50 moves for example) using Bellman dynamic programming equation (if the problem is solvable of course).
Now, I understand the logic behind the equation:
where V^T is the objective function at time T, a^0 is the action at time 0, x^0 is the starting configuration, H_0 is cumulative gain f(x^0, a^0)=x^1.
The cardinality of the state space is $k^d$ and I get that a good representation for a state is a number in base k: d digits that can go from 0 to k-1. Each digit represents a ring and the digit can go from 0 to k-1, that are the labels of the k rings.
I want to minimize the number of moves for going from the initial configuration (10 rings on the first pod) to the end one (10 rings on the last pod).
What I don't get is: how do I write my objective function?
The first you need to do is choose a reward function H_t(s,a) which will define you goal. Once this function is chosen, the (optimal) value function is defined and all you have to do is compute it.
The idea of dynamic programming for the Bellman equation is that you should compute V_t(s) bottom-up: you start with t=T, then t=T-1 and so on until t=0.
The initial case is simply given by:
V_T(s) = 0, ∀s
You can compute V_{T-1}(x) ∀x from V_T:
V_{T-1}(x) = max_a [ H_{T-1}(x,a) ]
Then you can compute V_{T-2}(x) ∀s from V_{T-1}:
V_{T-2}(x) = max_a [ H_{T-2}(x,a) + V_{T-1}(f(x,a)) ]
And you keep on computing V_{t-1}(x) ∀s from V_{t}:
V_{t-1}(x) = max_a [ H_{t-1}(x,a) + V_{t}(f(x,a)) ]
until you reach V_0.
Which gives the algorithm:
forall x:
V[T](x) ← 0
for t from T-1 to 0:
forall x:
V[t](x) ← max_a { H[t](x,a) + V[t-1](f(x,a)) }
What actually was requested was this:
def k_hanoi(npods,nrings):
if nrings == 1 and npods > 1: #one remaining ring: just one move
return 1
if npods == 3:
return 2**nrings - 1 #optimal solution with 3 pods take 2^d -1 moves
if npods > 3 and nrings > 0:
sol = []
for pivot in xrange(1, nrings): #loop on all possible pivots
sol.append(2*k_hanoi(npods, pivot)+k_hanoi(npods-1, nrings-pivot))
return min(sol) #minimization on pivot
k = 4
d = 10
print k_hanoi(k, d)
I think it is the Frame algorithm, with optimization on the pivot chosen to divide the disks in two subgroups. I also think someone demonstrated this is optimal for 4 pegs (in 2014 or something like that? Not sure btw) and conjectured to be optimal for more than 4 pegs. The limitation on the number of moves can be implemented easily.
The value function in this case was the number of steps needed to go from the initial configuration to the ending one and it needed be minimized. Thank you all for the contribution.

Maximize the score of circular arrangement of numbers

I am looking for an efficient algorithm to solve a problem of arranging a circular set of numbers between 1-12 to get the highest score.
The score of an arrangement is given by the sum of the score of all its adjacent pairs
To get the score of an adjacent pair (a,b), the following steps are calculated:
1. Find x such that (a+x) mod 12 = b
2. Look up x in a score table
3. The value in the score table at index 'x' is the score of the pair (a,b).
This is repeated for every adjacent pair and the sum is the score of the arrangement.
Here is an example:
Suppose the score table is [5,4,6,7,2,7,-2,-6,-8,-2,6,12,13]
Consider these numbers: 5, 12, 8, 9
For each adjacent pairs,
the values for x are: 5 -> 12: 7
12 -> 8: 8
8 -> 9: 1
9 -> 5: 8
The values for score[x] are:
score[7] = -6
score[8] = -8
score[1] = 4
score[8] = -6
The sum of the score[x] values is: (-6) + (-8) + (4) + (-6)
= -18
The goal is to come up with an algorithm to efficiently arrange the numbers to maximize the score, given the numbers themselves - up to twenty of them between 1 and 12 - and the score table.
Many thanks,
You can solve this problem with an exact TSP solver.
Imagine there's a set of cities, each which has a "value". We'll say that the value of a city x is V(x). Now imagine that to travel from city x to y it costs S(V(y) - v(X) (mod 12)). Note that S is your score table and V(y) - V(x) (mod 12) is the value to be looked up in the score table.
The goal of TSP is to find what order you should visit all the cities exactly once to optimize your cost -- in this case, you want to maximize your cost. (Alternatively, you could just make your scoring function negative and minimize your cost.)
That is, TSP will give you a permutation of the set of cities that optimize your score. Since your cities are actually the values you're interesting in permuting, it will give you a permutation of your values that produces an optimal score.
So.. Find a program or library that allows you to specify how much it costs to fly from city x to city y and then let it run and it'll give you the optimal permutation of your cities -- then you can replace the city IDs with the value (V(id)) to get the optimal solution you were looking for.
You could write your own TSP solver as well -- branch & bound techniques look popular.

Algorithm: find connections between towns with a limit of train changes

What algorithm would you use to create an application that given appropriate data (list of cities, train routes, train stations) is capable of returning a list of connection between any two user-selected cities? The application has to choose only those connections that fall into the limit of accepted train-changes.
Example: I ask the application which train to take if I need to travel from Paris to Moscow with max. 1 stop/switch - the application returns a route: Train 1 (Paris-Berlin) -> Train 2 (Berlin->Moscow) (No direct connection exists).
Graphical example
http://i.imgur.com/KEJ3I.png
If I ask the system about possible connections from Town A to Town G I get a response:
Brown Line (0 switches = direct)
Brown Line to Town B / Orange Line to Town G (1 switch)
Brown Line to Town B / Orange Line to Town D / Red Line to G (2 switch)
... all other possibilities
And thouh the 2nd and 3rd options are shorter than the 1st, it's the 1st that should have priority (since no train-switching is involved).
Assuming the only thing important is "number of stops/switches", then the problem is actually finding a shortest path in an unweighted directed graph.
The graph model is G = (V,E) where V = {all possible stations} and E = { (u,v) | there is a train/route from station u to station v }
Note: let's say you have a train which starts at a_0, and paths through a_1, a_2,...a_n: then E will contain: (a_0,a_1),(a_0,a_2),..,(a_0,a_n) and also (a_1,a_2),(a_1,a_3),... formally: for each i < j : (a_i,a_j) &in; E.
BFS solves this problem, and is both complete [always finds a solution if there is one] and optimal [finds the shortest path].
If the edges [routes] are weighted, something like dijkstra's algorithm will be needed instead.
If you want a list of all possible routes, Iterative-Deepening DFS could be used, without maintaining a visited set, and print all the paths found to the target up to the relevant depth. [BFS fails to return all paths with the counter example of a clique]
I think you need to compute all pairs shortest paths. Check http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm.

Resources