Least number of rides - algorithm

I'm trying to solve this problem using an algorithm for at least a week but to no avail. I have a set of roads (1,2,3,...) and for each road there can be at least 1 vehicle that can pass (A,B,C,...). My problem is how to get the least number of rides for one to take to reach one road to another. For example:
road | vehicle(s)
1 | A,B
2 | A,B,C
3 | C,D
4 | C,D
5 | D,E
The output should be:
from 1, ride A or B to 2
from 2, ride C to 4
from 4, ride D to 5
The policy here is to exhaust one ride as much as possible, but the output should have the least number of ride changes.
Example 2:
road | vehicle(s)
1 | A,B
2 | A,B,C
3 | C,D
4 | C,D
5 | A,E
6 | E,F
7 | F
8 | F,H
9 | F,G
10 | F,G
11 | F
12 | F,G
13 | G,H
14 | H
Output:
from 1, ride A to 5
from 5, ride E to 6
from 6, ride F to 8
from 8, ride H to 14
Please help me to write the algorithm for the problem. I need to solve this for my project. Thanks!
PS: If you need other examples or clarification, just tell me in the comments below.

One way to think about this problem is to model it as a graph search problem. For each of the different vehicles v, construct a graph Gv whose nodes are all of the roads in the network with arcs between the nodes that are connected by vehicle v. For example, in your first example, the graph GA would have five nodes, of which there is only a connection from node 1 to node 2, while the graph GC would have five nodes with edges from 2 to 3, 3 to 4, and 4 to 2.
Now, consider the final graph G constructed as follows. G is formed by taking all of the graphs Gv for all of the vehicles v (meaning that there are multiple copies of each node in the original graph), then adding edges between corresponding nodes in the different graphs if there are multiple different vehicles that all reach a road. For example, in the graph G for the original problem, you would have G contain subgraphs GA and GB, ..., GE. Since road 1 is serviced by both vehicles A and B, you would add an edge between the nodes for road 1 in the graphs GA and GB, and since road 2 is serviced by vehicles A, B, and C, there would be edges connecting all of the road 2 nodes for subgraphs GA, GB, and GC.
You are interested in minimizing the number of transfers you need to make, and so we'd like to set up some costs in this graph that measure that. In particular, we say that any edge contained completely in one of the subgraphs Gv has cost zero, since once you're on a vehicle of a given type you don't need to make any changes to move around the roads the vehicle services. However, we assign a cost of one to each of the edges linking the subgraphs for different vehicles, since following this sort of edge would mean that you're changing which vehicle you're using. If you now trace out any path in this graph, the total cost of that path is the number of vehicle changes you make.
To finalize the construction, we need to have some way of finding a cost from the starting road to the destination. To do this, we'll add two new nodes s and t to the graph representing the start and end of the journey. Node s will have cost-zero directed edges to the first road of each of the subgraphs, since when you start off the journey you can pick any of the vehicles as your first step. Similarly, every subgraph's node for the final road will have a zero-cost edge to t, since once you arrive at the destination road it doesn't matter what vehicle you're in.
In this setup, any path from s to t has a cost equal to the total number of transfers you need to make. Finding the shortest path in this graph from s to t therefore gives you both the route to take and the cost of that path. You can solve this using Dijkstra's algorithm, for example.
The runtime of this algorithm isn't stellar, but it's still polynomial time. Suppose that there are n roads and m different vehicles. The graph we create will have m different subgraphs in it, each of which is for one vehicle, and in the worst case these graphs have O(n2) edges in them. If we then link together all the corresponding nodes of these subgraphs where you can change lines, then in the worst case there will be O((mn)2) such edges, since there are m graphs of n nodes that all might be connected to one another. We thus have a graph with O(mn) nodes and O((mn)2) edges, so we can run Dijkstra's algorithm in O((mn)2 + mn log mn) time.
The main idea that I think is important to take away from this problem is that you can often solve problems about finding paths in graphs subject to certain constraints by creating a new graph formed out of multiple copies of the old graph and then coming up with a good edge-cost function for that graph.
Hope this helps!

Related

Minimum Hop Count in Directed Graph based on Conditional Statement

A directed graph G is given with Vertices V and Edges E, representing train stations and unidirectional train routes respectively.
Trains of different train numbers move in between pairs of Vertices in a single direction.
Vertices of G are connected with one another through trains with allotted train numbers.
A hop is defined when a passenger needs to shift trains while moving through the graph. The passenger needs to shift trains only if the train-number changes.
Given two Vertices V1 and V2, how would one go about calculating the minimum number of hops needed to reach V2 starting from V1?
In the above example, the minimum number of hops between Vertices 0 and 3 is 1.
There are two paths from 0 to 3, these are
0 -> 1 -> 2 -> 7-> 3
Hop Count 4
Hop Count is 4 as the passenger has to shift from Train A to B then C and B again.
and
0 -> 5 -> 6 -> 8 -> 7 -> 3
Hop Count 1
Hop Count is 1 as the passenger needs only one train route, B to get from Vertices 0 to 3
Thus the minimum hop count is 1.
Input Examples
Input Graph Creation
Input To be solved
Output Example
Output - Solved with Hop Counts
0 in the Hop Count column implies that the destination can't be reached
Assuming number of different trainIDs is relatively small (like 4 in your example), then I suggest using layered graph approach.
Let number of vertices be N, number of edges M, and number of different trainIDs K.
Let's divide our graph to K graphs. (graphA, graphB, ...)
graphA contains only edges labeled with A, and so on.
Weight of each edge in each of the graphs is 0.
Now create edges between these graphs.
Edge between graphs is representing a 'hop'
grapha[i] connects to graphB[i], graphC[i], ...
Each of these edges has weight 1.
Now for every graph run Dijkstra's shortest path algorithm from V1 in that graph, and read results from V2 in all graphs, take minimal value.
This way minimum of results for running dijkstra's for every graph will be your minimum number of hops.
Memory complexity is O(K*(N+M))
And time complexity is O(K*(((2^K)*N+M)*log(KV)))
(2^K)*N comes from fact that for every 1<=i<=N, vertices graphA[i],graphB[i],... must be connected to each other, and this gives 2^K connections for every i, and (2^K)*N connections in total.
For cases where K is relatively small, like 4 in your example, but N and M are quite big, this algorithm works like a charm. It isn't suitable for situation where K is big though.
I'm not sure if that's clear. Tell me if you need more detailed explanation.
EDIT:
Hope this makes my algorithm more clear.
Black edges have weight 0, and red edges have weight 1.
By using layered graph approach, we translated our special graph into plain weighted graph, so we can just run Dijkstra's algorithm on it.
Sorry for ugly image.
EDIT:
Since max K = 10, we would like to remove 2^K from our time complexity. I believe this can be done by making edges that represent possible hops virtual, instead of physically storing them on adjacency list.

Is there a type-o in this HackerRank challenge?

I've spending many hours on this HackerRank problem and I'm confused about what the prompt means. It says
You are given a tree (a simple connected graph with no cycles). The
tree has nodes numbered from to N.
Find the maximum number of edges you can remove from the tree to get a forest such that each connected component of the forest contains
an even number of vertices.
https://www.hackerrank.com/challenges/even-tree
and it has a graph that displays an example.
I'm confused about why it says
Find the maximum number of edges
Doesn't it mean minimum?
Because if I've trying to maximize the number of edges to remove from
1
/ | \
3 6 2
/ | / \
4 8 7 5
/ \
9 10
to make it into forests of all even counts then I would keep severing it from the top until I'm at
8
/
9
which is a single forest with an even count.
What the heck am I missing about this? Can someone help clarify?
Find the maximum number of edges you can remove from the tree to get a forest such that each connected component of the forest contains an even number of vertices
Note that when you remove an edge from tree, you increase number of connected components by one.
So if you remove m edges, number of connected component of the forest is m+1
This question now asks you to find maximum such m such that all the connected component will have even number of vertices.
If it had been minimum number of edges, answer would have been trivial (0), i.e don't remove any edge!
Hint
For solving this, for each vertex v, maintain count of vertices in subtree rooted at v. If this is even, then you can make it as different connected component.

How to find the optimal grid placement for least distance between nodes of a network?

If I wanted to display the nodes of a network on a 2D grid, but also I wanted to ensure the least amount of manhattan distance between any two directly connected nodes (where there is a maximum of one node per cell), what is the algorithm to do this?
To clarify, let me provide an elementary example:
A network has the following topology:
A -> B -> C
One solution of the grid placement would simply be to list the 3 items next to each other:
| A | B | C |
The distance between any two connecting nodes is 1 cell.
Suppose another network has the following topology:
A -> B -> C -> D -> A
One solution of the place for this network would be:
| A | B |
| D | C |
The distance between A and B, B and C, C and D, and D and A are each 1 cell. B and D, and A and C are not directly connected, therefore their distances do not factor into the problem.
The most optimal arrangement would be the one that provides the lowest sum distance between all directly connected nodes.
Now, how would one do this for an arbitrary network? Any help would certainly be appreciated. :)
A divide and conquer approach may bear some fruit. Consider the following algorithm:
if the cardinality of the graph is less than 10:
1) Create a 3x3 grid. Place this node of this piece of the graph on the grid in such a way that minimizes distance.
2) Return the 3x3 grid
else
1) Split the graph into two sets of nodes, recurse on each. Each recursion returns a graph of the optimal way to lay out that subset of the graph as a grid. Ideally you would find the minimum bisection for this split, but that problem is NP-hard, so perhaps an approximation?
2) Union the two subgraphs by creating a single grid with the returns of the two recursive calls next to one another. You can rotate the return of a recursive call by 90 degrees without changing it's distance sum, so there are 16 (4 orientations per) ways to union two grids. Large, but thankfully constant. Return the unioned grid that minimizes the total distance.
Clearly the factor that breaks this algorithm are the connections that span the subgrids. The rotation process only partially fixes this.
If you know your graph is planar, there's probably a way to do this optimally. Otherwise, you may be stuck with an approximation as your best solution, as for any given node with out degree > 4 you'll have to pick at least one neighbor to put at distance >= 2.
Another thing to consider is how to do the inner most step of putting <= 9 nodes on a 3x3 grid optimally. The problem is that there are probably many equally optimal ways to put the nodes on the grid in terms of the subgrid's cost, but you also want to make sure that nodes with related out-going edges (edges going out of this sub problem) are on the same side of the grid.

Count Minimum number of warehouses

Given V vertices(Towns) and E edges(Routes between towns) . A company decides to build warehouses to ensure that for any town X, there will be a warehouse located either in X or in an immediately neighboring town of X.
How to find the minimum number of warehouses the company has to build.
Example: Let V=10 and E = 7 and edge pairs are :
1 2
2 4
2 5
3 6
8 6
9 7
10 7
Here answer will be 3 as its sufficient to built warehouses at Town numbers 2,6,9.
My approach:
I first count the degree of each city and then placed a warehouse in the city with maximum degree. I then marked all the adjacent cities as visited and then moved onto the next un-visited maximum node and placed a warehouse their. I did so until no un-visited is left.
Is my approach correct? Please help me on this.
All you need to do is to form a graph where:
The vertices are the towns
An edge exists between two vertices iff there is a direct route between the corresponding towns.
Then find the minimal dominating set for this graph. You should build a warehouse in each town corresponding to the vertices in the minimal dominating set.
Unfortunately, the dominating set problem is NP-complete so finding the exact minimum is hard, but your greedy algorithm should give a good approximation.

Using disjoint-set data structure, graph theory

I'm practicing solving programming problems in free time. This problem I spotted some time ago and still don't know how to solve it:
For a given undirected graph with n vertices and m edges (both less than 2 × 106)
I need to split its vertices into as many groups as possible, but with one
condition: each pair of vertices from different groups are connected by edge.
Each vertex is in exactly one group. At the end I need to know the size of
each group.
I was proud when I came up with this solution: consider complemented graph of the original graph and use Disjoint-set data structure for it. It gives us the right answer (not difficult to prove). But it's only theoretical solution. With given constraints it's very very bad, not optimal. But I believe this approach can be somehow smartly fixed. But how?
Can anyone help?
EDIT: for a graph with vertices from 1 to 7 and 16 edges:
1 3
1 4
1 5
2 3
3 4
4 5
4 7
4 6
5 6
6 7
2 4
2 7
2 5
3 5
3 7
1 7
we have 3 groups with sizes: 1, 2 and 4.
These groups are: {4}, {5,7}, {1,2,3,6} respectively. There are edges connecting each pair of vertices from different groups and we can't create more groups.
I think the only ingredient you're missing is how to deal with sparse graphs.
Let's think about this in terms of finding the biggest possible complete graph where the only operation I can do is group a set of nodes (say v_1, ..., v_k) together and give the new supernode edges only to those nodes u that were connected to all of v_1, ..., v_k.
If your graph has fewer than n^2/4 edges, randomly sample n node pairs, noting which pairs are not joined by an edge. Union-find is an easy way to code this up. Now rebuild the graph using as groups the sets you found by this random sampling. Recurse on this reduced graph. (I'm not quite sure how to analyse this step, but I believe each sample-rebuild cycle reduces the graph size by at least a constant factor with high probability, so this whole process takes near-linear time.)
Once you have a fairly dense graph (at least n^2/4 edges), you can convert to an adjacency matrix representation and do exactly what you were suggesting --- check all node pairs, do a union whenever you see that two nodes aren't joined by an edge, and read off the sets.

Resources