I am stuck in a problem regarding Graph traversal based on the angle between two edges. I would like to summarize the problem as follows, given 5 vertices a,b,c,d,e and the edges (a, b), (b, c), (c, d), (d, e).
If I want to traverse the graph based on calculating the angle between two edges like for example angle((a, b), (b, c)). If my angle is greater than 10 degree I should stop at b and start the process again.
What steps do I need to consider to approach this problem having concrete programming structures.
If I understand correctly, when angle((a,b),(b,c)) returns a value of over some threshold (10, in your example), you should stop traversing the graph.
This means that effectively, this node (b) is not helping by connecting the two edges ((a,b) and (b,c)). It might be useful for some other set of edges, but that specific connection is not available.
What I suggest is swapping the role of edges and nodes. Every edge in G becomes a node in G' and every node in G becomes and edge in G' only if the value of angle() returns a value lower than your threshold.
On G' you can now run BFS, DFS or any other algorithm of your liking. When you are done, use the reverse transformation to "translate" your answer back into the original graph in question.
Related
I'm studying random contraction algorithm and could not understand how it works.
In the course it says that a graph G=(V,E) with n vertices, m edges. a minumum cut(A,B), are there are many vertices either on A's or B's sides. k=number of edges crossing (A,B).(call these edges F)
then it make the conclusion that an edge of F is contracted at some point, algorithm will not output(A,B).
Why is this? suppos there is a vertice C in A's side and a vertice D in B's side, so the edge(C,D) would belong to F, but even if C and D are to contract, we still have A and B, the algorithm can still return (A,B) right?
If G is a graph and (A, B) is a cut in the graph, then A and B are sets of nodes, not individual nodes in G. That is, there is no node in G called A or B. Rather, the nodes in G can be split apart into two groups, one of which we’ll call A and one of which we’ll call B. As a result, you can’t have the situation you’ve described.
Here’s another way to think about this. Suppose (A, B) is a minimum cut. You can then imagine that every node in the graph is painted red if it’s in the A side and blue if it’s in the B side. The randomized contraction algorithm will then find the cut (A, B) assuming that no red node is merged with a blue node. If nodes of opposite colors are merged, then the resulting cut won’t consist of all the red nodes on one side and all the blue nodes on the other.
I try to get this code developed for a potential project at work and I think Dijkstra can help but no idea how to get started.[![enter image description here][1]][1]
I have a list of Line objects called myList and each line has EndPoint1 and EndPoint2 as Point2Dcordinates (x,y) and Name as string. So the list has L1, L2, L3, L4, L5, L6, L7, and L8 as shown in the example image. Points A, B, C, D, and E are points of these lines and they are always not connected points between two lines.
I would like to write a method that gives me a list of the lines (or names of the lines) that connected two points for example:
List<string> FindPath(Point2D P1, Point2D P2): (A, E): L1, L3, L6, L7, L8
List<string> FindPath(Point2D P1, Point2D P2): (B, D): L2, L3, L5
Edit:
I would like to find all possible paths, although 99.9% of the time there is only 1 path possible.
You are talking about a data structure called a graph, a collection of nodes (points), connected by edges (line segments).
Graphs comes in several flavours. They can be directed or undirected, and they can by cyclic, or acyclic.
Directed graphs have one-way edges: the edge a→b can only be used to travel from a to b, it can't be used to get from b to a. Undirected graphs, on the other hand, have 2-way edges: as long as two nodes are connected, you can get from either one to the other.
Cyclic graphs allow cycles, where traversing the graph can return you to a node you have already visited (a → b → c → a is a cycle); acyclic graphs do not allow such cycles. If your graph is cyclic, when you traverse it, you'll need to track what nodes you've visited, so you can detect and deal with cycles. If you don't you'll wind up in an endless loop.
In addition, both nodes and edges may carry additional information, such as "cost", making them a weighted graph. Google's and Apple's maps are modeled as such weighted graphs. Each intersection is a node, and each street segment between intersections is an edge. The additional information (weigths) carried by edges are information such as average speed, starting/ending addresses, etc.
If you need to find the shortest path between two nodes in your graph, you may need a weighted graph (where the edges carry a distance. Or not: perhaps "shortest path" is defined as the least number of intermediate nodes between A and B.
So, you need the correct model:
a set of nodes, and
a set of edges, defined by the 2 nodes it connects.
One can (and it is sometimes useful to dispense with the set of nodes completely, and define the graph solely in terms of its edges:
Once you have that, finding a path from any two points in the graph is actually pretty easy. The algorithm is this:
You can get from node A to node B if an edge AB exists. Otherwise...
You can get from node A to node B if
an edge AX exists, and
you have not yet visited node X, and
you can [recursively] get from node X to node B.
That's about all there is to it.
I am assuming you need to find the shortest path from one point to another. Hence you need to do a BFS *).
First convert the points into a graph. The graph could be of the format
// The key is the point and the it contains the list of all
// the neighbours
Map<Point2D, List<Point2D>> graph = new HashMap<>();
Then use a Queue and a visited matrix to keep track of the visited points. When looping through the Points make sure you add them to an answer list.
For more details on BFS look here: https://www.geeksforgeeks.org/print-paths-given-source-destination-using-bfs/
*) Breadth First Search Algorithm
You can solve this by treating it as a graph. Each x is a vertex, and your lines are the edges. Then to find the path between P1 and P2, run BFS from P1.
Given a directed, weighted, cyclic graph, and minimal path distance between vertices given by m(x,y), find the vertex v that minimises m(a,v) + m(b,v) + m(c,v) + ... for n vertices a, b, c...
For example if the graph was undirected and we wanted the vertex v with minimal paths to vertices a and b, v would just be the vertex in the centre of the minimal path from a to b.
I can imagine an approach involving depth traversal etc, but wanted to ask what SO would suggest - Thanks hope this was clear.
Now that I am thinking a bit more about it, you should probably look at Bidirectional Search.
The basic idea would be to start a Dijkstra from each of your query nodes (a, b, c, ...) at the same time. The first vertex that is found by all of them is your result vertex.
You can implement this by putting all (unvisited vertex, distance, query vertex)triplets you encounter in one priority queue (sorted by distance) and process it similar to Dijkstra. You will need to label the the vertices you have seen with the query node from which you reached them. When a vertex is labeled with all query vertices then this is your result (let's call it median vertex).
I've faced with following problem: find the optimal edge coloring in a bipartite graph. I know that greedy coloring algorithm can sometimes not return the optimal number of colors. By 'greedy coloring algorithm' I mean: choose first vertex with the highest degree and color its edges on colors 1...degree, then choose the vertex with degree <= to the previous degree and color every of its incident edge on the first available number (the lowest number which is not used by its neighbour), the choose the next vertex etc.
But I've introduced one modification: the edges of first choosen vertex I color in descending order (degree...1), and edges of the next vertices as previously on 1...degree. This modification resulted in examples which I've come up I've got optimal number of colors. But I'm not pretty sure that it's always a rule. Does somebody know if this version of edge coloring algorithm is optimal, or maybe anyone is able to show any counterexample?
You can take your counterexample for the "naive" greedy algorithm and turn it into a counterexample for your "sophisticated" greedy algorithm. Simply insert dummy nodes with appropriate degree to "absorb" the backwards colorings. One can always fabricate a new node with degree n in an arbitrary part of the graph: simply insert n fresh nodes in the other part and connect them each by a single edge to the desired new node.
Since all nodes that get colored in descending order are freshly inserted, all the nodes in the original counterexample are colored in ascending order, hence get the same colors as they would have in the original "naive" greedy algorithm. Since the optimal coloring has at least as many colors as the degree of the original graph, and the freshly inserted nodes all have smaller degree than the original graph's maximal degree, the new graph does not need any more colors than the original. Therefore the coloring produced by the "sophisticated" algorithm -- which will still have more colors than necessary for the original graph -- is not optimal for the new graph.
For example, take the graph described in the comment below, which has nodes B,C,D on the left and E,F,G,H on the right. It has these edges:
B connects to E, F, and G
C connects to E, F, and G
D connects to G and H
For the moment, I will assume only the first node you touch gets colored in descending order. (For other nodes, it is not even clear what "descending order" might mean -- descending from what maximum? The degree of the node may not be high enough.)
Therefore, we insert a new node A on the left and three nodes I, J, and K on the right; the connectivity is now
A connects to I, J, and K
B connects to E, F, and G
C connects to E, F, and G
D connects to G and H
The sophisticated greedy algorithm will therefore color AI-3, AJ-2, AK-1, then proceed as the naive greedy algorithm on the remaining nodes.
For instance, suppose I have a graph G = (V, E) where
V = {A, B, C, D}
E = {(A, B), (A,D), (C, D)}
This graph is bipartite, and thus can be split into two disjoint sets {A, C} and {B, D}. My first guess is that I can simply walk the graph and assign alternating colors to each vertex. Is this the case, or is it more complicated/simpler than this? Are there any known algorithms for this?
Your first guess is correct - traverse the graph and alternate.
The algorithm should be simple. I'd keep two queues of nodes to visit, one for each colour. Pop nodes off the queues alternately, mark its colour, and push any non-visited adjacent nodes into the queue for the opposite colour. Terminate when the number of visited nodes + the length of both queues = number of nodes in the graph.
From Wikipedia (http://en.wikipedia.org/wiki/Bipartite_graph)
If a bipartite graph is connected, its bipartition can be defined by the parity of the distances from any arbitrarily chosen vertex v: one subset consists of the vertices at even distance to v and the other subset consists of the vertices at odd distance to v.
Thus, one may efficiently test whether a graph is bipartite by using this parity technique to assign vertices to the two subsets U and V, separately within each connected component of the graph, and then examine each edge to verify that it has endpoints assigned to different subsets.
Traverse the graph and alternate, if it doesn't succeded it means that your graph is not bipartite.
If you are sure that the graph is biparte, then you can just assign colors alternating them for traversing each vertex, as it holds that:
A graph is bipartite if and only if it is 2-colorable.
I implemented it in my graph drawing tool, you can see my code in JavaScript.
I just marked first vertex as left partity, then recursively marked it's neighbours as right partity, recursively mark their neighbours as left partity... If you find correctly marked node, stop recursion of this branch. If you find uncorrectly marked node, graph is not bipartite.
Maybe it can be done simpler, but during last few months I had some hard Prolog - Haskell coding days, maybe it had affected my brain and now I see recursion in everything :-D
Just in case anyone's curious, here's the code I came up with:
def dfs(root, colorings):
to_visit1 = deque()
to_visit2 = deque()
to_visit1.append(root)
while len(to_visit1) != 0 or len(to_visit2) != 0:
dfs_color(to_visit1, to_visit2, True, colorings)
dfs_color(to_visit2, to_visit1, False, colorings)
def dfs_color(queue, opposite_queue, color, colorings):
while len(queue) != 0:
v = queue.pop()
if v in adjacency_list:
colorings[v] = color
neighbors = adjacency_list[v]
del adjacency_list[v]
for neighbor in neighbors:
opposite_queue.append(neighbor)
Admittedly, this isn't my best code. I'm using True/False as the color because when I used recursion, it made it easy to just say not color. Of course, I had to change it because I blew my stack on bigger graphs. Also to give credit where due, this code is based on the wikipedia code for DFS.
Although as has been pointed out, I think this may just be a disguised BFS.