Here is my function that creates the igraph instance.
---------------------------------- Code begins ----------------------------------
import numpy as np
import igraph as ig
def buildIGraphFromAdjCost(adj, cost, names):
"""
Build an igraph with adj, cost and names.
Parameters
----------
adj: ndarray, int
NxK array specifying the adjacency relations.
adj[i, k] is the k^th nearest neighbor of the i^th node.
Each entry of adj is an integer between 0 and N-1 (inclusive).
cost: ndarry, double
NxK array specifying the cost of each edge
cost[i, k] is the cost of the edge connecting the i^th node and
its k^th nearest neighbor (i.e., edge between i and adj[i, k])
names: node names
Returns
-------
G: igraph
An igraph instance with N nodes.
"""
N, K = adj.shape
adjInd = np.tile(np.arange(N)[:, None], (1, K))
es = np.dstack((adjInd, adj[:, :K])).reshape((N*K, 2))
# es.shape at this point is (N*K, 2)
G = ig.Graph()
G.add_vertices(names)
G.add_edges(es)
G.es['weight'] = cost.ravel()
# At this point all the nodes have a degree around 2*K
G.simplify(multiple=True, loops=True, combine_edges=dict(weight="mean"))
# Now every node has degree around K
return G
----------------------------------- Code ends -----------------------------------
Before calling this function, the adj and cost arrays are built from a
set of points so that adj holds the k nearest neighbors of each point
and cost holds the distances of that point to its k nearest neighbors. I
ran this code on several data sets and I am observing multiple edges between pairs of nodes before simplifying the graph.
Thanks,
Ram