Example #1
0
    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]
Example #2
0
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
Example #3
0
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
Example #4
0
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