def build_graph(graph_data, weight_fxn): is_directed = False if 'directed' in graph_data: is_directed = graph_data['directed'] == 1 # TODO detect if graphs are bipartite and support that G = None if is_directed: G = DiGraph() else: G = Graph() # TODO: Load graph attributes # add nodes if 'node' in graph_data: nodes = graph_data['node'] if type(nodes) != list: raise ZenException, 'The node attribute of a graph must be a list' for node in nodes: # node must have an 'id' if 'id' not in node: raise ZenException, 'Node is missing the id attribute (node = %s)' % str( node) node_idx = node['id'] # collect and verify all the node properties standard_keys = set(['id', 'name', 'zenData']) node_data = {} node_obj = None zen_data = None for key, val in node.items(): if key == 'id': node_idx = val if type(val) != int or val < 0: raise ZenException, 'Node id attribute must be a positive integer (node = %s)' % str( node) elif key == 'name': node_obj = val if type(val ) != str: # enforce types on standard attributes raise ZenException, 'Node name attribute must be a string (node = %s)' % str( node) elif key == 'label': if node_obj is None: # give preference to 'name' as source of node_obj node_obj = val if type(val) != str: raise ZenException, 'Node label attribute must be a string (node = %s)' % str( node) elif key == 'zenData': zen_data = val else: node_data[ key] = val # node_data is dict of all other attributes # if zenData is only other attribute aside from those handled above _set_ to node_data else _append_ if zen_data is not None: if len(node_data) == 0: node_data = zen_data else: node_data['zenData'] = zen_data elif len(node_data) == 0: node_data = None if is_directed: G.add_node_x(node_idx, G.edge_list_capacity, G.edge_list_capacity, node_obj, node_data) else: G.add_node_x(node_idx, G.edge_list_capacity, node_obj, node_data) # add edges if 'edge' in graph_data: edges = graph_data['edge'] if type(edges) != list: raise ZenException, 'The edge attibute of a graph must be a list' for edge in edges: # make sure source and target are specified source = None target = None if 'source' not in edge: raise ZenException, 'Edge is missing the source attribute (edge = %s)' % str( edge) if 'target' not in edge: raise ZenException, 'Edge is missing the target attribute (edge = %s)' % str( edge) weight = 1 edge_idx = None zen_data = None edge_data = {} for key, val in edge.items(): if key == 'id': edge_idx = val if type(val) != int: raise ZenException, 'Edge id attribute must be a positive integer (edge = %s)' % str( edge) elif key == 'source': source = val if type(val) != int or val < 0: raise ZenException, 'Edge source attribute must be a positive integer (edge = %s)' % str( edge) elif key == 'target': target = val if type(val) != int or val < 0: raise ZenException, 'Edge target attribute must be a positive integer (edge = %s)' % str( edge) elif key == 'weight': weight = float(val) elif key == 'zenData': zen_data = val else: edge_data[ key] = val # edge_data is dict of all other attributes # give precedence to a weight-getting function if provided if weight_fxn != None: weight = weight_fxn(edge) # if zenData is only other attribute aside from those handled above _set_ to edge_data else _append_ if zen_data is not None: if len(edge_data) == 0: edge_data = zen_data else: edge_data['zenData'] = zen_data elif len(edge_data) == 0: edge_data = None if edge_idx != None: G.add_edge_x(edge_idx, source, target, edge_data, weight) else: G.add_edge_(source, target, edge_data, weight) return G
def read_str(sbuffer, **kwargs): """ Read graph data from the ascii string in the binary edge list format. **Args**: ``sbuffer`` is the string from which the network data will be read. **KwArgs**: * ``node_obj_fxn [= str]``: unlike the default definition, this function accepts integers and returns the node object * ``directed [= False]`` (boolean): indicates whether the data is read as directed * ``ignore_duplicate_edges [= False]`` (boolean): applies only when loading an undirected graph. If True, then a check will be made to ensure that no duplicate edges are attempted to be added (in case the underlying graph was originally directed). Checking incurs a small performance cost due to the check. **Returns**: :py:class:`zen.Graph` or :py:class:`zen.DiGraph`. The graph read from the input string. The ``directed`` parameter decides whether a directed or undirected graph is constructed. """ # handle the keyword arguments node_obj_fxn = kwargs.pop('node_obj_fxn', str) directed = kwargs.pop('directed', False) check_for_duplicates = kwargs.pop('ignore_duplicate_edges', False) if len(kwargs) > 0: raise ZenException, 'Unknown keyword arguments: %s' % ', '.join( kwargs.keys()) if check_for_duplicates and directed: raise ZenException, 'ignore_duplicate_edges can only be set when directed = False' # build the graph G = None if directed == True: G = DiGraph() elif directed == False: G = Graph() else: raise ZenException, 'directed must be either True or False.' ##### # convert the string into a bitvector bv = BitVector(size=len(sbuffer) * 8) offset = 0 for c in sbuffer: v = ord(c) dec2bv(v, bv, offset, 8) offset += 8 ##### # read the header offset = 0 # read the version version = bv2dec(bv, offset, VERSION_LEN) offset += VERSION_LEN if version != 1: raise Exception, 'Invalid file format or version number' # read the num of indexes last_idx = bv2dec(bv, offset, NUM_INDEX_LEN) idx_size = int(math.ceil(math.log(last_idx + 1, 2))) offset += NUM_INDEX_LEN idx2node = [None] * (last_idx + 1) # build all nodes right now if node_obj_fxn is not None: for x in xrange(last_idx + 1): n = node_obj_fxn(x) G.add_node(n) else: G.add_nodes(last_idx + 1) # read the number of edges num_edges = bv2dec(bv, offset, NUM_EDGES_LEN) offset += NUM_EDGES_LEN ##### # Read the content: every edge if directed: for ei in xrange(num_edges): idx1 = bv2dec(bv, offset, idx_size) offset += idx_size idx2 = bv2dec(bv, offset, idx_size) offset += idx_size G.add_edge_(idx1, idx2) else: for ei in xrange(num_edges): idx1 = bv2dec(bv, offset, idx_size) offset += idx_size idx2 = bv2dec(bv, offset, idx_size) offset += idx_size if check_for_duplicates and G.has_edge_(idx1, idx2): continue G.add_edge_(idx1, idx2) # done! return G
def read_str(sbuffer, **kwargs): #node_fxn=lambda x: x, edge_fxn=None, G = UNDIRECTED, build_all_nodes = False): """ Read graph data from the ascii string in the binary edge list format. """ # handle the keyword arguments node_obj_fxn = kwargs.pop('node_obj_fxn',str) directed = kwargs.pop('directed',False) check_for_duplicates = kwargs.pop('check_for_duplicates',False) if len(kwargs) > 0: raise ZenException, 'Unknown keyword arguments: %s' % ', '.join(kwargs.keys()) if check_for_duplicates and directed: raise ZenException, 'check_for_duplicates can only be set when directed = False' # build the graph G = None if directed == True: G = DiGraph() elif directed == False: G = Graph() else: raise ZenException, 'directed must be either True or False.' ##### # convert the string into a bitvector bv = BitVector(size = len(sbuffer) * 8) offset = 0 for c in sbuffer: v = ord(c) dec2bv(v,bv,offset,8) offset += 8 ##### # read the header offset = 0 # read the version version = bv2dec(bv,offset,VERSION_LEN) offset += VERSION_LEN if version != 1: raise Exception, 'Invalid file format or version number' # read the num of indexes last_idx = bv2dec(bv,offset,NUM_INDEX_LEN) idx_size = int(math.ceil(math.log(last_idx+1,2))) offset += NUM_INDEX_LEN idx2node = [None] * (last_idx + 1) # build all nodes right now if node_obj_fxn is not None: for x in xrange(last_idx+1): n = node_obj_fxn(x) G.add_node(n) else: G.add_nodes(last_idx+1) # read the number of edges num_edges = bv2dec(bv,offset,NUM_EDGES_LEN) offset += NUM_EDGES_LEN ##### # Read the content: every edge if directed: for ei in xrange(num_edges): idx1 = bv2dec(bv,offset,idx_size) offset += idx_size idx2 = bv2dec(bv,offset,idx_size) offset += idx_size G.add_edge_(idx1,idx2) else: for ei in xrange(num_edges): idx1 = bv2dec(bv,offset,idx_size) offset += idx_size idx2 = bv2dec(bv,offset,idx_size) offset += idx_size if check_for_duplicates and G.has_edge_(idx1,idx2): continue G.add_edge_(idx1,idx2) # done! return G
def read_str(sbuffer, **kwargs): """ Read graph data from the ascii string in the binary edge list format. **Args**: ``sbuffer`` is the string from which the network data will be read. **KwArgs**: * ``node_obj_fxn [= str]``: unlike the default definition, this function accepts integers and returns the node object * ``directed [= False]`` (boolean): indicates whether the data is read as directed * ``ignore_duplicate_edges [= False]`` (boolean): applies only when loading an undirected graph. If True, then a check will be made to ensure that no duplicate edges are attempted to be added (in case the underlying graph was originally directed). Checking incurs a small performance cost due to the check. **Returns**: :py:class:`zen.Graph` or :py:class:`zen.DiGraph`. The graph read from the input string. The ``directed`` parameter decides whether a directed or undirected graph is constructed. """ # handle the keyword arguments node_obj_fxn = kwargs.pop('node_obj_fxn',str) directed = kwargs.pop('directed',False) check_for_duplicates = kwargs.pop('ignore_duplicate_edges',False) if len(kwargs) > 0: raise ZenException, 'Unknown keyword arguments: %s' % ', '.join(kwargs.keys()) if check_for_duplicates and directed: raise ZenException, 'ignore_duplicate_edges can only be set when directed = False' # build the graph G = None if directed == True: G = DiGraph() elif directed == False: G = Graph() else: raise ZenException, 'directed must be either True or False.' ##### # convert the string into a bitvector bv = BitVector(size = len(sbuffer) * 8) offset = 0 for c in sbuffer: v = ord(c) dec2bv(v,bv,offset,8) offset += 8 ##### # read the header offset = 0 # read the version version = bv2dec(bv,offset,VERSION_LEN) offset += VERSION_LEN if version != 1: raise Exception, 'Invalid file format or version number' # read the num of indexes last_idx = bv2dec(bv,offset,NUM_INDEX_LEN) idx_size = int(math.ceil(math.log(last_idx+1,2))) offset += NUM_INDEX_LEN idx2node = [None] * (last_idx + 1) # build all nodes right now if node_obj_fxn is not None: for x in xrange(last_idx+1): n = node_obj_fxn(x) G.add_node(n) else: G.add_nodes(last_idx+1) # read the number of edges num_edges = bv2dec(bv,offset,NUM_EDGES_LEN) offset += NUM_EDGES_LEN ##### # Read the content: every edge if directed: for ei in xrange(num_edges): idx1 = bv2dec(bv,offset,idx_size) offset += idx_size idx2 = bv2dec(bv,offset,idx_size) offset += idx_size G.add_edge_(idx1,idx2) else: for ei in xrange(num_edges): idx1 = bv2dec(bv,offset,idx_size) offset += idx_size idx2 = bv2dec(bv,offset,idx_size) offset += idx_size if check_for_duplicates and G.has_edge_(idx1,idx2): continue G.add_edge_(idx1,idx2) # done! return G
def build_graph(graph_data,weight_fxn): is_directed = False if 'directed' in graph_data: is_directed = graph_data['directed'] == 1 # TODO detect if graphs are bipartite and support that G = None if is_directed: G = DiGraph() else: G = Graph() # TODO: Load graph attributes # add nodes if 'node' in graph_data: nodes = graph_data['node'] if type(nodes) != list: raise ZenException, 'The node attribute of a graph must be a list' for node in nodes: # node must have an 'id' if 'id' not in node: raise ZenException, 'Node is missing the id attribute (node = %s)' % str(node) node_idx = node['id'] # collect and verify all the node properties standard_keys = set(['id', 'name', 'zenData']) node_data = {} node_obj = None zen_data = None for key, val in node.items(): if key == 'id': node_idx = val if type(val) != int or val < 0: raise ZenException, 'Node id attribute must be a positive integer (node = %s)' % str(node) elif key == 'name': node_obj = val if type(val) != str: # enforce types on standard attributes raise ZenException, 'Node name attribute must be a string (node = %s)' % str(node) elif key == 'label': if node_obj is None: # give preference to 'name' as source of node_obj node_obj = val if type(val) != str: raise ZenException, 'Node label attribute must be a string (node = %s)' % str(node) elif key == 'zenData': zen_data = val else: node_data[key] = val # node_data is dict of all other attributes # if zenData is only other attribute aside from those handled above _set_ to node_data else _append_ if zen_data is not None: if len(node_data) == 0: node_data = zen_data else: node_data['zenData'] = zen_data elif len(node_data) == 0: node_data = None if is_directed: G.add_node_x(node_idx,G.edge_list_capacity,G.edge_list_capacity,node_obj,node_data) else: G.add_node_x(node_idx,G.edge_list_capacity,node_obj,node_data) # add edges if 'edge' in graph_data: edges = graph_data['edge'] if type(edges) != list: raise ZenException, 'The edge attibute of a graph must be a list' for edge in edges: # make sure source and target are specified source = None target = None if 'source' not in edge: raise ZenException, 'Edge is missing the source attribute (edge = %s)' % str(edge) if 'target' not in edge: raise ZenException, 'Edge is missing the target attribute (edge = %s)' % str(edge) weight = 1 edge_idx = None zen_data = None edge_data = {} for key, val in edge.items(): if key == 'id': edge_idx = val if type(val) != int: raise ZenException, 'Edge id attribute must be a positive integer (edge = %s)' % str(edge) elif key == 'source': source = val if type(val) != int or val < 0: raise ZenException, 'Edge source attribute must be a positive integer (edge = %s)' % str(edge) elif key == 'target': target = val if type(val) != int or val < 0: raise ZenException, 'Edge target attribute must be a positive integer (edge = %s)' % str(edge) elif key == 'weight': weight = float(val) elif key == 'zenData': zen_data = val else: edge_data[key] = val # edge_data is dict of all other attributes # give precedence to a weight-getting function if provided if weight_fxn != None: weight = weight_fxn(edge) # if zenData is only other attribute aside from those handled above _set_ to edge_data else _append_ if zen_data is not None: if len(edge_data) == 0: edge_data = zen_data else: edge_data['zenData'] = zen_data elif len(edge_data) == 0: edge_data = None; if edge_idx != None: G.add_edge_x(edge_idx,source,target,edge_data,weight) else: G.add_edge_(source,target,edge_data,weight) return G