Given an arbitrary directed graph DG in python, is it possible to elegantly make it an undirected one? (This is all in terms of the networkx library).
I was trying to compute some statistics like average clustering, number of triangles etc. However these all are defined for the undirected graphs, so I was wondering if it is trivial to convert the directed graph into an undirected one.
You can use:
H = G.to_undirected()
See the Networkx documentation.
Related
I have some multigraph bipartite networks where some nodes have several edges, all of the edges are directed. An example of one of my graphs:
I want to create projected graphs for both V1 vertices (i.e. x nodes) and connect them if they share the same neighbour from V2 vertices (i.e. r nodes). And vice versa.
But when trying to use Networkx and its projected_graph methods, they are all "not defined for multigraphs" despite allowing multigraphs to be returned? It has no explanation as to why.
I'm very new to graph and network theory, but I would assume that just because a node is allowed more than one edge wouldn't make it impossible to make a projected graph from it? If I am wrong, is there another way I can create projection graphs like I describe above?
Is there a library in python or c++ that is capable of estimating normals of point clouds in a consistent way?
In a consistent way I mean that the orientation of the normals is globally preserved over the surface.
For example, when I use python open3d package:
downpcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=4, max_nn=300))
I get an inconsistent results, where some of the normals point inside while the rest point outside.
many thanks
UPDATE: GOOD NEWS!
The tangent plane algorithm is now implemented in Open3D!
The source code and the documentation.
You can just call pcd.orient_normals_consistent_tangent_plane(k=15).
And k is the knn graph parameter.
Original answer:
Like Mark said, if your point cloud comes from multiple depth images, then you can call open3d.geometry.orient_normals_towards_camera_location(pcd, camera_loc) before concatenating them together (assuming you're using python version of Open3D).
However, if you don't have that information, you can use the tangent plane algorithm:
Build knn-graph for your point cloud.
The graph nodes are the points. Two points are connected if one is the other's k-nearest-neighbor.
Assign weights to the edges in the graph.
The weight associated with edge (i, j) is computed as 1 - |ni ⋅ nj|
Generate the minimal spanning tree of the resulting graph.
Rooting the tree at an initial node,
traverse the tree in depth-first order, assigning each node an
orientation that is consistent with that of its parent.
Actually the above algorithm comes from Section 3.3 of Hoppe's 1992
SIGGRAPH paper Surface Reconstruction from Unorganized Points. The algorithm is also open sourced.
AFAIK the algorithm does not guarantee a perfect orientation, but it should be good enough.
If you know the viewpoint from where each point was captured, it can be used to orient the normals.
I assume that this not the case - so given your situation, which seems rather watertight and uniformly sampled, mesh reconstruction is promising.
PCL library offers many alternatives in the surface module. For the sake of normal estimation, I would start with either:
ConcaveHull
Greedy projection triangulation
Although simple, they should be enough to produce a single coherent mesh.
Once you have a mesh, each triangle defines a normal (the cross product). It is important to note that a mesh isn't just a collection of independent faces. The faces are connected and this connectivity enforces a coherent orientation across the mesh.
pcl::PolygonMesh is an "half edge data structure". This means that every triangle face is defined by an ordered set of vertices, which defines the orientation:
order of vertices => order of cross product => well defined unambiguous normals
You can either use the normals from the mesh (nearest neighbor), or calculate a low resolution mesh and just use it to orient the cloud.
I'm working on implementing an algorithm to determine the graphical structure of a dataset. The dataset could have undirected or directed edges between variables. I could create my own graph object in Python, but I was curious if Networkx has this capability. From what I've seen, Networkx only has a Graph object (only undirected edges) and a DiGraph object (for directed edges only). Is there a way to include directed edges in a undirected graph in Networkx and/or vice versa?
networkx has no mixed graph handling. There were discussions about it, but the implementation had an impact on the whole library, so it was suspended. As I know, graph-tool and igraph has no this functionality too. If you are not satisfied by bidirected edges as undirected, I am afraid you should not use Python libraries, because it is impossible to have both directed and undirected edges in the most popular Python graph libraries: networkx, graph-tool and igraph.
My question is similar to this question. I am using python-igraph library to create undirected graph. What I want to achieve is to untangle as much as possible such that minimum number of crossings of edges is achieved. Then I want convert this clean layout to a 2D plane where I can read the the coordinates of each vertex and no vertex is overlapping any other vertex.
For my current graph I have generated the layout based on the Fruchterman-Reingold force-directed algorithm (as shown in the image).
Can anyone give me some hints how can I achieve that? or this cannot be solved in polynomial time because to find the best placement of vertices with minimum of number of crossing is a NP-Hard problem.
Properties of graph:
Graph has V vertices and E edges.
It is connected, undirected and positive weighted.
Graph has exactly one cycle.
The goal is to find the shortest path between two vertices a and b in O(V) time.
A link to a similar question if there's one will be appreciated.
Consider using Breadth-first search, It is O(V+E)
https://en.wikipedia.org/wiki/Breadth-first_search