Exemple #1
0
def build_cooc_graph(coDic, posMap):
    '''    
    Converts a dictionary keeping word-word co-occurrences to a graph object where the edge weight
    between nodes (words) corresponds to their co-occurrence.

    Args:
        coOcDic: A dictionary where keys are tuples with 2 elements, (string1, string2) corresponding to the co-occurrence of two words. 
        The corresponding value is an integer capturing the times the co-occurrence happened (e.g., through out a book).
        posMap: A dictionary from word to Part Of Speech.
    Returns:
        A graph object.
    
    '''
    g = Graph(directed=False)
    wordToNodeID = dict(
    )  #maps a word to the ID of the node that it will be stored
    eWeight = g.new_edge_property(
        "int")  #edges have weights capturing number of co-occurrences
    words = g.new_vertex_property(
        "object"
    )  #keep for each node the (potentially unicode) corresponding word as an attribute
    POS = g.new_vertex_property("string")  #keep the Part Of Speech
    nodeID = 0
    for word1, word2 in coDic.keys(
    ):  #Each key is a (noun, noun) string. It will become an edge
        if word1 not in wordToNodeID:
            wordToNodeID[word1] = nodeID
            v = g.add_vertex()
            assert (str(v) == str(nodeID))
            words[v] = word1
            POS[v] = posMap[word1]
            nodeID += 1
        if word2 not in wordToNodeID:
            wordToNodeID[word2] = nodeID
            v = g.add_vertex()
            assert (str(v) == str(nodeID))
            words[v] = word2
            POS[v] = posMap[word2]
            nodeID += 1
        source = wordToNodeID[word1]
        target = wordToNodeID[word2]
        e = g.add_edge(source, target)
        eWeight[e] = coDic[(word1, word2)]

    g.edge_properties["co-occurrence"] = eWeight
    g.vertex_properties["word"] = words
    g.vertex_properties["partOfSpeach"] = POS

    #Encode the POS as a short number
    POS_encoded = g.new_vertex_property("short")
    posEncoder = part_of_speech_int_map(posToInt=True)

    for v in g.vertices():
        POS_encoded[v] = posEncoder[POS[v][0]]

    g.vertex_properties["partOfSpeach_encoded"] = POS_encoded

    return g
def compose_graph(uid_pid_pairs):

    # set up graph
    g = Graph()
    g.vp['pid'] = v_pid_p = g.new_vertex_property('string')
    g.vp['count'] = v_count_p = g.new_vertex_property('int')
    g.ep['count'] = e_count_p = g.new_edge_property('int')

    pid_v_map = {}
    uid_last_v_map = {}
    vv_e_map = {}

    for uid, pid in uid_pid_pairs:

        # vertex

        v = pid_v_map.get(pid)
        if v is None:
            v = g.add_vertex()
            v_pid_p[v] = pid
            v_count_p[v] = 0
            pid_v_map[pid] = v
        v_count_p[v] += 1

        # edge

        last_v = uid_last_v_map.get(uid)
        uid_last_v_map[uid] = v
        if last_v is None:
            continue

        vv = (last_v, v)
        e = vv_e_map.get(vv)
        if e is None:
            e = g.add_edge(*vv)
            e_count_p[e] = 0
            vv_e_map[vv] = e
        e_count_p[e] += 1

    # calculate closeness
    g.vp['closeness'] = v_closeness_p = g.new_vertex_property('float')
    e_inverse_count_p = g.new_edge_property('int')
    e_inverse_count_p.a = e_count_p.a.max()-e_count_p.a
    debug('e_inverse_count_p.a: {}', e_inverse_count_p.a)
    closeness(g, weight=e_inverse_count_p, vprop=v_closeness_p)
    debug('v_closeness_p.a    : {}', v_closeness_p.a)
    v_closeness_p.a = nan_to_num(v_closeness_p.a)
    debug('v_closeness_p.a    : {}', v_closeness_p.a)

    # fillter
    g.vp['picked'] = v_picked_p = g.new_vertex_property('bool')
    debug('v_count_p.a.mean() : {}', v_count_p.a.mean())
    v_picked_p.a = v_count_p.a > v_count_p.a.mean()
    debug('v_picked_p.a       : {}', v_picked_p.a)
    g.set_vertex_filter(v_picked_p)
    g.set_vertex_filter(None)

    return g
Exemple #3
0
class Network:
    def __init__(self):
        self.g = Graph(directed=True)
        self.player_id_to_vertex = {}
        self.pairs = {}
        self.g.vertex_properties['player_id'] =
            self.g.new_vertex_property("string")
        self.g.vertex_properties['player_coords'] =
            self.g.new_vertex_property("vector<float>")
Exemple #4
0
def main():
    """
    Visualizes the research network of KTH as a graph.
    """
    start_time = time()

    # Create our undirected graph to return.
    g = Graph(directed=False)
    # The edge properties measuring collaboration.
    e_times = g.new_edge_property("float")
    # Grouping value for the verticies, verticies are in the same group if the
    # have the same value.
    v_groups = g.new_vertex_property("int")
    # Color the verticies based on their faculties colors.
    v_colors = g.new_vertex_property("vector<double>")

    db_path = '/home/_/kth/kexet/db/kex.db'
    query = """SELECT *
               FROM final
               WHERE (
                 name LIKE '%kth%' and
                 name LIKE '%;%' and
                 keywords is not null and
                 year >= 2013 and
                 ContentType = 'Refereegranskat' and
                 PublicationType = 'Artikel i tidskrift'
               );"""
    rows = load.rows(db_path, query)
    for row in rows:
        nobjs = parse.names(row['name'].split(';'))
        graph.add_relation(g, nobjs, e_times, v_colors, v_groups)

    g.edge_properties["times"] = e_times
    g.vertex_properties["colors"] = v_colors
    g.vertex_properties["groups"] = v_groups

    log.info(g.num_vertices())
    log.info(g.num_edges())
    g.save('a.gt')
    log.info('graph saved: a.gt')
    log.info("db & parse %ss" % round(time() - start_time, 2))

    # start_time = time()
    # g = load_graph('a.gt')
    # log.info("loading %ss" % round(time() - start_time, 2))

    draw.largest(g.copy())
    draw.radial_highest(g.copy())
    draw.sfdp(g.copy())
    draw.grouped_sfdp(g.copy())
    draw.min_tree(g.copy())
    draw.radial_random(g.copy())
    draw.hierarchy(g.copy())
    draw.minimize_blockmodel(g.copy())
    draw.netscience(g.copy())
    draw.fruchterman(g.copy())
Exemple #5
0
    def draw_game_flow(self, model: GameModel):
        self.log.debug('drawing game flow for model {0}'.format(model.name))
        TMPUTILS.clear_container(self.game_flow_panel)

        all_phases = [
            phase for pt in [model.table_type] + model.player_types
            for phase in pt.phases
        ]
        phase_phase = {}
        for phase in all_phases:
            phase_phase[phase] = list(TMPUTILS.end_phases(phase))

        graph = Graph()
        graph.vp.name = graph.new_vertex_property('string')
        graph.vp.color = graph.new_vertex_property('string')
        graph.vp.text_pos = graph.new_vertex_property('float')
        graph.vp.text_off = graph.new_vertex_property('vector<float>')
        phase_vertex = {}
        for phase in all_phases:
            vertex = graph.add_vertex()
            phase_vertex[phase] = vertex
            text = phase.name
            graph.vp.name[vertex] = text
            if phase is model.start_phase:
                color = self.config.start_game_color()
            elif phase is model.end_phase:
                color = self.config.end_game_color()
            elif phase in model.table_type.phases:
                color = self.config.table_color()
            else:
                number = model.player_types.index(
                    model.get_player_type_for_phase(phase))
                color = self.config.player_color(number)
            graph.vp.color[vertex] = color
            graph.vp.text_pos[vertex] = 0
            graph.vp.text_off[vertex] = [0, 0]

        for phase in all_phases:
            for other in phase_phase[phase]:
                graph.add_edge(phase_vertex[phase], phase_vertex[other])

        pos = sfdp_layout(graph)

        vprops = {
            'text': graph.vp.name,
            'fill_color': graph.vp.color,
            'text_position': graph.vp.text_pos,
            'text_offset': graph.vp.text_off
        }

        graph_widget = GraphWidget(graph, pos, vprops=vprops, vertex_size=50)
        self.game_flow_panel.pack_start(Gtk.Label('gameflow'), False, False, 0)
        self.game_flow_panel.pack_start(graph_widget, True, True, 0)
        self.show_all()
Exemple #6
0
def gt_subgraph(g: gt.Graph, vertices):
    filter_option = g.new_vertex_property('bool')
    for v in vertices:
        filter_option[v] = True
    sub = gt.GraphView(g, filter_option).copy()

    return sub
Exemple #7
0
    def __init__(self, state: SampleState, graph: Graph,
                 old_true_block_assignment: np.ndarray) -> None:
        """Creates a new Sample object. Contains information about the sampled vertices and edges, the mapping of
        sampled vertices to the original graph vertices, and the true block membership for the sampled vertices.

        Parameters
        ----------
        state : SampleState
            contains the sampled vertices
        graph : Graph
            the graph from which the sample is taken
        old_true_block_assignment : np.ndarray[int]
            the vertex-to-community assignment array. Currently assumes that community assignment is non-overlapping.
        """
        self.state = state
        sampled_vertices = sorted(state.sample_idx[-state.sample_size:])
        self.vertex_mapping = dict([(v, k)
                                    for k, v in enumerate(sampled_vertices)])
        binary_filter = np.zeros(graph.num_vertices())
        binary_filter[sampled_vertices] = 1
        graph.set_vertex_filter(
            graph.new_vertex_property("bool", binary_filter))
        self.graph = Graph(
            graph, prune=True
        )  # If ordering is wacky, may need to play around with vorder
        graph.clear_filters()
        true_block_assignment = old_true_block_assignment[sampled_vertices]
        # Assuming the sample doesn't capture all the blocks, the block numbers in the sample may not be consecutive
        # The true_blocks_mapping ensures that they are consecutive
        true_blocks = list(set(true_block_assignment))
        self.true_blocks_mapping = dict([(v, k)
                                         for k, v in enumerate(true_blocks)])
        self.true_block_assignment = np.asarray(
            [self.true_blocks_mapping[b] for b in true_block_assignment])
        self.sample_num = len(self.vertex_mapping)
def build_closure(g, terminals, debug=False, verbose=False):
    terminals = list(terminals)
    # build closure
    gc = Graph(directed=False)
    gc.add_vertex(g.num_vertices())

    edges_with_weight = set()
    r2pred = {}

    for r in terminals:
        if debug:
            print('root {}'.format(r))
        vis = init_visitor(g, r)
        pbfs_search(g, source=r, terminals=terminals, visitor=vis)
        new_edges = set(get_edges(vis.dist, r, terminals))
        if debug:
            print('new edges {}'.format(new_edges))
        edges_with_weight |= new_edges
        r2pred[r] = vis.pred

    for u, v, c in edges_with_weight:
        gc.add_edge(u, v)

    eweight = gc.new_edge_property('int')
    weights = np.array([c for _, _, c in edges_with_weight])
    eweight.set_2d_array(weights)

    vfilt = gc.new_vertex_property('bool')
    vfilt.a = False
    for v in terminals:
        vfilt[v] = True
    gc.set_vertex_filter(vfilt)
    return gc, eweight, r2pred
Exemple #9
0
class RoadMap(object):
    def __init__(self, mapfile):
        self._mapfile = mapfile
        self.DIRECTION_index = 6
        self.PATHCLASS_index = 20
        self.g = Graph()
        self.g.edge_properties["length"] = self.g.new_edge_property("double")
        self.g.edge_properties["level"] = self.g.new_edge_property("int")
        self.g.vertex_properties["pos"] = self.g.new_vertex_property("vector<double>")
        self.cross_pos_index = {}

    def load(self):
        if self._mapfile[-3:] != 'shp':
            self.g = load_graph(self._mapfile)
            return

        try:
            sf = shapefile.Reader(self._mapfile)
        except Exception as e:
            print(str(e))
            return False
        roads_records = sf.shapeRecords()  # 获取路段信息'
        for road_record in roads_records:
            cross_s_index = self.add_cross(road_record.shape.points[0])
            cross_e_index = self.add_cross(road_record.shape.points[-1])
            self.add_road_edge(cross_s_index, cross_e_index, road_record)
            if int(road_record.record[self.DIRECTION_index]) == 0:  # 若路段是双向车道
                self.add_road_edge(cross_e_index, cross_s_index, road_record)
        return True

    def has_edge(self, s_vertex, e_vertex):
        if self.g.num_vertices() >= max(s_vertex, e_vertex):
            return self.g.edge(s_vertex, e_vertex)
        else:
            return None

    def add_cross(self, cross_pos):
        if cross_pos in self.cross_pos_index:
            return self.cross_pos_index.get(cross_pos)
        else:
            cross_index = self.g.add_vertex()
            self.g.vp.pos[cross_index] = cross_pos
            self.cross_pos_index[cross_pos] = cross_index
            return cross_index

    def add_road_edge(self, s_vertex, e_vertex, road):
        if self.has_edge(s_vertex, e_vertex):
            return self.g.edge(s_vertex, e_vertex)
        else:
            edge = self.g.add_edge(s_vertex, e_vertex)
            self.g.ep.level[edge] = int(road.record[self.PATHCLASS_index])
            self.g.ep.length[edge] = self.road_length(road)
            return edge

    @staticmethod
    def road_length(road):
        length = 0
        for sub_road in zip(road.shape.points[:-1], road.shape.points[1:]):
            length += distance.euclidean(sub_road[0], sub_road[1])
        return length
Exemple #10
0
def balancedBinaryTree(h, drawGraph=False):
    '''
    h - the height of the tree
    '''
    g = Graph(directed=False)
    g.add_vertex(2**h - 1)

    for i in xrange(1, 2**(h - 1)):
        lc = 2 * i - 1
        rc = lc + 1
        g.add_edge(i - 1, lc)
        g.add_edge(i - 1, rc)

    hIndex = g.new_vertex_property(
        "int")  #associate with each node the height at which it lies
    k = 2
    m = 1
    for i in xrange(1, len(hIndex.a)):
        hIndex.a[i] = m
        k -= 1
        if k == 0:
            m += 1
            k = 2**m
    g.vp['height'] = hIndex

    if drawGraph == True:
        draw.graph_draw(g,
                        vertex_text=g.vertex_index,
                        edge_color="black",
                        output="binaryTree_h_" + str(h) + "_.pdf")

    return g
Exemple #11
0
def partition_from_truth(graph: Graph,
                         true_membership: np.ndarray) -> BlockState:
    """Creates the BlockState for a graph using the true community membership.

    Parameters
    ----------
    graph : Graph
        the graph for which the partiion is being created
    true_membership : np.ndarray[int]
        the true vertex-to-community membership array

    Returns
    -------
    partition : BlockState
        the partition created from the true community membership for the given graph

    Notes
    -----
    Assumes that that the community membership is non-overlapping.
    """
    assignment_property_map = graph.new_vertex_property("int", val=-1)
    assignment_property_map.a = true_membership
    partition = BlockState(graph, assignment_property_map,
                           np.max(true_membership) + 1)
    return partition
Exemple #12
0
def import_St_Mark_Data(save=True, export=True):

    saveLoadFolder = "StMarks"
    graphName = "StMarks"
    graphFile = "../Data/Graphs/" + saveLoadFolder + "/StMarks_adjusted_raw.txt"

    g = Graph(directed=False)
    with open(graphFile, "r") as inF:
        num_nodes = int(inF.readline().split()[0])
        g.add_vertex(num_nodes)
        for line in inF:
            if line[0] == "*": break
            node1, node2, unk = line.split()
            fromE, toE = int(node1) - 1, int(node2) - 1
            g.add_edge(fromE, toE)

        gMass = g.new_vertex_property("double")  #Read-record Bio-mass
        for i, line in enumerate(inF):
            gMass[g.vertex(i)] = float(line.split()[0])

    trophicF = graphFile = "../Data/Graphs/" + saveLoadFolder + "/10_Isotrophic_Groups.txt"

    troClass = g.new_vertex_property("int")  #Read-record Trophic Classes

    with open(trophicF, "r") as inF:
        for i, line in enumerate(inF):
            classMembers = line.split(",")
            for m in classMembers:
                troClass.a[int(m) - 1] = i


#                 print m, troClass.a[int(m)-1]

    g.vp["mass"] = gMass
    g.vp["trophicClass"] = troClass

    g = graph_analysis.IO.make_simple_graph(g, undirected=True, gcc=True)

    if save:
        graph_analysis.IO.save_data(
            "../Data/Graphs/" + saveLoadFolder + "/" + graphName + ".GT.graph",
            g)
    if export:
        exportToSnapAndGreach(graphName, saveLoadFolder)

    return g
def steiner_tree_greedy(
        g, root, infection_times, source, obs_nodes,
        debug=False,
        verbose=True):
    # root = min(obs_nodes, key=infection_times.__getitem__)
    sorted_obs = list(sorted(obs_nodes, key=infection_times.__getitem__))[1:]
    tree_nodes = {root}
    tree_edges = set()
    for u in sorted_obs:
        # connect u to the tree
        vis = init_visitor(g, u)
        if debug:
            print('connect {} to tree'.format(u))
            print('nodes connectable: {}'.format(tree_nodes))
        forbidden_nodes = list(set(obs_nodes) - tree_nodes)
        cpbfs_search(g, u, visitor=vis,
                     terminals=list(tree_nodes),
                     forbidden_nodes=forbidden_nodes,
                     count_threshold=1)

        # add edge
        reachable_nodes = set(np.nonzero(vis.dist > 0)[0]).intersection(tree_nodes)

        if debug:
            print('reachable_nodes: {}'.format(reachable_nodes))

        assert len(reachable_nodes) > 0
        sorted_ancestors = sorted(reachable_nodes, key=vis.dist.__getitem__)
        ancestor = sorted_ancestors[0]

        if debug:
            print('ancestor: {}'.format(ancestor))
            print('dist to reachable: {}'.format(vis.dist[sorted_ancestors]))

        new_edges = extract_edges_from_pred(g, u, ancestor, vis.pred)
        new_edges = {(v, u) for u, v in new_edges}  # needs to reverse the order

        if debug:
            print('new_edges: {}'.format(new_edges))

        tree_edges |= set(new_edges)
        tree_nodes |= {v for e in new_edges for v in e}

    t = Graph(directed=True)
    for _ in range(g.num_vertices()):
        t.add_vertex()

    vfilt = t.new_vertex_property('bool')
    vfilt.a = False
    for v in tree_nodes:
        vfilt[t.vertex(v)] = True

    for u, v in tree_edges:
        t.add_edge(t.vertex(u), t.vertex(v))

    t.set_vertex_filter(vfilt)

    return t
def build_closure(g, terminals, p=None, debug=False, verbose=False):
    """build the transitive closure on terminals"""
    def get_edges(dist, root, terminals):
        """get adjacent edges to root with weight"""
        return {(root, t, dist[t])
                for t in terminals if dist[t] != -1 and t != root}

    terminals = list(terminals)
    gc = Graph(directed=False)

    gc.add_vertex(g.num_vertices())

    edges_with_weight = set()
    r2pred = {}  # root to predecessor map (from bfs)

    # shortest path to all other nodes
    for r in terminals:
        if debug:
            print('root {}'.format(r))

        targets = list(set(terminals) - {r})
        dist_map, pred_map = shortest_distance(g,
                                               source=r,
                                               target=targets,
                                               weights=p,
                                               pred_map=True)
        dist_map = dict(zip(targets, dist_map))
        # print(dist_map)
        # print(pred_map)
        new_edges = get_edges(dist_map, r, targets)
        # if p is None:
        #     vis = init_visitor(g, r)
        #     bfs_search(g, source=r, visitor=vis)
        #     new_edges = set(get_edges(vis.dist, r, terminals))
        # else:
        #     print('weighted graph')

        if debug:
            print('new edges {}'.format(new_edges))
        edges_with_weight |= new_edges
        # r2pred[r] = vis.pred
        r2pred[r] = pred_map

    for u, v, c in edges_with_weight:
        gc.add_edge(u, v)

    # edge weights
    eweight = gc.new_edge_property('int')
    weights = np.array([c for _, _, c in edges_with_weight])
    eweight.set_2d_array(weights)

    vfilt = gc.new_vertex_property('bool')
    vfilt.a = False
    for v in terminals:
        vfilt[v] = True
    gc.set_vertex_filter(vfilt)
    return gc, eweight, r2pred
Exemple #15
0
    def create_sample(graph: Graph, old_true_block_assignment: np.ndarray,
                      args: argparse.Namespace,
                      prev_state: SampleState) -> 'Sample':
        """Performs sampling according to the sample type in args.

        TODO: either re-write how this method is used, or get rid of it - it seems to be a code smell.
        """
        # get rid of 1-degree vertices
        degrees = graph.get_total_degrees(np.arange(graph.num_vertices()))
        degree_filter = degrees > 2
        mapping = np.where(degrees > 2)[0]
        graph.set_vertex_filter(
            graph.new_vertex_property("bool", degree_filter))
        filtered_graph = Graph(graph, prune=True)
        print(filtered_graph.num_vertices())
        graph.clear_filters()
        # TODO: keep track of the mapping to original graph
        # TODO: below methods can return a SampleState, which we map back to original vertices here, then create the
        # sample before return. This is brilliant! I am genius!
        if args.sample_type == "degree_weighted":
            state = Sample.degree_weighted_sample(filtered_graph,
                                                  graph.num_vertices(),
                                                  prev_state, args)
        elif args.sample_type == "expansion_snowball":
            state = Sample.expansion_snowball_sample(filtered_graph,
                                                     graph.num_vertices(),
                                                     prev_state, args)
        elif args.sample_type == "forest_fire":
            state = Sample.forest_fire_sample(filtered_graph,
                                              graph.num_vertices(), prev_state,
                                              args)
        elif args.sample_type == "max_degree":
            state = Sample.max_degree_sample(filtered_graph,
                                             graph.num_vertices(), prev_state,
                                             args)
        elif args.sample_type == "random_jump":
            state = Sample.random_jump_sample(filtered_graph,
                                              graph.num_vertices(), prev_state,
                                              args)
        elif args.sample_type == "random_node_neighbor":
            state = Sample.random_node_neighbor_sample(filtered_graph,
                                                       graph.num_vertices(),
                                                       prev_state, args)
        elif args.sample_type == "random_walk":
            state = Sample.random_walk_sample(filtered_graph,
                                              graph.num_vertices(), prev_state,
                                              args)
        elif args.sample_type == "uniform_random":
            state = Sample.uniform_random_sample(filtered_graph,
                                                 graph.num_vertices(),
                                                 prev_state, args)
        else:
            raise NotImplementedError(
                "Sample type: {} is not implemented!".format(args.sample_type))
        state.sample_idx = mapping[state.sample_idx]
        return Sample(state, graph, old_true_block_assignment)
Exemple #16
0
def import_carribean_food_web_graph(save=True, export=True):
    saveLoadFolder = "Carribean_FoodWeb"
    graphFile = saveLoadPath + saveLoadFolder + "/Carribean_Adjacency_Matrix_raw.txt"
    g = Graph(directed=False)
    edgeWeights = g.new_edge_property("double")
    counter = -1

    with open(graphFile, "r") as inF:
        for line in inF:
            if line[0] == "#":  # This line is a header. Skip it.
                continue

            if counter == -1:  # First non header line revels all the species/categories.
                categories = line.split()
                num_nodes = int(len(categories))
                print num_nodes
                counter += 1
                g.add_vertex(num_nodes)
                continue

            splitted = line.split()
            category = splitted[0]
            assert (category == categories[counter])

            for neighbor, weight in enumerate(splitted[1:]):
                if weight != "0":
                    e = g.add_edge(g.vertex(neighbor),
                                   g.vertex(counter))  # Neighbor eats him.
                    edgeWeights[e] = float(weight)
            counter += 1

    taxaToInt = {"D": 0, "A": 1, "I": 2, "F": 3, "R": 4, "B": 5}
    troClass = g.new_vertex_property("int")
    for i, categ in enumerate(categories):
        troClass.a[i] = taxaToInt[categ[0]]

    g.vp["trophic_class"] = troClass
    g.ep["edge_weight"] = edgeWeights

    g = make_simple_graph(g, undirected=True, gcc=True)

    graphName = saveLoadFolder
    if save:
        save_data(
            saveLoadPath + saveLoadFolder + "/" + graphName + ".GT.graph", g)
        g.save(saveLoadPath + saveLoadFolder + "/" + graphName + ".graph.xml",
               fmt="xml")
    if export:
        from_GT_To_Greach(
            g,
            saveLoadPath + saveLoadFolder + "/" + graphName + ".greach.graph")
        from_GT_To_Snap(
            g, saveLoadPath + saveLoadFolder + "/" + graphName + ".snap.graph")

    return g
Exemple #17
0
def tree1():
    g = Graph(directed=True)
    g.add_vertex(5)  # one remaining singleton
    g.add_edge_list([(0, 1), (1, 2), (1, 3)])

    # to test 4 is not included
    vfilt = g.new_vertex_property('bool')
    vfilt.set_value(True)
    vfilt[4] = False
    g.set_vertex_filter(vfilt)
    return g
Exemple #18
0
def co_graph_directed():
    '''co_graph_directed
    '''
    g = Graph(directed=True)
    g.add_vertex(2)
    edges = [(0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1)]
    g.add_edge_list(edges)
    o = g.new_vertex_property('int')
    o.a = np.array([3, 4, 2])
    co = g.new_edge_property('int')
    co.a = np.array([2, 2, 1, 1, 2, 2])
    return g, o, co
def generateEmptyGraph(width, height):
    graph = Graph()
    graph.add_vertex(width * height)

    pos = graph.new_vertex_property("vector<double>")

    for x in range(0, width):
        for y in range(0, height):
            pos[graph.vertex((x * width) + (y))] = (x, y)

    graph.vertex_properties["position"] = pos
    return graph
Exemple #20
0
def transform_nx_gt(g, rescale=False):
    from graph_tool import Graph
    from limic.util import haversine_distance
    h = Graph(directed=False)
    h.vp.id = h.new_vertex_property("int64_t")
    if rescale:
        h.vp.lat = h.new_vertex_property("int32_t")
        h.vp.long = h.new_vertex_property("int32_t")
        h.ep.weight = h.new_edge_property("int32_t")
    else:
        h.vp.lat = h.new_vertex_property("double")
        h.vp.long = h.new_vertex_property("double")
        h.ep.weight = h.new_edge_property("float")
    h.ep.type = h.new_edge_property("int32_t")
    h.gp.rescaled = h.new_graph_property("bool")
    h.gp.rescaled = rescale
    pos2vertex = {}
    intersection_id = 0
    for n in g.nodes():
        v = h.add_vertex()
        pos2vertex[n[1], n[2]] = v
        if n[0] < 0:
            intersection_id -= 1
            h.vp.id[v] = intersection_id
        else:
            h.vp.id[v] = n[0]
        h.vp.lat[v] = int(n[1] * 10000000) if rescale else n[1]
        h.vp.long[v] = int(n[2] * 10000000) if rescale else n[2]
    for n, m, d in g.edges.data(data=True):
        w = d['weight']
        air = d['type']
        e = h.add_edge(pos2vertex[n[1], n[2]], pos2vertex[m[1], m[2]])
        h.ep.type[e] = air
        if rescale and air < 0:
            w = haversine_distance(longx=n[2],
                                   latx=n[1],
                                   longy=m[2],
                                   laty=m[1])
        h.ep.weight[e] = int(w * 1000) if rescale else w
    return h
Exemple #21
0
def partition_from_sample(sample_partition: BlockState, graph: Graph,
                          mapping: Dict) -> BlockState:
    """Creates a BlockState for the full graph from sample results.

    Parameters
    ----------
    sample_partition : BlockState
        the partitioning results on the sample subgraph
    graph : Graph
        the full graph
    mapping : Dict[int, int]
        the mapping of sample vertices to full graph vertices

    Returns
    -------
    partition : BlockState
        the extended partition on the full graph
    """
    assignment_property_map = graph.new_vertex_property("int", val=-1)
    assignment = assignment_property_map.get_array()
    sample_assignment = sample_partition.get_blocks().get_array()
    for key, value in mapping.items():
        assignment[key] = sample_assignment[value]
    next_block = sample_partition.get_B()
    for i in range(graph.num_vertices()):
        if assignment[i] >= 0:
            continue
        assignment[i] = next_block
        next_block += 1
    for i in range(graph.num_vertices()):
        if assignment[i] < sample_partition.get_B():
            continue
        # TODO: make a helper function that finds the most connected block
        # TODO: make this an iterative process, so vertices with all neighbors unknown wait until at least one neighbor
        # is known
        block_counts = dict()  # type: Dict[int, int]
        neighbors = graph.get_all_neighbors(i)
        for neighbor in neighbors:
            neighbor_block = assignment[neighbor]
            if neighbor_block < sample_partition.get_B():
                if neighbor_block in block_counts:
                    block_counts[neighbor_block] += 1
                else:
                    block_counts[neighbor_block] = 1
        if len(block_counts) > 0:
            assignment[i] = max(block_counts)
        else:
            assignment[i] = np.random.randint(0, sample_partition.get_B())
    assignment_property_map.a = assignment
    partition = BlockState(graph, assignment_property_map,
                           sample_partition.get_B())
    return partition
Exemple #22
0
def graph_from_dataframes(vertex_df, edge_df):
    '''Re-creates a Graph object with PropertyMaps taken
    from the vertex_df and edge_df DataFrames

    Paramters:
    ==========
    verex_df: a DataFrame with an index named 'vertex_index'
    edge_df: a DataFrame with a multi-index named ('source', 'target')

    Returns:
    ========
    graph: a grah-tool Graph with PropertyMaps copied
        from the columns of the input DataFrames
    '''

    graph = Graph(directed=True)

    vertex_index = vertex_df.index.get_level_values(level='vertex_index')
    vertices = graph.add_vertex(n=vertex_index.shape[0])
    for col in vertex_df.columns:
        in_type = vertex_df[col].dtype.name
        try:
            dtype = ALIASES[in_type]
        except KeyError:
            log.info('Data type {} not supported'.format(in_type))
            continue
        prop = graph.new_vertex_property(dtype)
        prop.fa = vertex_df[col]
        graph.vertex_properties[col] = prop

    src = edge_df.index.names.index('source')
    trgt = edge_df.index.names.index('target')
    ### TODO: use the list edge creation
    for tup in edge_df.index:
        source, target = tup[src], tup[trgt]
        try:
            edge = graph.add_edge(source, target)
        except ValueError:
            log.info('Invalid vertex in (source: {}, target: {})'.format(
                source, target))
    for col in edge_df.columns:
        in_type = edge_df[col].dtype.name
        try:
            dtype = ALIASES[in_type]
        except KeyError:
            log.info('Data type {} not supported'.format(in_type))
            continue
        prop = graph.new_edge_property(dtype)
        prop.fa = edge_df[col]
        graph.edge_properties[col] = prop

    return graph
Exemple #23
0
def graph_from_dataframes(vertex_df, edge_df):
    '''Re-creates a Graph object with PropertyMaps taken
    from the vertex_df and edge_df DataFrames

    Paramters:
    ==========
    verex_df: a DataFrame with an index named 'vertex_index'
    edge_df: a DataFrame with a multi-index named ('source', 'target')

    Returns:
    ========
    graph: a grah-tool Graph with PropertyMaps copied
        from the columns of the input DataFrames
    '''

    graph = Graph(directed=True)

    vertex_index = vertex_df.index.get_level_values(level='vertex_index')
    vertices = graph.add_vertex(n=vertex_index.shape[0])
    for col in vertex_df.columns:
        in_type = vertex_df[col].dtype.name
        try:
            dtype = ALIASES[in_type]
        except KeyError:
            log.info('Data type {} not supported'.format(in_type))
            continue
        prop = graph.new_vertex_property(dtype)
        prop.fa = vertex_df[col]
        graph.vertex_properties[col] = prop

    src = edge_df.index.names.index('source')
    trgt = edge_df.index.names.index('target')
    ### TODO: use the list edge creation
    for tup in edge_df.index:
        source, target = tup[src], tup[trgt]
        try:
            edge = graph.add_edge(source, target)
        except ValueError:
            log.info('Invalid vertex in (source: {}, target: {})'.format(source, target))
    for col in edge_df.columns:
        in_type = edge_df[col].dtype.name
        try:
            dtype = ALIASES[in_type]
        except KeyError:
            log.info('Data type {} not supported'.format(in_type))
            continue
        prop = graph.new_edge_property(dtype)
        prop.fa = edge_df[col]
        graph.edge_properties[col] = prop

    return graph
Exemple #24
0
def save_root_children(g: gt.Graph, root_id) -> gt.Graph:
    zero_id = vp_map(g, 'zero_id', 'int')
    roots = set()
    for v in g.vertices():
        if zero_id[v] == root_id:
            roots.add(v)

    leave_prop = g.new_vertex_property('bool')
    for v in roots:
        gt_top.label_out_component(g, v, leave_prop)

    sub = gt.GraphView(g, leave_prop)
    new_g = create_q_graph(sub, add_back_reference=False)
    return new_g
Exemple #25
0
def subsample_archive_from_matching(a: gt.Graph, mg: gt.Graph,
                                    t_graph: gt.Graph, e_idx):
    leave_prop = a.new_vertex_property('bool')
    one_prop = vp_map(mg, 'one_id', 'int')

    to_save = set([one_prop[n] for n in mg.vertices()])
    for v in a.vertices():
        leave_prop[v] = a.vertex_index[v] in to_save

    # get rid of all the nodes in A that aren't there
    sub = gt.GraphView(a, leave_prop)
    new_g = create_q_graph(sub, add_back_reference=True)

    return new_g
Exemple #26
0
 def util_graph(self, vertices, conn):
     """
     generate a generate a graph with vertices and connectivity in conn
     """
     g = Graph(directed=False)
     # now add vertices
     g.vp.type = g.new_vertex_property("string")
     for i, v in enumerate(vertices):
         g.add_vertex()
         g.vp.type[i] = v
     # now add edges ...
     for i, v in enumerate(vertices):
         for j in conn[i]:
             if j >= i:
                 g.add_edge(g.vertex(i), g.vertex(j))
     return g
Exemple #27
0
    def create_graph(cls, edges, is_directed=True):
        """Create a graph-tool type graph from a list of edges"""
        g = Graph()
        g.set_directed(is_directed)
        label2index = dict()
        label = g.new_vertex_property('int32_t')
        g.vertex_properties['label'] = label

        for v1_label, v2_label in edges:
            cls.add_vertex(v1_label, label2index, g)
            cls.add_vertex(v2_label, label2index, g)

            v1, v2 = label2index[v1_label], label2index[v2_label]
            g.add_edge(v1, v2)

        return g, label2index
Exemple #28
0
def basic_graph():
    """"""

    G = Graph()

    v0 = G.add_vertex()
    v1 = G.add_vertex()
    v2 = G.add_vertex()
    v3 = G.add_vertex()
    v4 = G.add_vertex()
    v5 = G.add_vertex()
    v6 = G.add_vertex()
    v7 = G.add_vertex()

    e0 = G.add_edge(v0, v1)
    e1 = G.add_edge(v0, v2)
    e2 = G.add_edge(v0, v3)
    e3 = G.add_edge(v0, v4)
    e4 = G.add_edge(v5, v4)
    e5 = G.add_edge(v6, v4)
    e6 = G.add_edge(v4, v7)

    prop_v = G.new_vertex_property('string')
    prop_e = G.new_edge_property('string')

    G.vertex_properties['name'] = prop_v
    G.edge_properties['c0'] = prop_e

    prop_v[v0] = '/John'
    prop_v[v1] = '*****@*****.**'
    prop_v[v2] = '*****@*****.**'
    prop_v[v3] = '/Researcher'
    prop_v[v4] = '/Rome'
    prop_v[v5] = '/Giacomo'
    prop_v[v6] = '/Piero'
    prop_v[v7] = '"Roma"@it'

    prop_e[e0] = 'foaf:mbox'
    prop_e[e1] = 'foaf:mbox'
    prop_e[e2] = 'rdf:type'
    prop_e[e3] = 'ex:birthPlace'
    prop_e[e4] = 'ex:areaOfWork'
    prop_e[e5] = 'ex:areaOfWork'
    prop_e[e6] = 'foaf:name'

    return G
Exemple #29
0
def clear_unconnected(g: gt.Graph, key_node) -> gt.Graph:
    # Get rid of any component that doesn't contain the key node.
    label_map, hist = gt_top.label_components(g, directed=False)

    zero_id = vp_map(g, 'zero_id', 'int')
    key_comps = set()
    for v in g.vertices():
        if zero_id[v] == key_node:
            key_comps.add(label_map[v])

    leave_prop = g.new_vertex_property('bool')
    for v in g.vertices():
        leave_prop[v] = label_map[v] in key_comps

    sub = gt.GraphView(g, leave_prop)
    new_g = create_q_graph(sub, add_back_reference=False)

    return new_g
Exemple #30
0
def evaluate_sampled_graph_partition(graph: Graph, true_b: np.ndarray,
                                     alg_partition: BlockState,
                                     evaluation: Evaluation,
                                     block_mapping: Dict[int, int]):
    """Evaluate the output partition against the truth partition and report the correctness metrics.
       Compare the partitions using only the nodes that have known truth block assignment.

    Parameters
    ----------
    graph : Graph
        the sampled graph that was partitioned.
    true_b : ndarray (int)
        array of truth block assignment for each vertex in the sampled graph. If the truth block is not known for a
        vertex, -1 is used to indicate unknown blocks.
    alg_partition : BlockState
        the partition result returned by stochastic block partitioning.
    evaluation : Evaluation
        stores evaluation results
    block_mapping : Dict[int, int]
        the mapping of actual block ids to sample block ids (to ensure they are in a [0,X] range, where X >= 0)
    """
    alg_b = alg_partition.get_blocks().get_array()
    evaluation.sampled_graph_description_length = alg_partition.entropy()
    evaluation.max_sampled_graph_description_length = BlockState(
        graph,
        graph.new_vertex_property("int",
                                  np.arange(graph.num_vertices()))).entropy()
    evaluation.sampled_graph_modularity = modularity(
        graph, alg_partition.get_blocks())
    if np.unique(
            true_b
    ).size == 1:  # Cannot evaluate the below metrics if true partition isn't provided
        evaluation.sampled_graph_num_blocks_algorithm = max(alg_b) + 1
        return
    true_b = np.asarray([block_mapping[block] for block in true_b])
    contingency_table, N = create_contingency_table(true_b,
                                                    alg_b,
                                                    evaluation,
                                                    sampled_graph=True)
    evaluation.sampled_graph_contingency_table = contingency_table
    joint_prob = evaluate_accuracy(contingency_table, evaluation, True)
    evaluate_pairwise_metrics(contingency_table, N, evaluation, True)
    evaluate_entropy_metrics(joint_prob, evaluation, True)
def build_closure(g, terminals, debug=False, verbose=False):
    """build the transitive closure on terminals"""
    def get_edges(dist, root, terminals):
        """get adjacent edges to root with weight"""
        return ((root, t, dist[t]) for t in terminals
                if dist[t] != -1 and t != root)

    terminals = list(terminals)
    gc = Graph(directed=False)

    gc.add_vertex(g.num_vertices())

    edges_with_weight = set()
    r2pred = {}  # root to predecessor map (from bfs)

    # bfs to all other nodes
    for r in terminals:
        if debug:
            print('root {}'.format(r))
        vis = init_visitor(g, r)
        bfs_search(g, source=r, visitor=vis)
        new_edges = set(get_edges(vis.dist, r, terminals))
        if debug:
            print('new edges {}'.format(new_edges))
        edges_with_weight |= new_edges
        r2pred[r] = vis.pred

    for u, v, c in edges_with_weight:
        gc.add_edge(u, v)

    # edge weights
    eweight = gc.new_edge_property('int')
    weights = np.array([c for _, _, c in edges_with_weight])
    eweight.set_2d_array(weights)

    #
    vfilt = gc.new_vertex_property('bool')
    vfilt.a = False
    for v in terminals:
        vfilt[v] = True
    gc.set_vertex_filter(vfilt)
    return gc, eweight, r2pred
Exemple #32
0
class Map:
    data = []

    def load(self, data):
        data = [x.strip() for x in data]
        # Create a new undirectedgraph
        self.graph = Graph(directed=False)

        # Label everything so I'm not going back and forth between hashes
        v_name = self.graph.new_vertex_property('string')
        self.graph.vertex_properties["name"] = v_name

        self.planets = dict()
        # Create all the vertexes first, so that creating the edges (orbits)
        # is easier
        for item in data:
            # Add vertexes, as needed
            src, dest = item.split(")")
            if src not in self.planets:
                v_src = self.graph.add_vertex()
                v_name[v_src] = src
                self.planets[src] = v_src
            if dest not in self.planets:
                v_dest = self.graph.add_vertex()
                v_name[v_dest] = dest
                self.planets[dest] = v_dest
            # Add edge
            self.graph.add_edge(self.planets[src], self.planets[dest])

    def part1(self):
        total = 0
        for planet in self.planets:
            total += self.calc_distance(planet, 'COM')
        return total

    def part2(self):
        return self.calc_distance('YOU', 'SAN')

    def calc_distance(self, src, dest):
        return shortest_distance(self.graph, self.planets[src],
                                 self.planets[dest])
Exemple #33
0
def evaluate_partition(graph: Graph, true_b: np.ndarray,
                       alg_partition: BlockState, evaluation: Evaluation):
    """Evaluate the output partition against the truth partition and report the correctness metrics.
       Compare the partitions using only the nodes that have known truth block assignment.

    Parameters
    ----------
    graph : Graph
        the graph which was partitioned.
    true_b : ndarray (int)
        array of truth block assignment for each node. If the truth block is not known for a node, -1 is used
        to indicate unknown blocks.
    alg_partition : BlockState
        the partition result returned by stochastic block partitioning.
    evaluation : Evaluation
        stores evaluation results

    Returns
    ------
    evaluation : Evaluation
        the evaluation results, filled in with goodness of partitioning measures
    """
    alg_b = alg_partition.get_blocks().get_array()
    evaluation.full_graph_description_length = alg_partition.entropy()
    evaluation.max_full_graph_description_length = BlockState(
        graph,
        graph.new_vertex_property("int",
                                  np.arange(graph.num_vertices()))).entropy()
    evaluation.full_graph_modularity = modularity(graph,
                                                  alg_partition.get_blocks())
    if np.unique(true_b).size != 1:
        contingency_table, N = create_contingency_table(
            true_b, alg_b, evaluation)
        evaluation.contingency_table = contingency_table
        joint_prob = evaluate_accuracy(contingency_table, evaluation)
        evaluate_pairwise_metrics(contingency_table, N, evaluation)
        evaluate_entropy_metrics(joint_prob, evaluation)
    else:
        evaluation.num_blocks_algorithm = max(alg_b) + 1
    evaluation.save()
Exemple #34
0
def graph_from_dataframes(vertex_df, edge_df):
    '''Re-creates a Graph object with PropertyMaps taken
    from the vertex_df and edge_df DataFrames

    Paramters:
    ==========
    verex_df: a DataFrame with an index named 'vertex_index'
    edge_df: a DataFrame with a multi-index named ('source', 'target')

    Returns:
    ========
    graph: a grah-tool Graph with PropertyMaps copied
        from the columns of the input DataFrames
    '''

    graph = Graph(directed=True)

    vertex_index = vertex_df.index.get_level_values(level='vertex_index')
    vertices = graph.add_vertex(n=vertex_index.shape[0])
    for col in vertex_df.columns:
        dtype = ALIASES[vertex_df[col].dtype.name]
        prop = graph.new_vertex_property(dtype)
        prop.a = vertex_df[col]
        graph.vertex_properties[col] = prop

    src = edge_df.index.names.index('source')
    trgt = edge_df.index.names.index('target')
    ### TODO: use the list edge creation
    for tup in edge_df.index:
        source, target = tup[src], tup[trgt]
        edge = graph.add_edge(source, target)

    for col in edge_df.columns:
        dtype = ALIASES[edge_df[col].dtype.name]
        prop = graph.new_edge_property(dtype)
        prop.a = edge_df[col]
        graph.edge_properties[col] = prop
    return graph
    def parse_graph_from_string(self, graphML_string):
        dom = minidom.parseString(graphML_string)
        root = dom.getElementsByTagName("graphml")[0]
        graph = root.getElementsByTagName("graph")[0]
        name = graph.getAttribute('id')

        g = Graph(directed=False)

        vpos=g.new_vertex_property("vector<double>")
        for node in graph.getElementsByTagName("node"):
            id=node.getAttribute('id')
            n = g.add_vertex()
            g.vertex_index[id]

            #right now only the positions are available
            for attr in node.getElementsByTagName("data"):
                if attr.firstChild:
                    key=attr.getAttribute("key")
                    #n[key] = attr.firstChild.data
                    if(key=="x"):
                        x=attr.firstChild.data
                    elif(key=="y"):
                        y=attr.firstChild.data

            vpos[id]=(x,y)

        g.vertex_properties["pos"]=vpos

        #have to workaround the directed graph written by the server
        for edge in graph.getElementsByTagName("edge"):
            source = edge.getAttribute('source')
            dest = edge.getAttribute('target')

            edge=g.edge(dest,source)
            if(edge==None):
                e = g.add_edge(source, dest)

	return g
def build_closure(g, terminals,
                  debug=False,
                  verbose=False):
    terminals = list(terminals)
    # build closure
    gc = Graph(directed=False)

    for _ in range(g.num_vertices()):
        gc.add_vertex()

    edges_with_weight = set()
    r2pred = {}

    for r in terminals:
        if debug:
            print('root {}'.format(r))
        vis = init_visitor(g, r)
        pbfs_search(g, source=r, terminals=terminals, visitor=vis)
        new_edges = set(get_edges(vis.dist, r, terminals))
        if debug:
            print('new edges {}'.format(new_edges))
        edges_with_weight |= new_edges
        r2pred[r] = vis.pred
    
    for u, v, c in edges_with_weight:
        gc.add_edge(u, v)
        
    eweight = gc.new_edge_property('int')
    weights = np.array([c for _, _, c in edges_with_weight])
    eweight.set_2d_array(weights)

    vfilt = gc.new_vertex_property('bool')
    vfilt.a = False
    for v in terminals:
        vfilt[v] = True
    gc.set_vertex_filter(vfilt)
    return gc, eweight, r2pred
Exemple #37
0
    def makeGraphFast(self,img,dia,xScale,yScale):
        print('Building Graph Data Structure'),
        start=time.time()
        G = Graph(directed=False)
        sumAddVertices=0
        
        vprop=G.new_vertex_property('object')
        eprop=G.new_edge_property('object')
        epropW=G.new_edge_property("float")
        h, w = np.shape(img)
        if xScale>0 and yScale>0: avgScale=(xScale+yScale)/2
        else: 
            avgScale=1.
            xScale=1.
            yScale=1.
        addedVerticesLine2=[]
        vListLine2=[]
        percentOld=0
        counter=0
        '''
        Sweep over each line in the image except the last line
        '''
        for idx,i in enumerate(img[:len(img)-2]):
            '''
            Get foreground indices in the current line of the image and make vertices
            '''
            counter+=1
            percent=(float(counter)/float(h))*100
            if percentOld+10< percent: 
                print (str(np.round(percent,1))+'% '),
                percentOld=percent

            line1=np.where(i==True)
            if len(line1[0])>0:
                line1=set(line1[0]).difference(set(addedVerticesLine2))
                vL=G.add_vertex(len(list(line1)))
                
                
                if len(line1)>1 : 
                    vList=vListLine2+list(vL)
                else: vList=vListLine2+[vL]
                line1=addedVerticesLine2+list(line1)
                for jdx,j in enumerate(line1):
                    vprop[vList[jdx]]={'imgIdx':(j,idx),'coord': (float(j)*xScale,float(idx)*yScale), 'nrOfPaths':0, 'diameter':float(dia[idx][j])*avgScale}
                '''
                keep order of the inserted vertices
                '''
                sumAddVertices+=len(line1)
                
                addedVerticesLine2=[]
                vListLine2=[]
                '''
                Connect foreground indices to neighbours in the next line
                '''
                for v1 in line1:
                    va=vList[line1.index(v1)]
                    diagonalLeft = diagonalRight = True
                    try:
                        if img[idx][v1-1]==True:
                            diagonalLeft=False
                            vb=vList[line1.index(v1-1)]
                            e=G.add_edge(va,vb)
                            eprop[e]={'coord1':vprop[va]['coord'], 'coord2':vprop[vb]['coord'],'weight':((vprop[va]['diameter']+vprop[vb]['diameter'])/2),'RTP':False}
                            epropW[e]=2./(eprop[e]['weight']**2)
                    except:
                        print 'Boundary vertex at: '+str([v1,idx-1])+' image size: '+ str([w,h])
                        pass
                    
                    try:
                        if img[idx][v1+1]==True:
                            diagonalRight=False
                            vb=vList[line1.index(v1+1)]
                            e=G.add_edge(va,vb)
                            eprop[e]={'coord1':vprop[va]['coord'], 'coord2':vprop[vb]['coord'],'weight':((vprop[va]['diameter']+vprop[vb]['diameter'])/2),'RTP':False}
                            epropW[e]=2./(eprop[e]['weight']**2)
                    except:
                        print 'Boundary vertex at: '+str([v1+1,idx])+' image size: '+ str([w,h])
                        pass # just if we are out of bounds
                    
                    try:
                        if img[idx+1][v1]==True:
                            diagonalRight=False
                            diagonalLeft=False
                            vNew=G.add_vertex()
                            vprop[vNew]={'imgIdx':(v1,idx+1),'coord': (float(v1)*xScale,float(idx+1)*yScale), 'nrOfPaths':0, 'diameter':float(dia[idx+1][v1])*avgScale}
                            vListLine2.append(vNew)
                            e=G.add_edge(vList[line1.index(v1)],vNew)
                            eprop[e]={'coord1':vprop[va]['coord'], 'coord2':vprop[vNew]['coord'],'weight':((vprop[va]['diameter']+vprop[vNew]['diameter'])/2),'RTP':False}
                            epropW[e]=1./(eprop[e]['weight']**2)
                            if v1 not in addedVerticesLine2: addedVerticesLine2.append(v1)
                    except:
                        print 'Boundary vertex at: '+str([v1,idx+1])+' image size: '+ str([w,h])
                        pass
                    
                    try:    
                        if diagonalRight == True and img[idx+1][v1+1]==True:
                            vNew=G.add_vertex()
                            vprop[vNew]={'imgIdx':(v1+1,idx+1),'coord': (float(v1+1)*xScale,float(idx+1)*yScale), 'nrOfPaths':0, 'diameter':float(dia[idx+1][v1+1])*avgScale}
                            vListLine2.append(vNew)
                            e=G.add_edge(vList[line1.index(v1)],vNew)
                            eprop[e]={'coord1':vprop[va]['coord'], 'coord2':vprop[vNew]['coord'],'weight':((vprop[va]['diameter']+vprop[vNew]['diameter'])/2),'RTP':False}
                            epropW[e]=1.41/(eprop[e]['weight']**2)
                            if v1+1 not in addedVerticesLine2: addedVerticesLine2.append(v1+1)
                    except:
                        print 'Boundary vertex at: '+str([v1+1,idx+1])+' image size: '+ str([w,h])
                        pass
                    
                    try:
                        if diagonalLeft  == True and img[idx+1][v1-1]==True:
                            vNew=G.add_vertex()
                            vprop[vNew]={'imgIdx':(v1-1,idx+1),'coord': (float(v1-1)*xScale,float(idx+1)*yScale), 'nrOfPaths':0, 'diameter':float(dia[idx+1][v1-1])*avgScale}
                            vListLine2.append(vNew)
                            e=G.add_edge(vList[line1.index(v1)],vNew)
                            eprop[e]={'coord1':vprop[va]['coord'], 'coord2':vprop[vNew]['coord'],'weight':((vprop[va]['diameter']+vprop[vNew]['diameter'])/2),'RTP':False}
                            epropW[e]=1.41/(eprop[e]['weight']**2)
                            if v1-1 not in addedVerticesLine2: addedVerticesLine2.append(v1-1)
                    except:
                        print 'Boundary vertex at: '+str([v1-1,idx+1])+' image size: '+ str([w,h])
                        pass
                    try:
                        if img[idx][v1+1]==False and img[idx][v1-1]==False and img[idx+1][v1]==False and diagonalLeft==False and diagonalRight==False:
                            print 'tip detected'
                            if img[idx-1][v1-1]==False and img[idx-1][v1+1]==False and img[idx-1][v1]==False:
                                print 'floating pixel'
                    except:
                        pass
        
        print'done!'                               
        G.edge_properties["ep"] = eprop
        G.edge_properties["w"] = epropW
        G.vertex_properties["vp"] = vprop            
        print 'graph build in '+str(time.time()-start)
        l = gt.label_largest_component(G)
        u = gt.GraphView(G, vfilt=l)
        print '# vertices'
        print(u.num_vertices())
        print(G.num_vertices())
        if u.num_vertices()!=G.num_vertices(): self.__fail=float((G.num_vertices()-u.num_vertices()))/float(G.num_vertices())
        return u,u.num_vertices()
Exemple #38
0
class SkeletonMatch(object):
    """
    implement Oscar's skeleton matching alogrithm in this class
    """
    def __init__(self, skel1, skel2, centricity=.5, length=.5, distorted=20.):
        if skel1 is not None and skel2 is not None :
            self.skel1 = skel1
            self.skel2 = skel2
            self.centricity_threhold = centricity
            self.length_threhold = length
            self.distorted_threhold = distorted
            self.skel1.calc_skel_properties()
            self.skel2.calc_skel_properties()
            # use index instead of real value
            skel1_index = np.arange(len(self.skel1.feature_node_index))
            skel2_index = np.arange(len(self.skel2.feature_node_index))
            junc1_num = len(skel1.junction_index)
            junc2_num = len(skel2.junction_index)

            #print 'skel1 normalized_verts\n', skel1.normalized_feature_verts
            #print 'skel2 normalized_verts\n', skel2.normalized_feature_verts

            #candidate matched pairs
            junction_pairs = []
            junc_term_pairs = []
            terminal_pairs = []
            for i, j in itertools.product(skel1_index, skel2_index):
                if self.test_node_centricity(c1=i, c2=j):
                    if i < junc1_num and j < junc2_num: # only junction nodes
                        junction_pairs.append([i,j])
                    elif i >= junc1_num and j >= junc2_num: # only terminal nodes
                        terminal_pairs.append([i,j])
                    else:
                        junc_term_pairs.append([i,j])

            self.junction_pairs = np.array(junction_pairs)
            self.terminal_pairs = np.array(terminal_pairs)
            self.junc_term_pairs = np.array(junc_term_pairs)
            #self.all_junc_pairs = np.vstack((self.junction_pairs, self.junc_term_pairs))

            self.vote_tree = Graph(directed=False)
            self.node_pair = self.vote_tree.new_vertex_property("vector<short>")

            self._construct_voting_tree()
        else:
            print 'need input two skeleton to match'


    def _construct_voting_tree(self, prev_pairs=np.array([]), mix_junc_term=True):
        """
        recursively consturct voting tree
        @param prev_pairs record that already on the path
        @param junc_pairs record that left part junction pairs (on current tree level)
        @param term_pairs record that left terminal pairs on current tree level

        now limits: at least one junction pair
        """
        # root of the tree
        if len(prev_pairs) == 0:
            v1 = self.vote_tree.add_vertex()
            #first level, only junction pairs (both are junction)
            for n, pair in enumerate(self.junction_pairs):
                new_prev = pair.reshape(-1,2)  # to use len(for level one), need to change shape
                print 'adding subtree', n+1, '/', len(self.junction_pairs)
                v2 = self._construct_voting_tree(prev_pairs=new_prev)
                self.vote_tree.add_edge(v1, v2)
            return v1                    # return the root

        elif len(prev_pairs) == 1:  # first level
            v1 = self.vote_tree.add_vertex()
            self.node_pair[v1] = prev_pairs.flatten()
            """
            priority order: junction pairs, terminal pairs, junc-term pairs
            """

            check_junc = True
            #prepare for next(second) level
            for n, pair in enumerate(self.junction_pairs):
                if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                    new_prev = np.vstack((prev_pairs, pair))
                    v2 = self._construct_voting_tree(prev_pairs=new_prev)
                    if v2 is not None: 
                        check_junc = False
                        self.vote_tree.add_edge(v1, v2)

            # it is sure that that should be some terminal_pairs
            # but in case
            check_term = mix_junc_term # if True allow mix junc and term 
            if check_junc:
                for n, pair in enumerate(self.terminal_pairs):
                    new_prev = np.vstack((prev_pairs, pair))
                    v2 = self._construct_voting_tree(prev_pairs=new_prev, mix_junc_term=True)
                    if v2 is not None:
                        check_term = False
                        self.vote_tree.add_edge(v1, v2)

            if check_junc and check_term:
                for n, pair in enumerate(self.junc_term_pairs):
                    new_prev = np.vstack((prev_pairs, pair))
                    v2 = self._construct_voting_tree(prev_pairs=new_prev)
                    if v2 is not None:
                        self.vote_tree.add_edge(v1, v2)

            return v1                   # return the first level of the tree

        elif 4 > len(prev_pairs) > 1:  # above level two
            #if satisfy T2 (length and radius prune)
            if self.test_length_radius(n1=prev_pairs[-1,0], n2=prev_pairs[-1,1], matched_pairs=prev_pairs[:-1]) and self.test_topology_consistency(n1=prev_pairs[-1,0], n2=prev_pairs[-1,1], matched_pairs=prev_pairs[:-1]):
                v1 = self.vote_tree.add_vertex()
                self.node_pair[v1] = prev_pairs.flatten()

                check_junc = True
                for pair in self.junction_pairs:
                    if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                        new_prev = np.vstack((prev_pairs, pair))
                        v2 = self._construct_voting_tree(prev_pairs=new_prev)
                        if v2 is not None:
                            check_junc = False
                            self.vote_tree.add_edge(v1, v2)
                
                check_term = mix_junc_term   # if allow mix junc and term
                if check_junc:
                    for pair in self.terminal_pairs:
                        if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                            new_prev = np.vstack((prev_pairs, pair))
                            v2 = self._construct_voting_tree(prev_pairs=new_prev, mix_junc_term=True)
                            if v2 is not None:
                                check_term = False
                                self.vote_tree.add_edge(v1, v2)

                if check_junc and check_term:
                    for pair in self.junc_term_pairs:
                        if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                            new_prev = np.vstack((prev_pairs, pair))
                            v2 = self._construct_voting_tree(prev_pairs=new_prev)
                            if v2 is not None:
                                self.vote_tree.add_edge(v1, v2)

                return v1             # return second and above level tree
            else:
                return None             # fail to match

        elif len(prev_pairs) >= 4:
            if self.test_length_radius(n1=prev_pairs[-1,0], n2=prev_pairs[-1,1], matched_pairs=prev_pairs[:-1]) and self.test_topology_consistency(n1=prev_pairs[-1,0], n2=prev_pairs[-1,1], matched_pairs=prev_pairs[:-1]):
                #print 'len(prev_pairs) >= 4',
                #print 'current pairs\n', prev_pairs, 
                if self.test_spatial_configuration(n1=prev_pairs[-1,0], n2=prev_pairs[-1,1], matched_pairs=prev_pairs[:-1]):
                    v1 = self.vote_tree.add_vertex()
                    self.node_pair[v1] = prev_pairs.flatten()
                    #print 'succeed testing spatial', '[', prev_pairs[-1,0], prev_pairs[-1,1], ']',
                    #print 'from\n',  prev_pairs[:-1]
                    #print 'current matched pairs\n', prev_pairs

                    check_junc = True
                    for pair in self.junction_pairs:
                        if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                            new_prev = np.vstack((prev_pairs, pair))
                            v2 = self._construct_voting_tree(prev_pairs=new_prev)
                            if v2 is not None:
                                check_junc = False
                                self.vote_tree.add_edge(v1, v2)

                    check_term = mix_junc_term # if True allow mix junction and terminal
                    if check_junc:
                        for pair in self.terminal_pairs:
                            if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                                new_prev = np.vstack((prev_pairs, pair))
                                v2 = self._construct_voting_tree(prev_pairs=new_prev)
                                if v2 is not None:
                                    check_term = False
                                    self.vote_tree.add_edge(v1, v2)

                    if check_junc and check_term:
                        for pair in self.junc_term_pairs:
                            if pair[0] not in prev_pairs[:,0] and pair[1] not in prev_pairs[:,1]:
                                new_prev = np.vstack((prev_pairs, pair))
                                v2 = self._construct_voting_tree(prev_pairs=new_prev)
                                if v2 is not None:
                                    self.vote_tree.add_edge(v1, v2)
                    return v1
                else:
                    return None
            else:
                return None
    

    def test_node_centricity(self, c1, c2):
        """
        match node centricity of the graph
        """
        node_cent1 = self.skel1.node_centricity[c1]
        node_cent2 = self.skel2.node_centricity[c2]
        match_result = abs(node_cent1 - node_cent2) / (node_cent1 + node_cent2)
        threhold = self.centricity_threhold * .5
        return match_result < threhold


    def test_length_radius(self, n1, n2, matched_pairs):
        """
        match path length and radius from n1/n2 to nodes that already in matched_pairs
        """
        path_len1 = self.skel1.path_length_ratio[n1, matched_pairs[:,0]]
        path_len2 = self.skel2.path_length_ratio[n2, matched_pairs[:,1]]
        length_match = abs(path_len1 - path_len2) / (path_len1 + path_len2)
        threhold = self.length_threhold * 0.5
        #if all satisfied
        if np.all(length_match < threhold):
            path_rad1 = self.skel1.path_radius_ratio[n1, matched_pairs[:,0]]
            path_rad2 = self.skel2.path_radius_ratio[n2, matched_pairs[:,1]]
            radius_match = abs(path_rad1 - path_rad2) / (path_rad1 + path_rad2)
            if np.all(radius_match < threhold):
                return True
            else:
                return False
        else:
            return False


    def test_topology_consistency(self, n1, n2, matched_pairs):
        """
        match skeleton topology consistency
        """
        if len(matched_pairs) > 0:
            junct1 = matched_pairs[matched_pairs[:,0] < len(self.skel1.junction_index), 0]
            junct2 = matched_pairs[matched_pairs[:,1] < len(self.skel2.junction_index), 1]
            if len(junct1) < 1 or len(junct2) < 1:
                print 'no junction node in already matched pairs'
                return False
            else:
                idx1 = np.argmin(self.skel1.path_to_junction[n1, junct1])
                idx2 = np.argmin(self.skel2.path_to_junction[n2, junct2])

                """
                print '\n[',n1,',',n2,']', 
                print 'nearest pair[',junct1[idx1],',', junct2[idx2],']',
                if [junct1[idx1], junct2[idx2]] in matched_pairs.tolist():
                    print ' IN ',
                else:
                    print ' NOT in ',

                for pair in matched_pairs:
                    print pair,
                print '\n'
                """

                return [junct1[idx1], junct2[idx2]] in matched_pairs.tolist()
        else:
            print 'none in matched_pairs'
            return False


    def test_spatial_configuration(self, n1, n2, matched_pairs):
        """
        match spatial configuration
        """
        threhold = self.distorted_threhold
        #need test if can be inverse
        skel1_vectors = self.skel1.normalized_feature_verts[matched_pairs[-3:,0]] - self.skel1.normalized_feature_verts[n1]
        skel2_vectors = self.skel2.normalized_feature_verts[matched_pairs[-3:,1]] - self.skel2.normalized_feature_verts[n2]
        #skel1_vectors = self.skel1.feature_node[matched_pairs[-3:,0]] - self.skel1.feature_node[n1]
        #skel2_vectors = self.skel2.feature_node[matched_pairs[-3:,1]] - self.skel2.feature_node[n2]
        """
        for i in xrange(3):
            skel1_vectors[i] *= ( 1. / np.linalg.norm(skel1_vectors[i]) )
            skel2_vectors[i] *= ( 1. / np.linalg.norm(skel2_vectors[i]) )
        """

        a = np.dot(skel2_vectors, np.linalg.inv(skel1_vectors))
        u, s, v = np.linalg.svd(a)
        r = np.dot(u, v)
        if np.linalg.det(r) < 0:
            r *= -1.0

        res1 = np.linalg.norm(a-r)
        #print 'res1', res1,
        if res1 > threhold:
            return False
        else:
            a = np.dot(skel1_vectors, np.linalg.inv(skel2_vectors))
            u, s, v = np.linalg.svd(a)
            r = np.dot(u, v)
            if np.linalg.det(r) < 0:
                r *= -1.0

            res2 = np.linalg.norm(a-r)
            if res2 > threhold:
                return False
            #print 'res2', res2

        #return max(res1, res2) <= threhold
        return True


    def elector_vote(self):
        """
        use elector vote to find better correspondence
        """
        vote_matrix = np.zeros((len(self.skel1.feature_node_index), len(self.skel2.feature_node_index)), dtype=int)
        for v in self.vote_tree.vertices():
            if v.out_degree() < 2:
                pairs = self.node_pair[v]
                if len(pairs) >= 8:
                    temp_pairs = pairs.a.reshape(-1,2)
                    for pair in temp_pairs:
                        vote_matrix[pair[0], pair[1]] += 1

        node_num_skel1 = len(self.skel1.feature_node_index)
        node_num_skel2 = len(self.skel2.feature_node_index)
        self.vote_matrix = vote_matrix.copy()

        
        #print 'original vote_matrix\n', vote_matrix
        if np.max(vote_matrix) == 0:
            final_corres = np.array([])
        else:
            node_pair = np.unravel_index(vote_matrix.argmax(), vote_matrix.shape)
            vote_matrix[node_pair[0], :] = vote_matrix[:, node_pair[1]] = 0
            final_corres = np.array(node_pair)
            final_corres.shape = (-1,2)
            #print 'correspondence\n', final_corres
            #print 'vote_matrix\n', vote_matrix
            while len(final_corres) < min(node_num_skel1, node_num_skel2):
                junct1 = final_corres[final_corres[:,0] < len(self.skel1.junction_index), 0]
                junct2 = final_corres[final_corres[:,1] < len(self.skel2.junction_index), 1]
                node_pair = np.unravel_index(vote_matrix.argmax(), vote_matrix.shape)
                if node_pair[0] not in final_corres[:,0] and node_pair[1] not in final_corres[:,1]:
                    if len(junct1) < 3 or len(junct2) < 3:
                        print 'less than 3 junction matched'
                        final_corres = np.vstack((final_corres, node_pair))
                        vote_matrix[node_pair[0], :] = vote_matrix[:, node_pair[1]] = 0
                    else:
                        idx1 = np.argmin(self.skel1.path_to_junction[node_pair[0], junct1])
                        idx2 = np.argmin(self.skel2.path_to_junction[node_pair[1], junct2])
                        if [junct1[idx1], junct2[idx2]] in final_corres.tolist():
                            final_corres = np.vstack((final_corres, node_pair))
                            vote_matrix[node_pair[0], :] = vote_matrix[:, node_pair[1]] = 0
                            #print 'added correspondence\n', final_corres
                            #print 'vote_matrix\n', vote_matrix
                        else:
                            vote_matrix[node_pair[0], node_pair[1]] = 0
                else:
                    vote_matrix[node_pair[0], node_pair[1]] = 0

                if np.all(vote_matrix == 0):
                    break

        self.final_corres = final_corres
Exemple #39
0
def main():
	conn = serial_interface.connect()

	cur_track = track.init_tracka()
	g = Graph()
	g.add_vertex(len(cur_track))
	for (vi, node) in enumerate(cur_track): node.i = vi

	n_title = g.new_vertex_property("string")
	n_color = g.new_vertex_property("string")
	n_pos = g.new_vertex_property("vector<double>")
	e_title = g.new_edge_property("string")
	e_dist = g.new_edge_property("double")

	for node in cur_track:
		v = g.vertex(node.i)
		n_title[v] = node.name
		if node.typ == track.NODE_EXIT:
			# Invert points to match our ASCII display.
			n_pos[v] = (-node.reverse.coord_x, -node.reverse.coord_y)
		else:
			n_pos[v] = (-node.coord_x, -node.coord_y)
		e = g.add_edge(g.vertex(node.i), g.vertex(node.reverse.i))
		if node.typ == track.NODE_SENSOR: n_color[v] = "blue"
		elif node.typ == track.NODE_BRANCH: n_color[v] = "orange"
		elif node.typ == track.NODE_MERGE: n_color[v] = "yellow"
		elif node.typ == track.NODE_ENTER: n_color[v] = "green"
		elif node.typ == track.NODE_EXIT: n_color[v] = "red"
		else: n_color[v] = "white"
		for edge in node.edge:
			if edge.src is None: continue
			e = g.add_edge(g.vertex(edge.src.i), g.vertex(edge.dest.i))
			e_dist[e] = edge.dist
			e_title[e] = "%.2f" % (edge.dist)

	win = graph_tool.draw.GraphWindow(g, n_pos, (640, 480), edge_text=e_title, vertex_fill_color=n_color, vertex_text=n_title)
	win.show_all()
	def destroy_callback(*args, **kwargs):
		win.destroy()
		Gtk.main_quit()

	def set_switch(sw, d):
		for node in cur_track:
			if node.typ == track.NODE_BRANCH and node.num == sw:
				node.switch_direction = d
				return
		print "WARN: Could not find switch %d" % sw

	class Train():
		num = -1
		vel = 0.
		speed = 0.
		edge = cur_track[0].edge[0]
		edge_dist = 0
		SPEEDX = 1.

		def __init__(self, num):
			self.num = num

		def update(self):
			# Super shitty deacceleration model
			self.vel = self.vel + (0.018/self.SPEEDX)*(self.speed - self.vel)
			self.edge_dist += self.vel
			while True:
				e = self.e()
				if self.edge_dist < e_dist[e]: break
				if self.edge.dest.typ == track.NODE_SENSOR:
					conn.set_sensor_tripped(self.edge.dest.num)
				self.edge = self.edge.dest.edge[self.edge.dest.switch_direction]
				self.edge_dist -= e_dist[e]

		def draw(self, n_pos, da, cr):
			e = self.e()
			start, end = np.array(n_pos[e.source()]), np.array(n_pos[e.target()])
			alpha = self.edge_dist / e_dist[e]
			pos = start + alpha*(end - start)
			dp = win.graph.pos_to_device(pos) # dp: device position
			cr.rectangle(dp[0]-10, dp[1]-10, 20, 20)
			cr.set_source_rgb(102. / 256, 102. / 256, 102. / 256)
			cr.fill()
			cr.move_to(dp[0]-10, dp[1] + 10 - 12./2)
			cr.set_source_rgb(1., 1., 1.)
			cr.set_font_size(12)
			cr.show_text("%d" % self.num)
			cr.fill()
		def e(self): return g.edge(self.edge.src.i, self.edge.dest.i)
		def set_speed(self, speed): self.speed = speed/self.SPEEDX
		def toggle_reverse(self):
			self.edge = self.edge.reverse
			self.edge_dist = e_dist[self.e()] - self.edge_dist

	def find_train(train_number):
		for train in trains:
			if train.num == train_number:
				return train
		train = Train(train_number)
		trains.append(train)
		return train

	trains = [Train(12)]
	startup_time = time.time()
	accumulated_error = [0.]
	last_time = [time.time()]
	last_sensor_poll = [0]
	FPS = 30.
	def my_draw(da, cr):
		(typ, a1, a2) = conn.next_cmd()
		if typ is None: pass
		elif typ == 'set_speed': find_train(a1).set_speed(a2)
		elif typ == 'toggle_reverse': find_train(a1).toggle_reverse()
		elif typ == 'switch': set_switch(a1, a2)
		elif typ == 'sensor': last_sensor_poll[0] = round((time.time() - startup_time) * 1000)/1000
		else: print "Ignoring command %s" % typ
		cur_time = time.time()
		dt = cur_time - last_time[0] + accumulated_error[0]
		num_steps = int(dt*FPS)
		accumulated_error[0] = dt - num_steps/FPS
		for train in trains:
			for _ in range(0, num_steps): train.update()
			train.draw(n_pos, da, cr)
			cr.move_to(10., 10.)
			cr.set_source_rgb(0., 0., 0.)
			cr.set_font_size(12)
			cr.show_text("Last polled at %.3f" % last_sensor_poll[0])
		da.queue_draw()
		last_time[0] = cur_time

	win.connect("delete_event", destroy_callback)
	win.graph.connect("draw", my_draw)
	Gtk.main()
def si(g, p, source=None, stop_fraction=0.5):
    """
    g: the graph
    p: edge-wise infection probability
    stop_fraction: stopping if more than N x stop_fraction nodes are infected
    """
    weighted = False
    if isinstance(p, PropertyMap):
        weighted = True
    else:
        # is float and uniform
        assert 0 < p and p <= 1

    if source is None:
        source = random.choice(np.arange(g.num_vertices()))
    infected = {source}
    infection_times = np.ones(g.num_vertices()) * -1
    infection_times[source] = 0
    time = 0
    edges = []

    stop = False

    infected_nodes_until_t = copy(infected)
    while True:
        infected_nodes_until_t = copy(infected)
        # print('current cascade size: {}'.format(len(infected_nodes_until_t)))
        time += 1
        for i in infected_nodes_until_t:
            vi = g.vertex(i)
            for e in vi.all_edges():
                if weighted:
                    inf_proba = p[e]
                else:
                    inf_proba = p
                vj = e.target()
                j = int(vj)
                rand = random.random()
                # print('rand=', rand)
                # print('inf_proba=', inf_proba)
                # print('{} infected?'.format(j), j not in infected)
                if j not in infected and rand <= inf_proba:
                    # print('SUCCESS')
                    infected.add(j)
                    infection_times[j] = time
                    edges.append((i, j))

                    # stop when enough nodes have been infected
                    if (len(infected) / g.num_vertices()) >= stop_fraction:
                        stop = True
                        break
            if stop:
                break
        if stop:
            break

    tree = Graph(directed=True)
    for _ in range(g.num_vertices()):
        tree.add_vertex()

    vertex_nodes = set()
    for u, v in edges:
        tree.add_edge(u, v)
        vertex_nodes.add(u)
        vertex_nodes.add(v)

    vfilt = tree.new_vertex_property('bool')
    vfilt.set_value(False)
    vfilt.a[list(vertex_nodes)] = True
    tree.set_vertex_filter(vfilt)

    return source, infection_times, tree
class BoardGraphGraphtool(BoardGraphBase):

    def __init__(self, number_of_vertices, graph_type):
        super().__init__(number_of_vertices, graph_type)
        # Graph tool creates directed multigraph by default.
        self._graph = Graph()
        self._graph.add_vertex(number_of_vertices)
        self._graph.vertex_properties["cell"] = self._graph.new_vertex_property(
            "object", number_of_vertices * [BoardCell()]
        )
        self._graph.edge_properties["direction"
                                   ] = self._graph.new_edge_property("object")
        self._graph.edge_properties["weight"
                                   ] = self._graph.new_edge_property("int")

    def __getitem__(self, position):
        return self._graph.vp.cell[self._graph.vertex(position)]

    def __setitem__(self, position, board_cell):
        self._graph.vp.cell[self._graph.vertex(position)] = board_cell

    def __contains__(self, position):
        return position in range(0, self.vertices_count())

    def vertices_count(self):
        return self._graph.num_vertices()

    def edges_count(self):
        return self._graph.num_edges()

    def has_edge(self, source_vertice, target_vertice, direction):
        for e in self._graph.vertex(source_vertice).out_edges():
            if (
                int(e.target()) == target_vertice and
                self._graph.ep.direction[e] == direction
            ):
                return True
        return False

    def out_edges_count(self, source_vertice, target_vertice):
        return len([
            1 for e in self._graph.vertex(source_vertice).out_edges()
            if int(e.target()) == target_vertice
        ])

    def reconfigure_edges(self, width, height, tessellation):
        """
        Uses tessellation object to create all edges in graph.
        """
        self._graph.clear_edges()
        for source_vertice in self._graph.vertices():
            for direction in tessellation.legal_directions:
                neighbor_vertice = tessellation.neighbor_position(
                    int(source_vertice),
                    direction,
                    board_width=width,
                    board_height=height
                )
                if neighbor_vertice is not None:
                    e = self._graph.add_edge(
                        source_vertice, neighbor_vertice, add_missing=False
                    )
                    self._graph.ep.direction[e] = direction

    # TODO: Faster version?
    # def reconfigure_edges(self, width, height, tessellation):
    #     """
    #     Uses tessellation object to create all edges in graph.
    #     """
    #     self._graph.clear_edges()
    #     edges_to_add = []
    #     directions_to_add = dict()
    #     for source_vertice in self._graph.vertices():
    #         for direction in tessellation.legal_directions:
    #             neighbor_vertice = tessellation.neighbor_position(
    #                 int(source_vertice), direction,
    #                 board_width=width, board_height=height
    #             )
    #             if neighbor_vertice is not None:
    #                 edge = (int(source_vertice), neighbor_vertice,)

    #                 edges_to_add.append(edge)

    #                 if edge not in directions_to_add:
    #                     directions_to_add[edge] = deque()

    #                 directions_to_add[edge].append(direction)

    #     self._graph.add_edge_list(edges_to_add) if edges_to_add else None

    #     for e in edges_to_add:
    #         e_descriptors = self._graph.edge(
    #             s = self._graph.vertex(e[0]),
    #             t = self._graph.vertex(e[1]),
    #             all_edges = True
    #         )

    #         for e_descriptor in e_descriptors:
    #             if len(directions_to_add[e]) > 0:
    #                 self._graph.ep.direction[e_descriptor] = directions_to_add[e][0]
    #                 directions_to_add[e].popleft()

    def calculate_edge_weights(self):
        for e in self._graph.edges():
            self._graph.ep.weight[e] = self.out_edge_weight(int(e.target()))

    def neighbor(self, from_position, direction):
        try:
            for e in self._graph.vertex(from_position).out_edges():
                if self._graph.ep.direction[e] == direction:
                    return int(e.target())
        except ValueError as e:
            raise IndexError(e.args)

        return None

    def wall_neighbors(self, from_position):
        return [
            int(n) for n in self._graph.vertex(from_position).out_neighbours()
            if self[int(n)].is_wall
        ]

    def all_neighbors(self, from_position):
        return [
            int(n) for n in self._graph.vertex(from_position).out_neighbours()
        ]

    def shortest_path(self, start_position, end_position):
        try:
            return [
                int(v)
                for v in shortest_path(
                    g=self._graph,
                    source=self._graph.vertex(start_position),
                    target=self._graph.vertex(end_position),
                )[0]
            ]
        except ValueError:
            return []

    def dijkstra_path(self, start_position, end_position):
        try:
            self.calculate_edge_weights()
            return [
                int(v)
                for v in shortest_path(
                    g=self._graph,
                    source=self._graph.vertex(start_position),
                    target=self._graph.vertex(end_position),
                    weights=self._graph.ep.weight,
                )[0]
            ]
        except ValueError:
            return []

    def position_path_to_direction_path(self, position_path):
        retv = []
        src_vertice_index = 0
        for target_vertice in position_path[1:]:
            source_vertice = position_path[src_vertice_index]
            src_vertice_index += 1

            for out_edge in self._graph.vertex(source_vertice).out_edges():
                if int(out_edge.target()) == target_vertice:
                    retv.append(self._graph.ep.direction[out_edge])

        return {
            'source_position': position_path[0] if position_path else None,
            'path': retv
        }
Exemple #42
0
def build_graph(df_list, sens='ST', top=410, min_sens=0.01,
                edge_cutoff=0.0):
    """
    Initializes and constructs a graph where vertices are the parameters
    selected from the first dataframe in 'df_list', subject to the
    constraints set by 'sens', 'top', and 'min_sens'.  Edges are the second
    order sensitivities of the interactions between those vertices,
    with sensitivities greater than 'edge_cutoff'.

    Parameters
    -----------
    df_list     : list
                  A list of two dataframes.  The first dataframe should be
                  the first/total order sensitivities collected by the
                  function data_processing.get_sa_data().
    sens        : str, optional
                  A string with the name of the sensitivity that you would
                  like to use for the vertices ('ST' or 'S1').
    top         : int, optional
                  An integer specifying the number of vertices to display (
                  the top sensitivity values).
    min_sens    : float, optional
                  A float with the minimum sensitivity to allow in the graph.
    edge_cutoff : float, optional
                  A float specifying the minimum second order sensitivity to
                  show as an edge in the graph.

    Returns
    --------
    g : graph-tool object
        a graph-tool graph object of the network described above.  Each
        vertex has properties 'param', 'sensitivity', and 'confidence'
        corresponding to the name of the parameter, value of the sensitivity
        index, and it's confidence interval.  The only edge property is
        'second_sens', the second order sensitivity index for the
        interaction between the two vertices it connects.
    """

    # get the first/total index dataframe and second order dataframe
    df = df_list[0]
    df2 = df_list[1]

    # Make sure sens is ST or S1
    if sens not in set(['ST', 'S1']):
        raise ValueError('sens must be ST or S1')
    # Make sure that there is a second order index dataframe
    try:
        if not df2:
            raise Exception('Missing second order dataframe!')
    except:
        pass

    # slice the dataframes so the resulting graph will only include the top
    # 'top' values of 'sens' greater than 'min_sens'.
    df = df.sort_values(sens, ascending=False)
    df = df.ix[df[sens] > min_sens, :].head(top)
    df = df.reset_index()

    # initialize a graph
    g = Graph()

    vprop_sens = g.new_vertex_property('double')
    vprop_conf = g.new_vertex_property('double')
    vprop_name = g.new_vertex_property('string')
    eprop_sens = g.new_edge_property('double')

    g.vertex_properties['param'] = vprop_name
    g.vertex_properties['sensitivity'] = vprop_sens
    g.vertex_properties['confidence'] = vprop_conf
    g.edge_properties['second_sens'] = eprop_sens

    # keep a list of all the vertices
    v_list = []

    # Add the vertices to the graph
    for i, param in enumerate(df['Parameter']):
        v = g.add_vertex()
        vprop_sens[v] = df.ix[i, sens]
        vprop_conf[v] = 1 + df.ix[i, '%s_conf' % sens] / df.ix[i, sens]
        vprop_name[v] = param
        v_list.append(v)

    # Make two new columns in second order dataframe that point to the vertices
    # connected on each row.
    df2['vertex1'] = -999
    df2['vertex2'] = -999
    for vertex in v_list:
        param = g.vp.param[vertex]
        df2.ix[df2['Parameter_1'] == param, 'vertex1'] = vertex
        df2.ix[df2['Parameter_2'] == param, 'vertex2'] = vertex

    # Only allow edges for vertices that we've defined
    df_edges = df2[(df2['vertex1'] != -999) & (df2['vertex2'] != -999)]
    # eliminate edges below a certain cutoff value
    pruned = df_edges[df_edges['S2'] > edge_cutoff]
    pruned.reset_index(inplace=True)
    # Add the edges for the graph
    for i, sensitivity in enumerate(pruned['S2']):
        v1 = pruned.ix[i, 'vertex1']
        v2 = pruned.ix[i, 'vertex2']
        e = g.add_edge(v1, v2)
        # multiply by a number to make the lines visible on the plot
        eprop_sens[e] = sensitivity * 150

    # These are ways you can reference properties of vertices or edges
    # g.vp.param[g.vertex(77)]
    # g.vp.param[v_list[0]]

    print ('Created a graph with %s vertices and %s edges.\nVertices are the '
           'top %s %s values greater than %s.\nOnly S2 values (edges) '
           'greater than %s are included.' %
           (g.num_vertices(), g.num_edges(), top, sens, min_sens, edge_cutoff))

    return g
Exemple #43
0
    def makeGraph(self,img,dia,xScale,yScale):
        print 'Building Graph Data Structure'
        start=time.time()
        G = Graph(directed=False)
        vprop=G.new_vertex_property('object')
        eprop=G.new_edge_property('object')
        epropW=G.new_edge_property("int32_t")
        avgScale=(xScale+yScale)/2

        test=np.where(img==True)
        ss = np.shape(test)
        cccc=0
        percentOld=0.0
        print str(np.round(percentOld,1))+'%'
        for (i,j) in zip(test[1],test[0]):
                cccc+=1
                percent=(float(cccc)/float(ss[1]))*100
                if percentOld+10< percent: 
                    print str(np.round(percent,1))+'%'
                    percentOld=percent
                nodeNumber1 = (float(i)*yScale,float(j)*xScale)
                if gu.find_vertex(G, vprop, {'imgIdx':(j,i),'coord':nodeNumber1, 'nrOfPaths':0, 'diameter':float(dia[j][i])*avgScale}):
                            v1=gu.find_vertex(G, vprop, {'imgIdx':(j,i),'coord':nodeNumber1, 'nrOfPaths':0, 'diameter':float(dia[j][i])*avgScale})[0]
                else:
                    v1=G.add_vertex()
                    vprop[G.vertex(v1)]={'imgIdx':(j,i),'coord':nodeNumber1, 'nrOfPaths':0, 'diameter':float(dia[j][i])*avgScale}
                try:
                    
                    if img[j,i+1] == True:
                        nodeNumber2 = (float(i+1)*yScale,float(j)*xScale)
                        if gu.find_vertex(G, vprop, {'imgIdx':(j,i+1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i+1])*avgScale}):
                            v2=gu.find_vertex(G, vprop, {'imgIdx':(j,i+1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i+1])*avgScale})[0]
                            if gu.find_edge(G, eprop, {'coord1':vprop[v2]['coord'], 'coord2':vprop[v1]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}):
                                pass
                            else:
                                e = G.add_edge(v1, v2)
                                epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                                eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                        else:
                            v2=G.add_vertex()
                            vprop[G.vertex(v2)]={'imgIdx':(j,i+1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i+1])*avgScale}
                            e = G.add_edge(v1, v2)
                            epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                            eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                except:
                    pass
                try:
                    if img[j,i-1] == True:
                        nodeNumber2 = (float(i-1)*yScale,float(j)*xScale)
                        if gu.find_vertex(G, vprop, {'imgIdx':(j,i-1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i-1])*avgScale}):
                            v2=gu.find_vertex(G, vprop, {'imgIdx':(j,i-1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i-1])*avgScale})[0]
                            if gu.find_edge(G, eprop, {'coord1':vprop[v2]['coord'], 'coord2':vprop[v1]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}):
                                pass
                            else:
                                e = G.add_edge(v1, v2)
                                epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                                eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                        else:
                            v2=G.add_vertex()
                            vprop[G.vertex(v2)]={'imgIdx':(j,i-1),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j][i-1])*avgScale}
                            e = G.add_edge(v1, v2)
                            epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                            eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                except:pass
                try:
                    if img[j + 1,i] == True:
                        nodeNumber2 = (float(i)*yScale,float(j+1)*xScale)
                        if gu.find_vertex(G, vprop, {'imgIdx':(j+1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j+1][i])*avgScale}):
                            v2=gu.find_vertex(G, vprop, {'imgIdx':(j+1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j+1][i])*avgScale})[0]
                            if gu.find_edge(G, eprop, {'coord1':vprop[v2]['coord'], 'coord2':vprop[v1]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}):
                                pass
                            else:
                                e = G.add_edge(v1, v2)
                                epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                                eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                        else:
                            v2=G.add_vertex()
                            vprop[G.vertex(v2)]={'imgIdx':(j+1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j+1][i])*avgScale}
                            e = G.add_edge(v1, v2)
                            epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                            eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                except:pass
                try:
                    if img[j - 1,i] == True:
                        nodeNumber2 = (float(i)*yScale,float(j-1)*xScale)
                        if gu.find_vertex(G, vprop, {'imgIdx':(j-1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j-1][i])*avgScale}):
                            v2=gu.find_vertex(G, vprop, {'imgIdx':(j-1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j-1][i])*avgScale})[0]
                            if gu.find_edge(G, eprop, {'coord1':vprop[v2]['coord'], 'coord2':vprop[v1]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}):
                                pass
                            else:
                                e = G.add_edge(v1, v2)
                                epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                                eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                        else:
                            v2=G.add_vertex()
                            vprop[G.vertex(v2)]={'imgIdx':(j-1,i),'coord':nodeNumber2, 'nrOfPaths':0, 'diameter':float(dia[j-1][i])*avgScale}
                            e = G.add_edge(v1, v2)
                            epropW[e]=(((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)/avgScale)**4
                            eprop[e]={'coord1':vprop[v1]['coord'], 'coord2':vprop[v2]['coord'],'weight':((vprop[v1]['diameter']+vprop[v2]['diameter'])/2)**4,'RTP':False}
                except: pass
#                    
        print '100.0%'
        print 'selecting largest connected component'
        G.edge_properties["ep"] = eprop
        G.edge_properties["w"] = epropW
        G.vertex_properties["vp"] = vprop
        l = gt.label_largest_component(G)
        print(l.a)
        u = gt.GraphView(G, vfilt=l)
        print '# vertices'
        print(u.num_vertices())
        print(G.num_vertices())
        print '# edges'
        print(u.num_edges())
        print 'building graph finished in: '+str(time.time()-start)+'s'
        return u 
        request.append(temp_source)
        while(1):
            temp_target = randint(0, 13)
            if(not(temp_target == temp_source)):
                request.append(temp_target)
                break
        if not(request in all_requests):
            all_requests.append(request)

    #print("Number of requests are " + str(len(all_requests)))

## Defining the graph properties ##
graph_weight = g.new_edge_property("float")
g.ep.weight = graph_weight

graph_pred_tree = g.new_vertex_property("int")
pred_tree = graph_pred_tree

edges_logger = {}

for e in g.edges():
    flags_of_edges = []
    # Temporary flag to ensure that alternative path is not on the primary path itself
    flags_of_edges.append(1)
    # Flags to see which channels are currently in use
    for i in range(number_frequency_bands):
        flags_of_edges.append(1)
    # Flags to keep record of the extent of the usage of a particular channel in a link
    for i in range(number_frequency_bands):
        flags_of_edges.append(0)
    # Flags to fulfil the single point failure protection between those who share their primary paths