Drawing small planar graphs with Graphviz - graphviz

I drew a small planar graph with Graphviz but in one place there's an intersection of two edges. I read on SO that not all planar graphs can be drawn without intersections because it's an NP-hard problem. I also read that there aren't even implemented complex algorithms in Graphviz that do that. But that intersection is as easy to fix as possible so there probably is a way to get rid of it.
Here are the options I used:
overlap = false;
splines = curved;
nodesep = 0.5;
And here's the graph:
So, is there a way of fixing that one intersection (25-38 with 7-18) without changing the order of edges like I did here? Isn't there like at least O(n^2) algorithm that would swap two vertices and check if the intersection disappeared?

This is kind of a hotfix:
Add an invisible edge between nodes 7 and 25, ie 7 -- 25 [style="invis"];. This clause may be added to the end of the graph definition so it shouldn't interfere with any automatic generation.
It feels like cheating, however, at least the order of the payload edges in the graph definition file remains untouched.
I cannot give an explanation of why this works,unfortunately. In particular, adding edges between other nodes incident to the offending edges does not produce the desired result.
Graphviz version: 2.38.0 (20140413.2041)

Related

Finding the inner-most path of a polygon

Given an undirected graph of vertices, I need to find the innermost path that connects two specific points. My original idea was to just use something like Dijkstra's algorithm to find the shortest path, but there are many cases where the shortest path is not the innermost. Here is a visual of what I am trying to achieve:
Ultimately, I am trying to generate "rooms" based on walls that are drawn in my program. So in this image, the dashed line is the final edge I am drawing, which should then find an edge path from vertex 1 to vertex 7 (occluding the dashed edge), which would give me the path 1-2-3-4-5-6-7. If I was to use my current solution, the shortest path would be 1-2-8-6-7, but obviously, this is not the innermost path.
I've attempted to research this extensively but can't seem to find an answer. I also tried to pick the lowest edge angle at each node to traverse but this would only work for traveling in one direction, as I have no current way of determining whether it traverses clockwise or counterclockwise across the nodes. It might be worth noting that I am attempting this in Lua, but pseudo-code or a similarly high-level language would be appreciated as well!
Let me know if I can clarify anything.
Basically what you want is to enumerate the edges incident to a face of a planar straight-line graph.
First you need an embedding: for each node, sort the edges entering it in some counterclockwise order, e.g., 5→6, 8→6, 12→6, 7→6. (You can avoid trig if you like using the law of cosines.) Then store the successors in a big map: (5→6): (8→6), (8→6): (12→6), (12→6): (7→6), (7→6): (5→6), (1→7): (6→7), etc.
Second, to find the face to the right of a directed edge, repeatedly find the next directed edge in counterclockwise order and reverse it, until you come back to the starting edge. For example, 1→7, 6→7, 7→6, 5→6, 6→5, 4→5, 5→4, 3→4, 4→3, 2→3, 3→2, 1→2, 2→1, 7→1, 1→7.
Now, there's a slight complication here in that if you start with 7→1, you're going to loop around the infinite face: 7→1, 10→1, 1→10, 9→10, etc. The way to handle this is by computing the signed area of the face. If it's negative, then we're good, because we enumerate the finite faces in clockwise order. If it's positive, then we need the other face, because we enumerate the infinite face in counterclockwise order.
You'll have to tell me what you want if both incident faces are finite.

Adding cycles to a Minimum Spanning Tree without moving the points?

I am generating a dungeon layout for a video game. I have created the rooms, spaced them out using seperation steering, and created a fully connected weighted, undirected graph of the rooms. Then I calculated a MST using Prim's Algorithm, all using GML (GameMaker Language). I miss Python.
My intention is to add additional edges to reintroduce loops, so a player does not have to always return along a path, and to make layouts more interesting. The problem is, these edges cannot cross, and I would prefer not to have to move the points around. I had been given a recommendation to use Delaunay Triangulation, but if I am honest this is completely over my head, and may not be a viable solution in GML. I am asking for any suggestions on algorithms that I could use to identify edges that I could add that do not intersect previously created edges.
I have included an image of the MST (the lines connect to the corners of the red markers, even if the image shows they stop short)
If I'm understanding your question correctly, we're looking at more of a geometry problem than a graph theory problem. You have existing points and line segments with concrete locations in 2d space, and you want to add new line segments that will not intersect existing line segments.
For checking whether you can connect two nodes, node1 and node2, you can iterate through all existing edges and see whether the line segment node1---node2 would intersect the line segment edge.endpoint1 --- edge.endpoint2. The key function that checks whether two line segments intersect can be implemented with any of the solutions found here: How can I check if two segments intersect?.
That would take O(E) time and look something like
def canAddEdge(node1, node2):
canAdd = True
for edge in graph:
canAdd = canAdd and not doesIntersect([node1.location(),
node2.location(), edge.endpoint1.location(), edge.endpoint2.location()])
And you can get a list of valid edges to add in O(EV^2) with something like
def getListOfValidEdges(graph):
validEdges = []
for index,firstEndpointNode in enumerate(graph.nodes()):
for secondEndpointNode in graph.nodes()[index:]:
if (canAddEdge(firstEndpointNode, secondEndpointNode)):
validEdges.append([firstEndpointNode, secondEndpointNode])
return validEdges
Of course, you would need to recalculate the valid edges every time after adding a new edge.

Arranging nodes-edges for 'good looking' graph layout

I came across following graph layout proposed in the paper NodeTrix :
The big blocks that are visible are nodes themselves (A sort of composite node of a sub-graph).
I see that the edges are some sort of curves which seem to not intersect too much among themselves. Also, the nodes and edges don't intersect among themselves. Paper doen't talk about it btw.
I was hoping to implement this visualization. I have following doubts:
Q1. Is this some specific algorithm to arrange Nodes-Edges so that the graph look good, as shown in this paper ? Any other algorithm in general ?
Q2. Is there some special algorithm for the curved edges shown above as well ?
It would be great if someone could figure out the exact algorithm in the above figure visually, but some general similar algorithm should also do.
One algorithm is Force-directed graph drawing. It will produce an output very different from the posted picture, but it is quite popular and might give you a place to start looking.
To be honest, I suspect that the shown graph is manually laid out.
EDIT: Answer to comment
In the example all nodes are square boxes, and the edges start/end diagonal to the sides of the boxes. A way to to this could be
Place boxes using force-direction (or likely some customized version of it, forces depend on the size of the box)
Imagine a "guide-edge" going directly between the centers of the boxes
Calculate the the places where the guide-edge intersects the boxes, and use that as the start/end points of the real, drawn edge.
Make the real edge start diagonal to the sides, and use bezier curves to draw the curve.
You probably want to represent this as some vector format, that has bezier cures built in, e.g., svg.

Find nearest edge in graph

I want to find the nearest edge in a graph. Consider the following example:
Figure 1: yellow: vertices, black: edges, blue: query-point
General Information:
The graph contains about 10million vertices and about 15million edges. Every vertex has coordinates. Edges are defined by the two adjacent vertices.
Simplest solution:
I could simply calculate the distance from the query-point to every other edge in the graph, but that would be horribly slow.
Idea and difficulties:
My idea was to use some spatial index to accelerate the query. I already implemented a kd-tree to find the nearest vertex. But as Figure 1 shows the edges incident to the nearest vertex are not necessarily the nearest to the query-point. I would get the edge 3-4 instead of the nearer edge 7-8.
Question:
Is there an algorithm to find the nearest edge in a graph?
A very simple solution (but maybe not the one with lowest complexity) would be to use a quad tree for all your edges based on their bounding box. Then you simply extract the set of edges closest to your query point and iterate over them to find the closest edge.
The extracted set of edges returned by the quad tree should be many factors smaller than your original 15 million edges and therefore a lot less expensive to iterate through.
A quad tree is a simpler data structure than the R-tree. It is fairly common and should be readily available in many environments. For example, in Java the JTS Topology Suite has a structure QuadTree that can easily be wrapped to perform this task.
There are spatial query structures which are appropriate for other types of data than points. The most general is the "R-tree" structure (and its many, many variants), which will allow you to store the bounding rectangles of your line segments. You can then search outward from your query points, examining the segments in the bounding rectangles and stopping when the nearest remaining rectangle is further than the closest line encountered so far. This could have poor performance when there are many long line segments overlapping, but for a PSLG such as you seem to have here, that shouldn't happen.
Another option is to use the segments to define a BSP tree, and scan outwards from your point to find all the "visible" lines. This in turn will be problematic if your point can see many edges.
Without proof:
You start with a constrained Delaunay Triangulation, that is a triangulation that takes the existing edges into account. E.g. CGAL or Triangle can do this. For each query point you determine which triangle it belongs to. Then you you only have to check the edges touching a corner of that triangle.
I think this should work in most cases, but there are certainly corner cases where it fails, e.g. when there are many vertices without any edge at all, so at least you have to remove those empty vertices.
You can compute the voronoi diagram and run a query on each voronoi cell. You can subdivide the voronoi diagram to get a better result. You can combine metric and voronoi diagram:http://www.cc.gatech.edu/~phlosoft/voronoi/
you could insert extra vertices in long edges to get some approximation based on closest vertices ..

How to draw a graph with less crossing by using some broken line?

I'm dealing with a graph with n nodes' coordinate and m undirected edges, how can I get a better visual graph(with less crossing) by allow using some broken line instead of straight line?
I know minimize the crossing number is a NP problem. So I just ask for some help here beacuse I think someone may give me some resources about it.
What's more, I think it is ok that change some nodes' coordinate(not move them too far), all in all, it's the problem that how to find a more clear graph for our eyes!
GraphViz website is a good place to start learning about graph visualization.
The Boost graph library (i.e. BGL) has plenty of algorithms and data structures to experiment with, and a dual interface (c++ of course, or python). Of course, Boost isn't the easiest way to start. Surely Graphviz (that BGL can interface) it's way simpler.
In the BGL docs there are many resource you could find useful: for instance, from the previous link:
Any plane drawing separates the plane into distinct regions bordered by graph edges called faces. As a simple example, any embedding of a triangle into the plane separates it into two faces: the region inside the triangle and the (unbounded) region outside the triangle. The unbounded region outside the graph's embedding is called the outer face. Every embedding yields one outer face and zero or more inner faces. A famous result called Euler's formula states that for any planar graph with n vertices, e edges, f faces, and c connected components,
n + f = e + c + 1
This formula implies that any planar graph with no self-loops or parallel edges has at most 3n - 6 edges and 2n- 4 faces. Because of these bounds, algorithms on planar graphs can run in time O(n) or space O(n) on an n vertex graph even if they have to traverse all edges or faces of the graph.
A convenient way to separate the actual planarity test from algorithms that accept a planar graph as input is through an intermediate structure called a planar embedding. Instead of specifying the absolute positions of the vertices and edges in the plane as a plane drawing would, a planar embedding specifies their positions relative to one another. A planar embedding consists of a sequence, for each vertex in the graph, of all of the edges incident on that vertex in the order in which they are to be drawn around that vertex. The orderings defined by this sequence can either represent a clockwise or counter-clockwise iteration through the neighbors of each vertex, but the orientation must be consistent across the entire embedding.
In the Boost Graph Library, a planar embedding is a model of the PlanarEmbedding concept. A type that models PlanarEmbedding can be passed into the planarity test and populated if the input graph is planar. All other "back end" planar graph algorithms accept this populated PlanarEmbedding as an input. '

Resources