percolation (network attack) by degree - python

I am trying to implement a function to remove some fraction of high degree nodes based on initial lcc (1% in every step) until the lcc will be destructed completely (size zero). to test my code I am using DBLP coauthor ship network which is already shown that the lcc of the this graph will be destructed after removing 1.5% of high degree nodes. However my code fail to that,.
one thing that I am not sure is that when we mask some nodes and then use GraphView(G,vfilt=mask), it does not take of isolated vertices after masking. So I had to check for them manually. thanks for any hint!
def _breake_lcc(self, G, remove_ratio):
'''
G:graph
remove_ratio = ratio for removing high degree nodes
'''
#lcc of complete graph
l = gt.label_largest_component(G)
lcc_graph = gt.GraphView(G,vfilt=l)
lcc_org_size = float(lcc_graph.num_vertices())
lcc_size = [lcc_org_size/lcc_org_size]
#print 'lcc_size_zero: ', lcc_graph.num_vertices()
#extract the vertices inside lcc
node_ind = np.where(l.a==1)[0]
#compute the degree of all nodes
degree = lcc_graph.degree_property_map('total')
#extract the degreee of nodes in the lcc
lcc_vertex_degree = degree.a[node_ind]
#sort the nodes based on degree
sorted_idx = np.argsort(lcc_vertex_degree)[::-1]
sorted_vertex = set(node_ind[sorted_idx])
#number of nodes
n = len(node_ind)
#number of top x% degree nodes to be removed -ratio to size
remove_size = int((n*remove_ratio)/100.)
print 'remove size',remove_size
step = 1
#extract top x% vertices to remove
nodes_to_be_removed = list(sorted_vertex)[:remove_size]
#removed the above vertices from the list of valid vertices
valid_vertices = list(sorted_vertex - set(nodes_to_be_removed))
#continue until there is no other node to remove
while len(valid_vertices)>0:
print step * remove_ratio
# print len(valid_vertices)
#filter out those nodes from lcc.
#THIS IS AUTOMATICALLY UPDATE LCC_GRAPH
l.a[np.array(nodes_to_be_removed)] = False
#I REALIZED GRAPHVIEW DOES NOT TAKE CARE OF ISOLATED NODE AUTOMATICALLY
#SO I CHECK FOR THEM MANUALLY
ind_remove = [int(i) for i in lcc_graph.vertices() if i.out_degree()==0]
if len(ind_remove)>0:
print len(ind_remove)
mask = lcc_graph.new_vertex_property("bool")
#mask.a[::] = True
mask.a = l.a.copy()
#l.a[np.array(ind_remove)] = False
mask.a[np.array(ind_remove)] = False
#mask.a[nodes_to_be_removed] = False
#print np.all(mask.a==l.a)
lcc_graph = gt.GraphView(lcc_graph, vfilt=mask)
#update the valid nodes
valid_vertices = list(set(valid_vertices) - set(ind_remove))
print len(valid_vertices), len(sorted_vertex),lcc_graph.num_vertices()
lcc_temp_size = float(lcc_graph.num_vertices())
#print 'valid', len(valid_vertices),lcc_temp_size
valid_vertices = list(sorted_vertex -set(nodes_to_be_removed))
nodes_to_be_removed = valid_vertices[:int(remove_size)]
print lcc_temp_size,lcc_org_size
rel_size = lcc_temp_size/lcc_org_size
lcc_size.append(rel_size)
print 'lcc size', rel_size
print '------------'
step+=1
return lcc_size

Related

Operands could not be broadcast together with shapes

data = pd.read_csv('./Book1.csv')
# Read the edgelist of the Wiki Talk network
G = nx.from_pandas_edgelist(data, data.columns[0], data.columns[1])
G = G.subgraph(max(nx.connected_components(G), key=len))
ic_seed_set = np.random.choice(G.nodes(), ic_seed_set_size)
Determine the model parameter
ic_threshold = 0.4
g = Graph([[u,v] for (u,v) in G.edges])
def IC(g,S,ic_threshold,ic_num_steps):
"""
Input: graph object, set of seed nodes, propagation probability
and the number of Monte-Carlo simulations
Output: average number of nodes influenced by the seed nodes
"""
# Loop over the Monte-Carlo Simulations
spread = []
for i in range(ic_num_steps):
# Simulate propagation process
new_active, A = S[:], S[:]
for i in range(len(new_active)) :
# For each newly active node, find its neighbors that become activated
new_ones = []
for node in new_active:
# Determine neighbors that become infected
np.random.seed(i)
success = np.random.uniform(0,1,len(g.neighbors(node,mode="out"))) < ic_threshold
new_ones += list(np.extract(success, g.neighbors(node,mode="out")))
new_active = list(set(new_ones) - set(A))
# Add newly activated nodes to the set of activated nodes
A = A + new_active
spread.append(len(A))
return(np.mean(spread))
modelpropagation =IC(g,ic_seed_set,ic_threshold,ic_num_steps)
i expected list of integer
but in this line >>> A = A + new_active
<ipython-input-24-fc67faf2ae99> in IC(g, S, ic_threshold, ic_num_steps)
61
62 # Add newly activated nodes to the set of activated nodes
---> 63 A = A + new_active
64
65 spread.append(len(A))
ValueError: operands could not be broadcast together with shapes (5,) (492,)

How to find nearest node along nearest edge?

I am using this script from here: link
I want to add new functionality to it. I want it to define starting node on the graph not only by finding the closest node (because that produces odd results like finding the closest node on an other road) but finding the closest and and the closest node along that edge.
My code is available below. I created the findnearestnodeonnearestedge function which should do the work but it doesn't work.
It finds the same node for the starting and destination point, even though they are far from each other...
I am using the newest versions of all packages so you can try the code easily.
Thank you for help
import osmnx as ox
import networkx as nx
import plotly.graph_objects as go
import numpy as np
def findnearestnodeonnearestedge(Gr, pointin):
u, v, key = ox.distance.nearest_edges(G, pointin[0], pointin[1])
n1 = Gr.nodes[u]
n2 = Gr.nodes[v]
d1 = ox.distance.euclidean_dist_vec(pointin[0], pointin[1], n1['x'], n1['y'])
d2 = ox.distance.euclidean_dist_vec(pointin[0], pointin[1], n2['x'], n2['y'])
if d1 < d2:
nodeid = u
else:
nodeid = v
return nodeid
state = ox.geocode_to_gdf('Georgia, US')
ax = ox.project_gdf(state).plot(fc='gray', ec='none')
_ = ax.axis('off')
# Defining the map boundaries
north, east, south, west = 33.798, -84.378, 33.763, -84.422
# Downloading the map as a graph object
G = ox.graph_from_bbox(north, south, east, west, network_type = 'drive')
# Plotting the map graph
ox.plot_graph(G)
# Displaying the 3rd node
list(G.nodes(data=True))[2]
# Displaying the 1st edge
list(G.edges(data=True))[1]
# Displaying the shape of edge using the geometry
list(G.edges(data=True))[1][2]['geometry']
# define origin and desination locations
origin_point = (33.787201, -84.405076)
destination_point = (33.764135, -84.394980)
# get the nearest nodes to the locations
origin_node = findnearestnodeonnearestedge(G, origin_point)
destination_node = findnearestnodeonnearestedge(G, destination_point)
# printing the closest node id to origin and destination points
origin_node, destination_node
# Finding the optimal path
route = nx.shortest_path(G, origin_node, destination_node, weight = 'length')
route
# getting coordinates of the nodes
# we will store the longitudes and latitudes in following list
long = []
lat = []
for i in route:
point = G.nodes[i]
long.append(point['x'])
lat.append(point['y'])
def plot_path(lat, long, origin_point, destination_point):
"""
Given a list of latitudes and longitudes, origin
and destination point, plots a path on a map
Parameters
----------
lat, long: list of latitudes and longitudes
origin_point, destination_point: co-ordinates of origin
and destination
Returns
-------
Nothing. Only shows the map.
"""
# adding the lines joining the nodes
fig = go.Figure(go.Scattermapbox(
name="Path",
mode="lines",
lon=long,
lat=lat,
marker={'size': 10},
line=dict(width=4.5, color='blue')))
# adding source marker
fig.add_trace(go.Scattermapbox(
name="Source",
mode="markers",
lon=[origin_point[1]],
lat=[origin_point[0]],
marker={'size': 12, 'color': "red"}))
# adding destination marker
fig.add_trace(go.Scattermapbox(
name="Destination",
mode="markers",
lon=[destination_point[1]],
lat=[destination_point[0]],
marker={'size': 12, 'color': 'green'}))
# getting center for plots:
lat_center = np.mean(lat)
long_center = np.mean(long)
# defining the layout using mapbox_style
fig.update_layout(mapbox_style="stamen-terrain", mapbox_center_lat=30, mapbox_center_lon=-80)
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0},
mapbox={
'center': {'lat': lat_center, 'lon': long_center},
'zoom': 13})
fig.show()
plot_path(lat, long, origin_point, destination_point)
# Getting the start and end node of this part
start_node=route[-7]
end_node=route[-6]
# Getting the edge connecting these nodes and storing it as a list in z to maintain the data structure of G.edges
z = []
for i in list(G.edges(data=True)):
if (i[0]==start_node) & (i[1]==end_node):
z.append(i)
z[0][2]['geometry']
def node_list_to_path(G, node_list):
"""
Given a list of nodes, return a list of lines that together follow the path
defined by the list of nodes.
Parameters
----------
G : networkx multidigraph
route : list
the route as a list of nodes
Returns
-------
lines : list of lines given as pairs ( (x_start, y_start), (x_stop, y_stop) )
"""
edge_nodes = list(zip(node_list[:-1], node_list[1:]))
lines = []
for u, v in edge_nodes:
# if there are parallel edges, select the shortest in length
data = min(G.get_edge_data(u, v).values(), key=lambda x: x['length'])
# if it has a geometry attribute (ie, a list of line segments)
if 'geometry' in data:
# add them to the list of lines to plot
xs, ys = data['geometry'].xy
lines.append(list(zip(xs, ys)))
else:
# if it doesn't have a geometry attribute, the edge is a straight
# line from node to node
x1 = G.nodes[u]['x']
y1 = G.nodes[u]['y']
x2 = G.nodes[v]['x']
y2 = G.nodes[v]['y']
line = [(x1, y1), (x2, y2)]
lines.append(line)
return lines
# getting the list of coordinates from the path (which is a list of nodes)
lines = node_list_to_path(G, route)
long2 = []
lat2 = []
for i in range(len(lines)):
z = list(lines[i])
l1 = list(list(zip(*z))[0])
l2 = list(list(zip(*z))[1])
for j in range(len(l1)):
long2.append(l1[j])
lat2.append(l2[j])
print("Length of lat: ", len(lat))
print("Length of lat2: ", len(lat2))
plot_path(lat2, long2, origin_point, destination_point)
Problem was that in the graph coordinates are stored in reverse order. So all pointin[0] and pointin[1] in the function should be reversed and then it will work

Duplicate a nurbs curve along a curve to perform a loft

I have put together a script that creates the following; A start and end curve shape and a linear curve between.
Now what I'm wanting to do is to duplicate and transform the starting curve shape along the path (as depicted by the image), and perform a loft (preferred as would prob give the cleanest result), or alternatively, loft between the two existing curve shapes, and then deform the loft geometry to the curve. For the latter I have tried;
pm.deformer((loftShape, path), type='curveWarp', name='curveWarp#')
without success. The locators are points calculated to generate the correct
bezier curve given different distances/ starting angles. I would have thought the hard work was done, but I'm having trouble with this seemingly simple last step.
Below is a method I put together to query curve info:
def getClosestCV(x, curves, tolerance=0.0):
'''Find the closest control vertex between the given vertices, CVs, or objects and each of the given curves.
:Parameters:
x (str)(obj)(list) = Polygon vertices, control vertices, objects, or points given as (x,y,z) tuples.
curves (str)(obj)(list) = The reference object in which to find the closest CV for each vertex in the list of given vertices.
tolerance (int)(float) = Maximum search distance. Default is 0.0, which turns off the tolerance flag.
:Return:
(dict) closest vertex/cv pairs (one pair for each given curve) ex. {<vertex from set1>:<vertex from set2>}.
ex. vertices = Init.getComponents(objects, 'vertices')
closestVerts = getClosestCV(curve0, curves)
'''
pm.undoInfo(openChunk=True)
x = pm.ls(x, flatten=1) #assure x arg is a list (if given as str or single object).
npcNode = pm.ls(pm.createNode('nearestPointOnCurve'))[0] #create a nearestPointOnCurve node.
result={}
for curve in pm.ls(curves):
pm.connectAttr(curve.worldSpace, npcNode.inputCurve, force=1) #Connect the curve's worldSpace geometry to the npc node.
for i in x:
if not isinstance(i, (tuple, list, set)):
pos = pm.pointPosition(i)
else:
pos = i
pm.setAttr(npcNode.inPosition, pos)
distance = Init.getDistanceBetweenTwoPoints(pos, pm.getAttr(npcNode.position))
p = pm.getAttr(npcNode.parameter)
if not tolerance:
result[i] = p
elif distance < tolerance:
result[i] = p
pm.delete(npcNode)
pm.undoInfo(closeChunk=True)
return result
def getCvInfo(c, returnType='cv', filter_=[]):
'''Get a dict containing CV's of the given curve(s) and their corresponding point positions (based on Maya's pointOnCurve command).
:Parameters:
- c (str)(obj)(list) = Curves or CVs to get CV info from.
- returnType (str) = The desired returned values. Default is 'cv'.
valid values are:
'cv' = Return a list of all CV's for the given curves.
'count' = Return an integer representing the total number of cvs for each of the curves given.
'parameter', 'position', 'index', 'localPosition', 'tangent', 'normalizedTangent', 'normal', 'normalizedNormal', 'curvatureRadius', 'curvatureCenter'
= Return a dict with CV's as keys and the returnType as their corresponding values.
ex. {NurbsCurveCV(u'polyToCurveShape7.cv[5]'): [-12.186520865542082, 15.260936896515751, -369.6159740743584]}
- filter_ (str)(obj)(list) = Value(s) to filter for in the returned results.
:Return:
(dict)(list)(int) dependant on returnType.
ex. cv_tan = getCvInfo(curve.cv[0:2],'tangent') #get CV tangents for cvs 0-2.
ex. cvParam = getCvInfo(curve, 'parameters') #get the curves CVs and their corresponding U parameter values.
ex. filtered = getCvInfo(<curve>, 'normal', <normal>) #filter results for those that match the given value.
'''
result={}
for curve in pm.ls(c):
if '.cv' in str(curve): #if CV given.
cvs = curve
curve = pm.listRelatives(cvs, parent=1)
else: #if curve(s) given
cvs = curve.cv
parameters = Init.getClosestCV(cvs, curve) #use getClosestCV to get the parameter location for each of the curves CVs.
for cv, p in parameters.items():
if returnType is 'position': # Get cv position
v = pm.pointOnCurve(curve, parameter=p, position=True)
elif returnType is 'localPosition':
v = pm.getAttr(cv) # local cv position
elif returnType is 'tangent': # Get cv tangent
v = pm.pointOnCurve(curve, parameter=p, tangent=True)
elif returnType is 'normalizedTangent':
v = pm.pointOnCurve(curve, parameter=p, normalizedTangent=True)
elif returnType is 'normal': # Get cv normal
v = pm.pointOnCurve(curve, parameter=p, normal=True)
elif returnType is 'normalizedNormal':
v = pm.pointOnCurve(curve, parameter=p, normalizedNormal=True) #Returns the (x,y,z) normalized normal of curve1 at parameter 0.5.
elif returnType is 'curvatureRadius': # Get cv curvature
v = pm.pointOnCurve(curve, parameter=p, curvatureRadius=True) #Returns the curvature radius of curve1 at parameter 0.5.
elif returnType is 'curvatureCenter':
v = pm.pointOnCurve(curve, parameter=p, curvatureCenter=True)
elif returnType is 'parameter': # Return the CVs parameter.
v = p
elif returnType is 'count': # total number of cv's for the curve.
result[curve] = len(Init.getCvInfo(curve))
break
elif returnType is 'index': # index of the cv
s = str(cv)
v = int(s[s.index('[')+1:s.index(']')])
else:
v = None
result[cv] = v
if returnType is 'cv':
result = result.keys()
if filter_:
if not isinstance(filter_, (tuple, set, list)):
filter_ = list(filter_)
try:
result = {k:v for k,v in result.items() if any((v in filter_, v==filter_))}
except AttributeError:
result = [i for i in result if any((i in filter_, i==filter_))]
if len(result) is 1:
try:
result = result.values()[0]
except AttributeError, TypeError:
result = result[0]
return result
I ultimately decided to use the built-in MASH plugin for this. Perhaps this will be of help to someone in the future.
def duplicateAlongCurve(path, start, count=6, geometry='Instancer'):
'''Duplicate objects along a given curve using MASH.
:Parameters:
path (obj) = The curve to use as a path.
start () = Starting object.
count (int) = The number of duplicated objects. (point count on the MASH network)
geometry (str) = Particle instancer or mesh instancer (Repro node). (valid: 'Mesh' (default), 'Instancer')
:Return:
(list) The duplicated objects in order of start to end.
'''
pm.undoInfo(openChunk=1)
#create a MASH network
import MASH.api as mapi
mashNW = mapi.Network()
mashNW.MTcreateNetwork(start, geometry=geometry, hideOnCreate=False) #MASH_tools module (derived from 'createNetwork')
curveNode = pm.ls(mashNW.addNode('MASH_Curve').name)[0]
pm.connectAttr(path.worldSpace[0], curveNode.inCurves[0], force=1)
pm.setAttr(curveNode.stopAtEnd, 1) #0=off, 1=on
pm.setAttr(curveNode.clipStart, 0)
pm.setAttr(curveNode.clipEnd, 1)
pm.setAttr(curveNode.timeStep, 1)
pm.setAttr(curveNode.curveLengthAffectsSpeed, 1)
distNode = pm.ls(mashNW.distribute)[0]
pm.setAttr(distNode.pointCount, count)
pm.setAttr(distNode.amplitudeX, 0)
instNode = pm.ls(mashNW.instancer)[0]
baked_curves = mashNW.MTbakeInstancer(instNode) #MASH_tools module (derived from 'MASHbakeInstancer')
result=[start]
for curve in reversed(baked_curves):
result.append(curve)
pm.delete(mashNW.waiter.name()) #delete the MASH network.
pm.undoInfo(closeChunk=1)
return result

network x graph and floyd warshall

I am a newbie in Python. I have a map like this map, and I want to create the shortest paths from each node to every other nodes using network x. I've tried to write a simple code like this:
shp = nx.read_shp("../Shapefiles/Shapefiles/Station_in_Corridors/Group_1.shp")
G = nx.DiGraph()
for data in shp.edges(data = True):
G.add_edge(data[0],data[1],weight = data[2]["Length_Km"])
nx.floyd_warshall(G)
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos = pos, node_size=100)
nx.draw_networkx_edges(G, pos = pos)
plt.show()
Prior to calling the result of floyd warshall, I'd like to see the graph first. Turns out the graph return like this:result. I don't think that graph is similar to the input (or is it?).
Anyhow, I've also tried to manually append the points with this code:
cor1 = driver.Open(cor1Data)
cor2 = driver.Open(cor2Data)
ly1 = cor1.GetLayer()
ly2 = cor2.GetLayer()
allpoints = {}
kreuz = []
arcs = {}
for i in range(ly1.GetFeatureCount()):
for j in range(ly2.GetFeatureCount()): #Create road
feat1 = ly1.GetFeature(i)
geom1 = feat1.GetGeometryRef()
points1 = geom1.GetPoints()
feat2 = ly2.GetFeature(j)
geom2 = feat2.GetGeometryRef()
points2 = geom2.GetPoints()
arcs[i] = [(points1[0],points1[1],geom1.Length()),feat1]
arcs[len(ly1)+j] = [(points2[0],points2[1],geom2.Length()),feat2]
#Create OD trips
if not points1[0] in allpoints.values():
allpoints[i] = [points1[0],geom1.Length(),feat1]
else:
allpoints[i] = [points1[1],geom1.Length(),feat1]
if not points2[0] in allpoints.values():
allpoints[len(ly1)+j] = [points2[0],geom1.Length(),feat1]
else:
allpoints[len(ly1)+j] = [points2[1],geom1.Length(),feat1]
#append kreuz
if points1[0] == points2[0] or points1[0] == points2[1]:
kreuz.append(points1[0])
elif points1[1] == points2[0] or points1[1] == points2[1]:
kreuz.append(points1[1])
G = nx.DiGraph() #Set a directed graph
for k,v in arcs.items():
G.add_edge(v[0][0],v[0][1], weight = v[0][2])
G.add_nodes_from(allpoints.values())
nx.floyd_warshall(G)
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos = pos, node_size=100)
nx.draw_networkx_edges(G, pos = pos)
plt.show()
and the result:
Result of second code
Is it a normal graph? And can anybody give some insights on how to calculate the shortest path right?
The networkx floyd_warshall calculates the shortest path for all pair of node in a graph and returns a dictionary as per the documentation.
distance (dict) – A dictionary, keyed by source and target, of shortest paths distances between nodes.
The algorithm does not change the graph in any way so by not storing the returned dictionary in a variable will do nothing.
To your question, you've already calculated the shortest paths, you simple doesn't do anything with them. If you wish to position the nodes in the plot according to some path length I don't think you're using an appropriate algorithm.

python concatenation in cycle partitioning

I understand that I can only concatenate things of similar types, but I'm really confused as to why the following are of different types.
this a part of my code:
import sys
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import gurobipy as GRB
def solveOptCyclePartition(diGraph):
# Create the Optimization Model
try:
m = GRB.Model("ctrlModel")
linkWeights = {}
for (u,v) in sorted(diGraph.edges(data=False)):
linkWeights[(u,v)] = diGraph[u][v]['weight']
#Create variables
e = m.addVars(sorted(diGraph.edges(data=False)),lb=0.0,ub=1.0,
obj=linkWeights , name="e")
# Add the objective function
m.setObjective( (e.prod(linkWeights)), GRB.MAXIMIZE)
#Add Constraint: One output edge from each node
m.addConstrs( (e.sum(i,'*') == 1 for i in nx.nodes(diGraph)), "outDegree")
#Add Constraint: One input edge from each node
m.addConstrs( (e.sum('*',i) == 1 for i in nx.nodes(diGraph)), "inDegree")
# Compute optimal solution
m.optimize()
# Print solution
if m.status == GRB.Status.OPTIMAL:
objOptimalVal = m.getAttr('objVal')
solution = m.getAttr('x', e)
for (u,v) in sorted(diGraph.edges(data=False)):
if solution[u,v] > 0:
print('%s -> %s: %g' % (u, v, solution[u,v]))
return objOptimalVal , solution
except:
print('Error reported')
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#def main():
# Network Adjacency Matrix
A = np.matrix([[0,0,0],
[1,0,0],
[1,0,1]])
G = nx.DiGraph()
G = nx.from_numpy_matrix(A)
# Check to see if connected
if nx.is_connected(G) == False:
print('The graph is not connected and has unaccessible nodes')
sys.exit(0)
# Nodes and Edge Lists
nodes = nx.nodes(G)
N = len(nodes)
edgeList = nx.to_edgelist(G)
# M Actuator nodes are selected randomly fron N nodes
M = 1;
augNodes = range(N,N+M)
actuatorNodes = sorted(list(np.random.permutation(np.arange(N))[:M]))
actuatorEdges = [(i,actuatorNodes[N-i],{'weight':1}) for i in augNodes ]
# Augmented edges lists and augmented graph
augEdgeList = (edgeList + actuatorEdges +
[(i,j,{'weight':0}) for i in nodes for j in augNodes] +
[(i,i,{'weight':0}) for i in nodes+augNodes if (i,i,{'weight':1}) not in edgeList])
Gprim = nx.DiGraph()
Gprim = nx.from_edgelist(augEdgeList,Gprim)
# Poljak Algorithm: Perform maximum weight cycle partitioning on
# augmented graph and return the optimal solution
objOptimalVal, solution = solveOptCyclePartition(Gprim)
plt.draw()
# Evaluate the solution
#if __name__ == '__main__':
# main()
I'm trying to solve cycle partitioning to find among all the partitions the one that encompasses the maximum number of edges with unit weight and satisfies the
following constraint. but i get this error:
*** TypeError: can only concatenate list (not "range") to list
Without the full stack trace it's hard to be sure exactly where this error is occurring, but I believe that it is happening on the following line:
[(i,i,{'weight':0}) for i in nodes+augNodes if (i,i,{'weight':1}) not in edgeList])
The particular section to pay attention to is nodes+augNodes.
The nodes variable contains the return value from calling networkx.nodes() which returns a list according to the documentation. augNodes on the other hand is being set to a range on the following line:
augNodes = range(N,N+M)
Since you can't append a range to a list, you're getting the TypeError that you see.

Categories