Graph road complexity - java

I need to make an algorithm that verifies if there is a road from the node x to the node y in a graph. The edges in the graph have a series of rights attached to them (like r, w, e, etc.). My algorithm need to have |e| + |v| complexity. I can only go through nodes whose edge with the node before them has a certain set of rights given as a parameter.
For example, if I have a set of rights: r, w, e, g and I distribute these rights randomly on the edges, and I give as a parameter for my search method the set of rights: e, g, I can only go through nodes whose edges has the rights e,g.
How can I do this in |e| + |v| time complexity if DFS algorithm has is I recall correctly |e| + |v| time complexity and I also need to search if the edges have the desired set of rights, which I think adds to the complexity.

You need to apply breadth-first search (unlike DFS, it will find the shortest path) modifying it slightly to take into account only nodes which have the required rights.
Here is the pseudo-code, I'm sure you can translate it to Java:
procedure BFS(G,v):
create a queue Q
create a set V
enqueue v onto Q
add v to V
while Q is not empty:
t ‹ Q.dequeue()
if t is what we are looking for:
return t
for all edges e in G.adjacentEdges(t) do
u ‹ G.adjacentVertex(t,e)
if u is not in V and t.hasRights(allowedRights):
add u to V
enqueue u onto Q
return none
It differs from the one on Wikipedia only by checking the t.hasRights(allowedRights) condition.
Using Java HashSet, checking a set of rights can be easily done in O(1) time, adding nothing to E+V complexity of the BFS algorithm (assuming number of available rights is constant).
In each node you store a set of rights, and then check if all required rights are in the set (HashSet.contains(Object) is O(1)).
Also, you can represent your rights as enum and use EnumSet to store the right sets. EnumSet is implemented as bit vectors and so is as fast as you can get with sets.

Related

minimum edges needed to connect the given pairs

We are given the number of vertices of a directed unweighted graph and a list of pairs of vertices like (a, b) . We want to make the graph in a way that there will be a directed paths between two vertices of each given pair. The problem is to find minimum number of edges to satisfy the conditions. Note that for every pair like (a, b) we have the below conditions:
1- (a, b) is different from (b, a)
2- if (a, b) is in the given list, then there should be a directed path from a to b in graph. This path may be multiple hop.
here is my try: as I found that hard to find an algorithm to find edges should be in the graph, I decided to add an edge between two vertices of each given pair in the graph (i.e. if the pairs (a ,b) and (c, d) are given, I draw two edges. One from a to b and the other from c to d) and then delete the edges which removing them does not affect connectivity between vertices. However I still could not find a way to indicate these edges.
We are given the number of vertices of a directed unweighted graph
I will assume that this graph has some pre-existing edges to which you are going to add to and perhaps remove some. You do not say this, but the question makes no sense unless there are such pre-existing edges.
Here is the algorithm ( pseudo code )
ADD edges between given node pairs
FIND maximal cliques https://en.wikipedia.org/wiki/Clique_problem
LOOP over cliques
FIND minimum spanning tree in clique https://en.wikipedia.org/wiki/Minimum_spanning_tree
LOOP over edges in clique
IF edge is NOT in spanning tree
REMOVE edge

How to check if there exist a path running through all nodes in an adjacency list in Java

I recently created an unweighted bidirectional graph by using an adjacency list from a HashMap in Java. I have randomly created connections between nodes and now I am unsure of how to check if there's a single path that passes through every node once and exactly once.
What is the best way / algorithm to check if a path exists between all nodes?
//Sample
A -> B
B -> A -> C -> D
C -> B -> E
D -> B
E -> C -> G
F -> G
G -> E -> F
The sort of path you’re asking for is called a Hamiltonian path and unfortunately there are no known algorithms for this problem that run efficiently on all inputs (the problem is NP-complete). You could solve this problem by brute force (list all possible paths and see if any of them go through all the nodes once and exactly once). There’s also a famous O(n22n)-time dynamic programming algorithm for this problem as well.
You can use DFS or BFS algorithm to traverse the graph and check if each of the nodes is visited at least once.
If you only want to know whether the graph is connected or not then you can do the following:
Use BFS/DFS to map the graph starting from any of the nodes. Whenever you encounter a new node (including the first one) increase a counter by 1. This will give you the number of connected nodes to your starting node.
Compare that counter with the size of the map (number of keys). If the number of keys is greater than the number of nodes traversed then the graph is disconnected, if the number is equal then it is connected.
It's not really clear what your data structure is because you're talking about a HashMap, but showing something else. Generally, BFS/DFS run in O(|V| + |E|) (where |V| is the number of vertices and |E| is the number of edges), and size is O(1) for a HashMap.
If you want to know which nodes are not connected to your starting one, then
Store or mark all the nodes you traverse. This will give you all the nodes connected to the node from which you initiated the traversing.
Iterate over all the nodes and find those which are not contained in your previous step.
contains is also O(1) for a HashMap, though you would have to run it |V|-1 times.
There's a similar (more theory oriented) question on Computer Science: How to check whether a graph is connected in polynomial time?

Directed Acyclic Graph Traversal in Java Web Application

So I am building a web application where you can build a directed graph where a node will represent some operation and the edge will represent data flow between those operations. So for an edge {u,v} , u must run before v does. Click this link to see a sample graph
START node represents the initial value and the other nodes except the output does the operation as specified. Output node will output the value it receives as input.
Which algorithm approach should i use to process a graph like that ?
This is a perfect example of a topological sort. The most common algorithm for creating a set following the order requirements via traversing is Kahn's Algorithm. The pseudocode can be seen below and the information in the Wikipedia link should be enough to get you started.
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
add n to tail of L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)
Note the "starting node" will be enforced by properly representing the incoming edges in the graph. It will be the only node in S to start. Please let me know in the comments if you would like any other information.

Algorithm for minimal cost + maximum matching in a general graph

I've got a dataset consisting of nodes and edges.
The nodes respresent people and the edges represent their relations, which each has a cost that's been calculated using euclidean distance.
Now I wish to match these nodes together through their respective edges, where there is only one constraint:
Any node can only be matched with a single other node.
Now from this we know that I'm working in a general graph, where every node could theoretically be matched with any node in the dataset, as long as there is an edge between them.
What I wish to do, is find the solution with the maximum matches and the overall minimum cost.
Node A
Node B
Node C
Node D
- Edge 1:
Start: End Cost
Node A Node B 0.5
- Edge 2:
Start: End Cost
Node B Node C 1
- Edge 3:
Start: End Cost
Node C Node D 0.5
- Edge 2:
Start: End Cost
Node D Node A 1
The solution to this problem, would be the following:
Assign Edge 1 and Edge 3, as that is the maximum amount of matches ( in this case, there's obviously only 2 solutions, but there could be tons of branching edges to other nodes)
Edge 1 and Edge 3 is assigned, because it's the solution with maximum amount of matches and the minimum overall cost (1)
I've looked into quite a few algorithms including Hungarian, Blossom, Minimal-cost flow, but I'm uncertain which is the best for this case. Also there seems so be an awful lot of material to solving these kinds of problems in bipartial graph's, which isn't really the case in this matter.
So I ask you:
Which algorithm would be the best in this scenario to return the (a) maximum amount of matches and (b) with the lowest overall cost.
Do you know of any good material (maybe some easy-to-understand pseudocode), for your recomended algorithm? I'm not the strongest in mathematical notation.
For (a), the most suitable algorithm (there are theoretically faster ones, but they're more difficult to understand) would be Edmonds' Blossom algorithm. Unfortunately it is quite complicated, but I'll try to explain the basis as best I can.
The basic idea is to take a matching, and continually improve it (increase the number of matched nodes) by making some local changes. The key concept is an alternating path: a path from an unmatched node to another unmatched node, with the property that the edges alternate between being in the matching, and being outside it.
If you have an alternating path, then you can increase the size of the matching by one by flipping the state (whether or not they are in the matching) of the edges in the alternating path.
If there exists an alternating path, then the matching is not maximum (since the path gives you a way to increase the size of the matching) and conversely, you can show that if there is no alternating path, then the matching is maximum. So, to find a maximum matching, all you need to be able to do is find an alternating path.
In bipartite graphs, this is very easy to do (it can be done with DFS). In general graphs this is more complicated, and this is were Edmonds' Blossom algorithm comes in. Roughly speaking:
Build a new graph, where there is an edge between two vertices if you can get from u to v by first traversing an edge that is in the matching, and then traversing and edge that isn't.
In this graph, try to find a path from an unmatched vertex to a matched vertex that has an unmatched neighbor (that is, a neighbor in the original graph).
Each edge in the path you find corresponds to two edges of the original graph (namely an edge in the matching and one not in the matching), so the path translates to an alternating walk in the new graph, but this is not necessarily an alternating path (the distinction between path and walk is that a path only uses each vertex once, but a walk can use each vertex multiple times).
If the walk is a path, you have an alternating path and are done.
If not, then the walk uses some vertex more than once. You can remove the part of the walk between the two visits to this vertex, and you obtain a new graph (with part of the vertices removed). In this new graph you have to do the whole search again, and if you find an alternating path in the new graph you can "lift" it to an alternating path for the original graph.
Going into the details of this (crucial) last step would be a bit too much for a stackoverflow answer, but you can find more details on Wikipedia and perhaps having this high-level overview helps you understand the more mathematical articles.
Implementing this from scratch will be quite challenging.
For the weighted version (with the Euclidean distance), there is an even more complicated variant of Edmonds' Algorithm that can handle weights. Kolmogorov offers a C++ implementation and accompanying paper. This can also be used for the unweighted case, so using this implementation might be a good idea (even if it is not in java, there should be some way to interface with it).
Since your weights are based on Euclidean distances there might be a specialized algorithm for that case, but the more general version I mentioned above would also work and and implementation is available for it.

Transposing on a Directed Graph

I've been assigned the following problem, but am having issues figuring it out. I know what I'd like to accomplish, but given the skeleton code he's outlined for us, I'm not sure where to start...I drew a pic to illustrate what I'd like to accomplish (I think...)
http://i802.photobucket.com/albums/yy304/Growler2009/Transposing-1.jpg
This is what I need to do:
Consider a directed graph G(V;A). The transpose of G written GT (V;AT ) is nothing more than
G where all the arcs have been transposed, i.e., the origin of the arc becomes the end and the end
becomes the origin. In a sense, GT is the \backward" version of G. For this question you must
implement an algorithm which, given a directed graph, produces its transpose. The API of the
algorithm is given by the following interface:
public interface Transpose<VT,AT> {
public DIGraph<VT,AT> doIt(DIGraph<VT,AT> src);
}
Implement the transpose algorithm given above. You have no restrictions on how to do this (except
that it must operate on a graph represented as an adjacency list and it cannot modify the original
graph. Report (in the comments) the space and time complexities in big O notation and brie
y
justify. (i.e., how long does it take and how much space does it uses to transpose a graph with n
vertices and m arcs).
Any help you can offer to get me started would be great.
Thanks!
in pseudolanguagecode:
create new empty set of edges E
for I in all edges:
(X,Y) = vertices of edge I ;
insert edge (Y,X) to E;
result is in E.
Space complexity: no requirements
Time complexity: O(num. of edges)

Categories

Resources