def __iter__(self): if self.buildNet: if self.symmetricNet: net = pynet.SymmNet() else: net = pynet.Net() if self.nodes == None: ktree = Ktree() else: ktree = Ktree(size=len(self.nodes), nodeNames=self.nodes) for edge in self.edges: if isinstance(edge, EvaluationEvent): if self.returnKtree: ktree.threshold = edge.threshold ktree.addedEdges = edge.addedElements yield ktree else: cs = ktree.getCommStruct() cs.threshold = edge.threshold cs.addedEdges = edge.addedElements if self.buildNet: cs.net = net yield cs else: ktree.addEdge(edge) if self.buildNet: net[edge[0], edge[1]] = edge[2]
def loadNet_gml(input): """ Reads a networks data from input in gml format. Note: This is not a complete gml-parser, because gml format can hold almost anykind of data. Instead this parser tries to find edges of one graph from the given input. Use at you own risk with complicated gml-files. """ source = None target = None value = None for line in input: line = line.strip() if line.startswith("directed"): if line[9:10] == "0": net = pynet.SymmNet() elif line[9:10] == "1": net = pynet.Net() elif line.startswith("source"): source = line.split()[1] elif line.startswith("target"): target = line.split()[1] elif line.startswith("value"): value = line.split()[1] elif line.startswith("edge"): if source != None and target != None: if value != None: net[source][target] = float(value) else: net[source][target] = 1 source = None target = None value = None if source != None and target != None: if value != None: net[source][target] = float(value) else: net[source][target] = 1 return net
def loadNet_edg(input, mutualEdges=False, splitterChar=None, symmetricNet=True, numerical=None, allowSelfEdges=True, hasHeaderLine=False): """Read network data from input in edg format. If `mutualEdges` is set to True, an edge is added between nodes i and j only if both edges (i,j) and (j,i) are listed. The weight of the edge is the sum of the weights of the original edges. If the same edge is encountered multiple times, the edge weight will be the sum of all weights. If 'allowSelfEdges', the self edges are translated as nodes with no edges. Otherwise those edges are just thrown out. If hasHeaderLine is True the first line is skipped, if it is False the first line is read normally, and if it is None the first line is skanned for "from to weight" string to decide if it is a header line. """ def isNumerical(input): try: for line in input: int(line.split(splitterChar)[0]) int(line.split(splitterChar)[1]) except ValueError: input.seek(0) return False input.seek(0) return True if numerical is None: numerical = isNumerical(input) if symmetricNet: newNet = pynet.SymmNet() else: newNet = pynet.Net() #Check for headers possibleHeaders = [["from", "to", "weight"], ["head", "tail", "weight"]] if hasHeaderLine != False: firstLine = input.readline().strip().lower() fields = firstLine.split(splitterChar) if hasHeaderLine == None and fields not in possibleHeaders: input.seek(0) if hasHeaderLine == True: input.seek(0) nodeMap = {} # Used only if mutualEdges = True. for line in input: fields = line.split(splitterChar) if len(fields) > 1: if len(fields) == 2: #if weight is missing: fields[1] = fields[1].strip( '\n') #strip the endline from the node name fields.append(1) #add one as the weight if fields[0] != fields[1] or allowSelfEdges: if numerical: fields[0] = int(fields[0]) fields[1] = int(fields[1]) if fields[0] != fields[1]: if mutualEdges: if nodeMap.has_key((fields[1], fields[0])): newNet[fields[0]][fields[1]] += nodeMap[( fields[1], fields[0])] newNet[fields[0]][fields[1]] += float(fields[2]) nodeMap[(fields[1], fields[0])] = 0 nodeMap[(fields[0], fields[1])] = 0 else: nodeMap[(fields[0], fields[1])] = nodeMap.get( (fields[0], fields[1]), 0) + float(fields[2]) else: newNet[fields[0]][fields[1]] += float(fields[2]) else: newNet.addNode(fields[0]) return newNet
def getLineGraph(net, useWeights=False, output=None, format='edg'): """Return a line graph constructed from `net`. The nodes in the line graph correspond to edges in the original graph, and there is an edge between two nodes if they have a common incident node in the original graph. If weights are not used (`useWeights = False`), the resulting network will be undirected and the weight of each new edge will be 1/(k_i-1), where k_i is the degree of the common node in `net`. If weights are used (`useWeights = True`), the resulting network will be directed and the weight of edge (e_ij, e_jk) will be w_jk/sum_{x != i} w_jx, where the indices i, j and k refer to nodes in `net`. Parameters ---------- net : pynet.SymmNet object The original graph that is used for constructing the line graph. useWeights : boolean If True, the edge weights will be used when constructing the line graph. output : file object If given, the edges will be written to output in edg-format instead of returning a pynet.Net() or pynet.SymmNet() object. format : str, 'edg' or 'net' If `output` is specified, `format` specifies how the output is written. 'edg' is the standard edge format (FROM TO WEIGHT) and 'net' gives the Pajek format. Return ------ IF `output` is None: linegraph : pynet.SymmNet or pynet.Net object The weighted line graph. id_array : numpy.array with shape (len(net.edges), 2) Array for converting the nodes in the line graph back into the edges of the original graph. id_array[EDGE_ID] contains the two end nodes of given edge, where EDGE_ID is the same as used in `linegraph`. """ if output is None: if useWeights: linegraph = pynet.Net() else: linegraph = pynet.SymmNet() edge_map = dict() # edge_map[sorted([n_i, n_j])] = new_node_ID if output is not None and format == 'net': # Print Pajek file header. N_edges = len(list(net.edges)) output.write("*Vertices %d\n" % N_edges) for i in range(N_edges): output.write('%d "%d"\n' % (i, i)) N_edge_links = 0 for n in net: degree = len(list(net[n])) N_edge_links += (degree * (degree - 1)) / 2 if useWeights: output.write("*Arcs %d\n" % (2 * N_edge_links, )) else: output.write("*Edges %d\n" % N_edge_links) # Go through all nodes (n_c = center node), and for each node, go # through all pairs of neighbours (n_i and n_j). The edges # e_i=(n_c,n_i) and e_j=(n_c,n_j) are nodes in the line graph, so # we add a link between them. for n_c in net: strength = net[n_c].strength() nb = list(net[n_c]) # List of neighbours for i, n_i in enumerate(nb): e_i = edge_map.setdefault(tuple(sorted([n_c, n_i])), len(edge_map)) other_nb = (nb[:i] + nb[i + 1:] if useWeights else nb[i + 1:]) for n_j in other_nb: e_j = edge_map.setdefault(tuple(sorted([n_c, n_j])), len(edge_map)) if useWeights: w = net[n_c][n_j] / (strength - net[n_c][n_i]) else: w = 1.0 / (len(nb) - 1) if output is None: linegraph[e_i][e_j] = w else: output.write(" ".join(map(str, [e_i, e_j, w])) + "\n") # Construct id_array from edge_map id_array = np.zeros((len(edge_map), 2), int) for node_pair, edgeID in edge_map.iteritems(): id_array[edgeID] = list(node_pair) if output is None: return linegraph, id_array else: return id_array