Esempio n. 1
0
def test_maximal_matching():
    graph = nx.Graph()
    graph.add_edge(0, 1)
    graph.add_edge(0, 2)
    graph.add_edge(0, 3)
    graph.add_edge(0, 4)
    graph.add_edge(0, 5)
    graph.add_edge(1, 2)
    matching = nx.maximal_matching(graph)

    vset = set(u for u, v in matching)
    vset = vset | set(v for u, v in matching)

    for edge in graph.edges_iter():
        u, v = edge
        ok_(len(set([v]) & vset) > 0 or len(set([u]) & vset) > 0, "not a proper matching!")

    eq_(1, len(matching), "matching not length 1!")
    graph = nx.Graph()
    graph.add_edge(1, 2)
    graph.add_edge(1, 5)
    graph.add_edge(2, 3)
    graph.add_edge(2, 5)
    graph.add_edge(3, 4)
    graph.add_edge(3, 6)
    graph.add_edge(5, 6)

    matching = nx.maximal_matching(graph)
    vset = set(u for u, v in matching)
    vset = vset | set(v for u, v in matching)

    for edge in graph.edges_iter():
        u, v = edge
        ok_(len(set([v]) & vset) > 0 or len(set([u]) & vset) > 0, "not a proper matching!")
Esempio n. 2
0
def min_maximal_matching(G):
    """Returns the minimum maximal matching of G. That is, out of all maximal
    matchings of the graph G, the smallest is returned.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    Returns
    -------
    min_maximal_matching : set
      Returns a set of edges such that no two edges share a common endpoint
      and every edge not in the set shares some common endpoint in the set.
      Cardinality will be 2*OPT in the worst case.

    Notes
    -----
    The algorithm computes an approximate solution fo the minimum maximal
    cardinality matching problem. The solution is no more than 2 * OPT in size.
    Runtime is O(|E|).

    References
    ----------
    .. [1] Vazirani, Vijay Approximation Algorithms (2001)
    """
    return nx.maximal_matching(G)
 def f37(self):
     start = 0
     s = nx.maximal_matching(self.G)
     res = len(s)
     stop = 0
     # self.feature_time.append(stop - start)
     return res
Esempio n. 4
0
    def minleaf(G, start):
        dag = __class__.get_dag(G, start)

        GG = nx.Graph()
        GG.add_nodes_from(G)
        GG.add_edges_from(dag)
        B = nx.DiGraph()
        tgt_dict = dict()
        mm_tgt_set = set()
        tmin = []
        for edge in dag:
            src = edge[0]
            tgt = (edge[1][0] + 100, edge[1][1] + 100)
            tgt_dict.setdefault(tgt, []).append(src)
            B.add_edge(src, tgt)
        mm = nx.maximal_matching(B)
        for edge in mm:
            mm_tgt_set.add(edge[1])
        for node in tgt_dict:
            if node not in mm_tgt_set:
                mm.add((tgt_dict[node][0], node))
        for edge in mm:
            tgt = (edge[1][0] - 100, edge[1][1] - 100)
            assert tgt[0] >= 0 and tgt[1] >= 0
            tmin.append((edge[0], tgt))

        return tmin, dag
 def f37(self):
     start = 0
     s = nx.maximal_matching(self.G)
     res = len(s)
     stop = 0
     # self.feature_time.append(stop - start)
     return res
Esempio n. 6
0
def is_subtree(G, u, H, w, subtree):
    G_childs = G.childrenOf[u]
    H_childs = H.childrenOf[w]

    # If the subtrees don't have the same number of children, they can't
    # possibly be isomorphic
    if len(G_childs) != len(H_childs):
        subtree[(u, w)] = False
    else:

        print G.G.edges(), H.G.edges(), u, w

        edgeSet = []
        for ui in G_childs:
            for wi in H_childs:
                edge = (ui, wi)
                if edge in subtree and subtree[edge] == True:
                    edgeSet.append(edge)

        bg = nx.Graph()
        bg.add_nodes_from(G_childs, bipartite=0)
        bg.add_nodes_from(H_childs, bipartite=1)
        bg.add_edges_from(edgeSet)

        print bg.nodes(), bg.edges()

        matchingSize = len(nx.maximal_matching(bg))
        if matchingSize == (len(bg.nodes()) / 2): # perfect matching for bg
            subtree[(u, w)] = True
Esempio n. 7
0
def generate_coarser_graph(G, level):
    if G.number_of_nodes() <= 2: return G, level

    # sort the edges

    col[level] = {}
    edges[level] = {}

    mie = nx.maximal_matching(G)
    if (len(mie)) == 0:
        return G, level
    for i in mie:
        new_node = "{0}-{1}".format(i[0], i[1])
        G.add_node(new_node)
        col[level][new_node] = list(i)
        c1, c2 = i[0], i[1]
        cn1, cn2 = list(G.adj[c1]), list(G.adj[c2])
        G.remove_node(c1)
        G.remove_node(c2)
        edges[level][new_node] = []
        for i in cn1:
            if i == c1 or i == c2: continue
            G.add_edge(i, new_node)
            edges[level][new_node].append((i, c1))

        for i in cn2:
            if i == c1 or i == c2: continue
            G.add_edge(i, new_node)
            edges[level][new_node].append((i, c2))
    return generate_coarser_graph(G, level + 1)
Esempio n. 8
0
def min_maximal_matching(G):
    """Returns the minimum maximal matching of G. That is, out of all maximal
    matchings of the graph G, the smallest is returned.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    Returns
    -------
    min_maximal_matching : set
      Returns a set of edges such that no two edges share a common endpoint
      and every edge not in the set shares some common endpoint in the set.
      Cardinality will be 2*OPT in the worst case.

    Notes
    -----
    The algorithm computes an approximate solution fo the minimum maximal
    cardinality matching problem. The solution is no more than 2 * OPT in size.
    Runtime is O(|E|).

    References
    ----------
    .. [1] Vazirani, Vijay Approximation Algorithms (2001)
    """
    return nx.maximal_matching(G)
Esempio n. 9
0
def test_maximal_matching_ordering():
    # check edge ordering
    G = nx.Graph()
    G.add_nodes_from([100, 200, 300])
    G.add_edges_from([(100, 200), (100, 300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
    G = nx.Graph()
    G.add_nodes_from([200, 100, 300])
    G.add_edges_from([(100, 200), (100, 300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
    G = nx.Graph()
    G.add_nodes_from([300, 200, 100])
    G.add_edges_from([(100, 200), (100, 300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
Esempio n. 10
0
    def compute_features(self):

        self.add_feature(
            "maximal_matching",
            lambda graph: len(nx.maximal_matching(graph)),
            "Maximal matching",
            InterpretabilityScore(4),
        )
Esempio n. 11
0
def test_maximal_matching_ordering():
    # check edge ordering
    G = nx.Graph()
    G.add_nodes_from([100,200,300])
    G.add_edges_from([(100,200),(100,300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
    G = nx.Graph()
    G.add_nodes_from([200,100,300])
    G.add_edges_from([(100,200),(100,300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
    G = nx.Graph()
    G.add_nodes_from([300,200,100])
    G.add_edges_from([(100,200),(100,300)])
    matching = nx.maximal_matching(G)
    assert_equal(len(matching), 1)
Esempio n. 12
0
 def test_self_loops(self):
     # Create the path graph with two self-loops.
     G = nx.path_graph(3)
     G.add_edges_from([(0, 0), (1, 1)])
     matching = nx.maximal_matching(G)
     assert_equal(len(matching), 1)
     # The matching should never include self-loops.
     assert_false(any(u == v for u, v in matching))
     assert_true(nx.is_maximal_matching(G, matching))
Esempio n. 13
0
 def test_self_loops(self):
     # Create the path graph with two self-loops.
     G = nx.path_graph(3)
     G.add_edges_from([(0, 0), (1, 1)])
     matching = nx.maximal_matching(G)
     assert_equal(len(matching), 1)
     # The matching should never include self-loops.
     assert_false(any(u == v for u, v in matching))
     assert_true(nx.is_maximal_matching(G, matching))
Esempio n. 14
0
def calculate_mcm(graph):
    G = nx.Graph()
    for v in graph:
        G.add_node(str(v))
    for v in graph:
        for e in graph[v]:
            G.add_edge(str(v), str(e))

    return [(int(left), int(right)) for left, right in nx.maximal_matching(G)]
Esempio n. 15
0
    def run_mechanism(self):
        k_max = max(int(self.B_depart[-1]//self.d), int(self.S_depart[-1]//self.d))
        B_alive_idx = np.array([],dtype=int) #Store indices of alive buy bids
        S_alive_idx = np.array([],dtype=int) #Store indices of alive sell bids
        B_current = 0
        S_current = 0
        G = nx.DiGraph()
        for k in range(k_max):
            start = k*self.d 
            end = (k+1) * self.d
            # Remove departing bids
            if B_alive_idx.size != 0:
                B_depart_idx = B_alive_idx[np.where(self.B_depart[B_alive_idx] <= end)]
                B_alive_idx = np.setdiff1d(B_alive_idx,B_depart_idx)
                for b in B_depart_idx:
                    if (-b-1) in G:
                        G.remove_node(-b-1)
                    
            if S_alive_idx.size != 0:
                S_depart_idx = S_alive_idx[np.where(self.S_depart[S_alive_idx] <= end)]
                S_alive_idx = np.setdiff1d(S_alive_idx,S_depart_idx)
                for s in S_depart_idx:
                    if (s+1) in G:
                        G.remove_node(s+1)

            # Add arriving bids
            while B_current < len(self.B) and self.B_arrival[B_current] <= end:
                B_alive_idx = np.append(B_alive_idx,B_current)
                S_candidates = S_alive_idx[np.where(self.S[S_alive_idx] <= self.B[B_current])]
                for s in S_candidates:
                    G.add_edge(s+1, -B_current-1)         
                B_current = B_current + 1

            while S_current < len(self.S) and self.S_arrival[S_current] <= end:
                S_alive_idx = np.append(S_alive_idx,S_current)
                B_candidates = B_alive_idx[np.where(self.B[B_alive_idx] >= self.S[S_current])]
                for b in B_candidates:
                    G.add_edge(S_current+1, -b-1)
                S_current = S_current + 1


            # Clear matching
            M_new = nx.maximal_matching(G)
            M_num_new = len(M_new)
            if np.array(list(M_new)).size != 0:
                S_M_new = np.array(list(M_new))[:,0]-1
                B_M_new = -np.array(list(M_new))[:,1]-1

                self.B_M = np.hstack((self.B_M, B_M_new))
                self.S_M = np.hstack((self.S_M, S_M_new))
                self.M_num = self.M_num + M_num_new
                B_alive_idx = np.setdiff1d(B_alive_idx, B_M_new)
                G.remove_nodes_from(-B_M_new-1)
                S_alive_idx = np.setdiff1d(S_alive_idx, S_M_new)
                G.remove_nodes_from(S_M_new-1)
        return self.B[self.B_M], self.S[self.S_M]
def maximal_matching(nodes, edges):
    g = nx.from_edgelist(edges)
    mat = nx.maximal_matching(g)
    weight = np.zeros(len(g.edges))
    k = 0
    for e in g.edges:
        if e in mat:
            weight[k] = 1
        k += 1
    return weight
Esempio n. 17
0
    def test_ordering(self):
        """Tests that a maximal matching is computed correctly
        regardless of the order in which nodes are added to the graph.

        """
        for nodes in permutations(range(3)):
            G = nx.Graph()
            G.add_nodes_from(nodes)
            G.add_edges_from([(0, 1), (0, 2)])
            matching = nx.maximal_matching(G)
            assert_equal(len(matching), 1)
            assert_true(nx.is_maximal_matching(G, matching))
Esempio n. 18
0
def Maximal_matching(grafo):
    tiempo=[]
    for i in range(30):
        tiempo_inicial = dt.datetime.now()
        for j in range(1000):
            nx.maximal_matching(grafo)
        tiempo_final = dt.datetime.now()
        tiempo_ejecucion = (tiempo_final - tiempo_inicial).total_seconds()
        tiempo.append(tiempo_ejecucion)
    
    media=nup.mean(tiempo)
    desv=nup.std(tiempo)
    mediana=nup.median(tiempo)
    datos["algoritmo"].append("Maximal_matching")
    datos["grafo"].append(grafo.name)
    datos["cant_vertice"].append(grafo.number_of_nodes())
    datos["cant_arista"].append(grafo.number_of_edges())
    datos["media"].append(media)
    datos["desv"].append(desv)
    datos["mediana"].append(mediana)
    return datos
Esempio n. 19
0
    def test_ordering(self):
        """Tests that a maximal matching is computed correctly
        regardless of the order in which nodes are added to the graph.

        """
        for nodes in permutations(range(3)):
            G = nx.Graph()
            G.add_nodes_from(nodes)
            G.add_edges_from([(0, 1), (0, 2)])
            matching = nx.maximal_matching(G)
            assert_equal(len(matching), 1)
            assert_true(nx.is_maximal_matching(G, matching))
Esempio n. 20
0
    def gen_edges(self, graph):
        # Split Cv and generate alias graph
        if not self.a_graph:
            self.a_graph = self.split(graph)

        # Solve max matching to obtain round
        queue = nx.maximal_matching(self.a_graph)

        # Cull active edges
        self.a_graph.remove_edges_from(queue)

        # Reassociate aliases
        return [(e[0].org, e[1].org) for e in queue]
Esempio n. 21
0
def rank_maximal_allocation(G, agent_cap=None):
    """Returns a rank-maximal matching of G, which is assumed to be a weighted bipartite graph, using Irving's algorithm.

    Args:
        G (nx.Graph): Weighted bipartite Graph with nodes named after natural numbers and positive weights on each edge. Agents are assumed to be nodes 1 through
        i for some i <= n.
        agent_cap (int): The numerical label of the last agent; that is, if agents are enumerated by nodes 1 through i, then agent_cap is equal to i. Defaults
        to len(G.nodes)//2 if not given.

    Returns:
        A set of 2-tuples representing a matching on G that has the rank-maximality property.
    """
    if agent_cap is None:
        agent_cap = len(G.nodes) // 2

    H = G.copy()
    n = len(H.nodes)
    rankify_graph(H, agent_cap)

    edge_list = [set() for i in range(n)]

    for (agent, good) in H.edges:
        edge_list[H[agent][good]['rank']].add((agent, good))

    I = nx.Graph()
    I.add_nodes_from(H.nodes)

    S = set()

    for i in range(n):
        I.add_edges_from(edge_list[i])
        S = nx.maximal_matching(I)
        even_odd_unreachable_decomposition(I)

        for j in range(i + 1, n):
            to_remove = set()
            for (u, v) in edge_list[j]:
                if I.nodes[u]['decomp'] in [
                        'O', 'U'
                ] or I.nodes[v]['decomp'] in ['O', 'U']:
                    to_remove.add((u, v))

            edge_list[j] = edge_list[j].difference(to_remove)

        for (x, y) in I.edges:
            if I.nodes[x]['decomp'] + I.nodes[y]['decomp'] in [
                    'OO', 'UO', 'OU'
            ]:
                I.remove_edge((x, y))

    return S
Esempio n. 22
0
def bottleneckassignment(Bottleneckgraph):
    """
    :param Bottleneckgraph: networkx graph between initial states of the agent and initial elements of the targets
    :return:
    matching: optimal bottleneck matching between agents and assignments
    """
    costlow=0
    costhigh=1e6
    #compute optimal bottleneck matching
    print("computing bottleneck assignment")
    while costhigh-costlow>1e-3:
        aux_graph=Bottleneckgraph.copy()
        cost_bisec=(costhigh+costlow)/2

        #remove edges if the cost is larger than the current cost

        dict_item=list(aux_graph.edges(data=True))
        for item in dict_item:
            if aux_graph[item[0]][item[1]]['weight']>cost_bisec:
                aux_graph.remove_edge(item[0],item[1])

        #print(aux_graph.edges)
        #for item in aux_graph.edges:
        #    print(item,aux_graph[item[0]][item[1]]['weight'])
        #try if there exists a matching, if not, do not return it
        matching = nx.maximal_matching(aux_graph)
        matching_node=[]
        for item in list(matching):
            matching_node.append(item[0])
            matching_node.append(item[1])

        matchflag=True
        for nodes in aux_graph:
            #print(nodes,matching,list(matching),nodes in matching_node,matching_node)
            if nodes in matching_node:
                pass
            else:
                matchflag=False
        if matchflag:
            #matching=nx.maximal_matching(aux_graph)
            costhigh=cost_bisec
            #print(matching,cost_bisec,"matching")
            matchingdict=dict()
            for item in list(matching):
                matchingdict[item[0]]=item[1]
                matchingdict[item[1]]=item[0]

        else:
            costlow=cost_bisec

    return matchingdict
Esempio n. 23
0
def maximal_matching(nombre):#Para Grafo Simple Aciclico No dirigido
    df = pd.read_csv(nombre, header=None) 
    b = nx.from_pandas_adjacency(df, create_using=nx.Graph())

    for i in range(30):
        inicio = datetime.datetime.now()
        for key in range(50): # Ejecutar las 50 corridas         
            nx.maximal_matching(b)
        final = datetime.datetime.now()
        tiempos.append((final - inicio).total_seconds()) # Guardo los tiempos de las corridas 
        
    media=np.mean(tiempos)
    desv=np.std(tiempos)
    mediana=np.median(tiempos)
    nodos=nx.number_of_nodes(b) 
    arcos=nx.number_of_edges(b) 
    salvar=[]
    salvar.append(media)
    salvar.append(desv)
    salvar.append(mediana)
    salvar.append(nodos)
    salvar.append(arcos)

    return salvar
Esempio n. 24
0
def test_maximal_matching():
    graph = nx.Graph()
    graph.add_edge(0, 1)
    graph.add_edge(0, 2)
    graph.add_edge(0, 3)
    graph.add_edge(0, 4)
    graph.add_edge(0, 5)
    graph.add_edge(1, 2)
    matching = nx.maximal_matching(graph)

    vset = set(u for u, v in matching)
    vset = vset | set(v for u, v in matching)

    for edge in graph.edges_iter():
        u, v = edge
        ok_(len(set([v]) & vset) > 0 or len(set([u]) & vset) > 0, \
                "not a proper matching!")

    eq_(1, len(matching), "matching not length 1!")
    graph = nx.Graph()
    graph.add_edge(1, 2)
    graph.add_edge(1, 5)
    graph.add_edge(2, 3)
    graph.add_edge(2, 5)
    graph.add_edge(3, 4)
    graph.add_edge(3, 6)
    graph.add_edge(5, 6)

    matching = nx.maximal_matching(graph)
    vset = set(u for u, v in matching)
    vset = vset | set(v for u, v in matching)

    for edge in graph.edges_iter():
        u, v = edge
        ok_(len(set([v]) & vset) > 0 or len(set([u]) & vset) > 0, \
                "not a proper matching!")
def min_edge_dominating_set(graph):
    """Return minimum weight dominating edge set.

    Parameters
    ----------
    graph : NetworkX graph
      Undirected graph

    Returns
    -------
    min_edge_dominating_set : set
      Returns a set of dominating edges whose size is no more than 2 * OPT.
    """
    if not graph:
        raise ValueError("Expected non-empty NetworkX graph!")
    return nx.maximal_matching(graph)
Esempio n. 26
0
def min_edge_dominating_set(graph):
    """Return minimum weight dominating edge set.

    Parameters
    ----------
    graph : NetworkX graph
      Undirected graph

    Returns
    -------
    min_edge_dominating_set : set
      Returns a set of dominating edges whose size is no more than 2 * OPT.
    """
    if not graph:
        raise ValueError("Expected non-empty NetworkX graph!")
    return nx.maximal_matching(graph)
Esempio n. 27
0
def mwm_homs(homs, ls, rs):
    '''get max cardinamlity homs'''
    edgelist = []
    for l, r in homs:
        if l in ls and r in rs:
            edgelist.append((l, r))

    G = nx.from_edgelist(edgelist)
    _hs = nx.maximal_matching(G)
    hs = []
    for pair in _hs:
        if pair[0] in rs and pair[1] in ls:
            hs.append((pair[1], pair[0]))
        elif pair[1] in rs and pair[0] in ls:
            hs.append(pair)
        else:
            assert False, "We shouldn't have this case..."
    return hs
Esempio n. 28
0
def contract_edges_matching(G, num_iters=2):
    """Given a graph G and a desired number of edges to be contracted, contracts edges
    uniformly at random (non-mutating of the original graph). Edges are contracted such
    that the two endpoints are now "identified" with one another. This mapping is returned
    as a dictionary If more edges are provided than can be contracted, an error is thrown. 

    Returns (1) contracted graph (NetworkX Graph); 
    (2) identified nodes dictionary (NetworkX node -> NetworkX node)
    """
    identified_nodes = {}
    for _ in range(num_iters):
        edges = list(G.edges)
        matching = nx.maximal_matching(G)
        for vertex_pair in matching:
            identified_nodes[vertex_pair[0]] = vertex_pair[
                0]  # right gets contracted into left
            G = nx.contracted_edge(G, vertex_pair, self_loops=False)
    return G, identified_nodes
Esempio n. 29
0
def execute_all_possible_int_gates(routing: Routing, int_pairs: Set[frozenset]) -> bool:
    int_graph = nx.Graph()
    gate_executed = False
    for int_pair in int_pairs:
        hard_qb0 = routing.mapping.log2hard[list(int_pair)[0]]
        hard_qb1 = routing.mapping.log2hard[list(int_pair)[1]]
        if routing.qpu.graph.has_edge(hard_qb0, hard_qb1):
            if routing.layers[-1].int_gate_applicable(frozenset((hard_qb0, hard_qb1))):
                int_graph.add_edge(hard_qb1, hard_qb0)
                gate_executed = True
    matching = nx.maximal_matching(int_graph)
    for match in matching:
        gate = frozenset(match)
        log_qb0 = routing.mapping.hard2log[list(match)[0]]
        log_qb1 = routing.mapping.hard2log[list(match)[1]]
        int_pair = frozenset((log_qb0, log_qb1))
        routing.apply_int(gate)
        int_pairs.remove(int_pair)
    return gate_executed
Esempio n. 30
0
def draw_bipartite_matching(ax):
    BasicGraphSet.ax_set(ax, 'maximal matching')
    g = nx.Graph()
    g.add_edges_from([('a', 'b'), ('a', 'c'), ('a', 'e'), ('b', 'd'),
                      ('d', 'e')])
    if not nx.bipartite.is_bipartite(g):
        print('This graph is not bipartite')
        return
    print('This graph is bipartite')
    l, r = nx.bipartite.sets(g)
    node_colors = BasicGraphSet.set_property_for_nodes(g.nodes, l, 'green',
                                                       'yellow')
    max_matching = nx.maximal_matching(g)  # a dict, eg {('a', 'b'), ('b', 'c)}
    edge_colors = BasicGraphSet.set_property_for_edges(g.edges, max_matching,
                                                       'black', 'r')
    BasicGraphSet.basic_draw_color(g,
                                   ax,
                                   edge_colors=edge_colors,
                                   node_colors=node_colors)
Esempio n. 31
0
def max_cardinality_matching(Mrkt, Agents, verbose=False):
    """
    Find a maximal cardinality matching in the graph.
    A matching is a subset of edges in which no node occurs more than once. 
    The cardinality of a matching is the number of matched edges.
    Implemented by NetworkX
    Runtime: O(e) for e edges

    The algorithm greedily selects a maximal matching M of the graph G
    (i.e. no superset of M exists). It runs in `O(|E|)` time.

    Arguments
    ---------
    Mrkt: mm.Market object
        The market in which the matches are made
    Agents: list
        list of agents initiating matches
    verbose: bool
        Whether algorithm prints information on action
    Returns
    -------
    dict { agent.name : agent.name } of matches

    """
    if verbose:
        print("\nMax Weight Match Algorithm\n")
        print("Agents to match ", [a.name for a in Agents], "\n")

    # If Agents not whole market, get subgraph
    if len(Mrkt.Graph.nodes()) != len(Agents):
        to_match = deepcopy(Mrkt.Graph.subgraph(Agents))
    else:
        to_match = Mrkt.Graph
    # Workaround of assertionerror in Nx verifyOptimum() function
    # Breaks around integer weights
    for u, v, d in to_match.edges(data=True):
        d['weight'] = float(d['weight'])

    mate = nx.maximal_matching(to_match)

    result = {a[0].name: a[1].name for a in mate}
    return result
Esempio n. 32
0
def Dilworth(ng):
    global unmatched

    g = nx.Graph()
    gdas = nx.Graph()

    # Creating bipirate graph from a partial order, and partitioning into chains according to a matching
    for n in nx.topological_sort(ng, ng.nodes()):
        g.add_node(Copy0(n))
        g.node[Copy0(n)]['label'] = Copy0(ng.node[n]['label'])
        g.add_node(Copy1(n))
        g.node[Copy1(n)]['label'] = Copy1(ng.node[n]['label'])
        gdas.add_node(Copy0(n))
        gdas.add_node(Copy1(n))

    for n in nx.nodes(ng):
        for (u, v) in nx.edges(ng, n):
            g.add_edge(Copy0(n), Copy1(v))

    # Running matching algorithm
    s = nx.maximal_matching(g)
    gdas.add_edges_from(s)
    unmatched = nx.number_of_nodes(ng)
    # print 'unmatched = ', unmatched
    # nx.drawing.nx_pydot.write_dot(gdas,'sample.dot')
    # print s

    chains = []
    while len(s) > 0:
        # print '********', len(s)
        seed = next(iter(s))
        chain = []

        ExtendForward(gdas, ng, s, seed, chain, chains)
        # print '///////////'
        ExtendBackward(gdas, ng, s, seed, chain, chains)
        # print len(s)
        # print len(chain) + 1

        unmatched = unmatched - 1
        chains.append(chain)
Esempio n. 33
0
def min_maximal_matching(graph):
    """Returns a set of edges such that no two edges share a common endpoint
    and every edge not in the set shares some common endpoint in the set.

    Parameters
    ----------
    graph : NetworkX graph
      Undirected graph

    Returns
    -------
    min_maximal_matching : set
      Returns a set of edges such that no two edges share a common endpoint
      and every edge not in the set shares some common endpoint in the set.
      Cardinality will be 2*OPT in the worst case.

    References
    ----------
    .. [1] Vazirani, Vijay Approximation Algorithms (2001)
    """
    return nx.maximal_matching(graph)
Esempio n. 34
0
def min_maximal_matching(graph):
    """Returns a set of edges such that no two edges share a common endpoint
    and every edge not in the set shares some common endpoint in the set.

    Parameters
    ----------
    graph : NetworkX graph
      Undirected graph

    Returns
    -------
    min_maximal_matching : set
      Returns a set of edges such that no two edges share a common endpoint
      and every edge not in the set shares some common endpoint in the set.
      Cardinality will be 2*OPT in the worst case.

    References
    ----------
    .. [1] Vazirani, Vijay Approximation Algorithms (2001)
    """
    return nx.maximal_matching(graph)
Esempio n. 35
0
def displayMatching(people: dict, edges: List[list]):
    graph = nx.Graph()
    for p in people.values():
        graph.add_node(p.p_id)

    for edge in edges:
        w = edge[0].rel + edge[1].rel
        graph.add_edge(edge[0].p_id, edge[1].p_id, weight=w)

    max_match = nx.maximal_matching(graph)
    max_match_w = nx.max_weight_matching(graph)

    labels = nx.get_edge_attributes(graph, 'weight')
    plt.ion()
    plt.figure()
    plt.title("Max Matching Graph")
    pos = nx.spring_layout(graph, seed=42)
    pos2 = nx.spring_layout(graph, seed=42)
    nx.draw(graph, pos=pos, with_labels=True, font_color='w')
    nx.draw_networkx_edges(graph,
                           pos=pos,
                           edgelist=max_match,
                           edge_color='r',
                           width=4)
    nx.draw_networkx_edge_labels(graph, pos, edge_labels=labels)

    plt.figure()
    plt.title("Relative Graph")
    nx.draw(graph, pos=pos2, with_labels=True, font_color='w')
    nx.draw_networkx_edges(
        graph,
        pos=pos2,
        edgelist=max_match_w,
        edge_color='g',
        width=4,
    )
    nx.draw_networkx_edge_labels(graph, pos2, edge_labels=labels)
    plt.ioff()
    plt.show()
Esempio n. 36
0
def min_edge_dominating_set(G):
    r"""Return minimum cardinality edge dominating set.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    Returns
    -------
    min_edge_dominating_set : set
      Returns a set of dominating edges whose size is no more than 2 * OPT.

    Notes
    -----
    The algorithm computes an approximate solution to the edge dominating set
    problem. The result is no more than 2 * OPT in terms of size of the set.
    Runtime of the algorithm is `O(|E|)`.
    """
    if not G:
        raise ValueError("Expected non-empty NetworkX graph!")
    return nx.maximal_matching(G)
Esempio n. 37
0
def min_edge_dominating_set(G):
    """Return minimum cardinality edge dominating set.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    Returns
    -------
    min_edge_dominating_set : set
      Returns a set of dominating edges whose size is no more than 2 * OPT.

    Notes
    -----
    The algorithm computes an approximate solution to the edge dominating set
    problem. The result is no more than 2 * OPT in terms of size of the set.
    Runtime of the algorithm is O(|E|).
    """
    if not G:
        raise ValueError("Expected non-empty NetworkX graph!")
    return nx.maximal_matching(G)
Esempio n. 38
0
def init(n):
    G = nx.Graph()
    G.add_nodes_from(range(1, n + 1))

    # Le nombre d'arêtes max est de (n*(n-1))/2 et on cherche un remplissage de 0.25%
    nbAretesMax = (n * (n - 1)) / 2
    remplissageSouhaitee = 0.25 * nbAretesMax
    while (G.number_of_edges() < remplissageSouhaitee
           ):  #Remplissage est inférieur à 25% on ajoute des arêtes
        noeud1 = randint(1, n)
        noeud2 = noeud1
        while (
                noeud1 == noeud2
        ):  #Ici on ne veut pas qu'un graphe possède une arête pointant vers lui même.
            noeud2 = randint(1, n)
        G.add_edge(noeud1, noeud2)
    print("Le graphe possède les arêtes suivantes :")
    print(list(G.edges()))
    #print(list(G.nodes()))
    print("Affichage les couples de sommets permettant un maximum matching")
    print(nx.maximal_matching(G))  #Vérifier que on obtient bien :

    #Calcul de la solution optimale de VertexCover (recherche exhaustive)
    grapheParent = cp.deepcopy(
        G
    )  #Copie en profondeur de G (chaque modification de graphe2 ne modifiera pas G)

    #Ici on fait une boucle qui va vérifier que les différents graphes sont des VC. A la fin de la boucle, nous avons forcément trouvé min VC
    for i in range(1, n + 1):
        newpid = os.fork()
        if newpid == 0:  #Si c'est un enfant
            grapheEnfant = cp.deepcopy(grapheParent)
            #print(isVertexCover(grapheParent,grapheEnfant))
            print("Enfant: %d\n" % i)

        else:
            newpid = os.fork()
            pids = (os.getpid(), newpid)
def subtree_isomorphism(G, H):
    # Run the algorithm
    r = G.nodes()[0]

    # Enumerate all leaves in G by BFS
    leaves, children = find_leaves(G, r)
    print "Leaves:", leaves
    print "Children:", children

    # Initialize the S map
    S = {}
    for u in H.nodes():
        for v in G.nodes():
            S[(v,u)] = set()

    # Initialize S[] based on the leaves of G to start
    for gl in leaves:
        for u in H.nodes():
            hleaves, dummyChildren = find_leaves(H, u)
            for hl in hleaves:
                S[(gl, hl)] = H.neighbors(u)

    ### CORRECT TO HERE

    # Main loop
    internals = find_internals(G, r, leaves)

    for i,v in enumerate(internals):
        childs = children[v]
        t = len(childs)
        hdegrees = find_nodes_of_at_most_degree(H, t + 1)
        for j,u in enumerate(hdegrees):
            uneighbors = H.neighbors(u) # u1,...,us
            s = len(uneighbors)


            X = uneighbors
            Y = childs

            edgeSet = []
            for uu in X:
                for vv in Y:
                    if (vv,uu) in S:
                        if u in S[(vv, uu)]:
                            edgeSet.append((uu, vv))

            # Construct the bipartite graph between the two vertex sets
            bg = nx.Graph()
            bg.add_nodes_from(X, bipartite=0)
            bg.add_nodes_from(Y, bipartite=1)
            bg.add_edges_from(edgeSet)

            #pause(locals())

            # Try to find all the maximal matchings for all i = 0..s
            mi_vector = []
            m_star = 0
            X_star = []
            for si in range(-1, s):
                # Define X_0 = X and X_i = X \ {u_i}
                X_i = X # only if i = 0 (si == -1)
                u_i = u # fixed.
                if si >= 0:
                    u_i = X[si] # X = uneighbors
                    X_i = [uu for uu in X if uu != u_i]

                testGraph = nx.Graph()
                testGraph.add_nodes_from(X_i, bipartite=0)
                testGraph.add_nodes_from(Y, bipartite=1)

                edgeSet = []
                for uu in X_i:
                    neighbors = bg.neighbors(uu)
                    for n in neighbors:
                        edgeSet.append((uu, n))
                testGraph.add_edges_from(edgeSet)

                m_i = len(nx.maximal_matching(testGraph))
                mi_vector.append((m_i, u_i, X_i)) # record the X_i, this can be skipped

                #pause(locals())

                if m_i > m_star:
                    m_star = m_i
                    X_star = X_i

            if (v,u) not in S:
                S[(v,u)] = set()
            for (m_i, u_i, X_i) in mi_vector:
                if m_i == len(X_i): #m_star:
                    S[(v, u)].add(u_i)

            if u in S[(v, u)]:
                print v, u
                return "YES"

    return "NO"
def twoOptApprox(graph):
    max_matching = list(nx.maximal_matching(graph))
    res = [x[0] for x in max_matching]
    res.extend([x[1] for x in max_matching])
    return res
  if (g_person_node_count+g_wine_node_count) < MIN_MEM_NODE_COUNT:
    print "Merge Tree Overlaps"
    pt.merge_overlaps()
    wt.merge_overlaps()
    print "Buffering..."
    while (g_person_node_count+g_wine_node_count) < MAX_MEM_NODE_COUNT and more_file:
      line = f.readline() #read in line from input
      if line:
        if add_line_to_graph(line): 
          nodes_to_process = True
      else:
        more_file = False
    print "Buffering Done"

  print "FG Length:",len(fg)
  max_match = nx.maximal_matching(fg)
  print "Match Count:",len(max_match)
  if len(max_match) == 0:
    fg.clear()
    g_person_node_count = 0
    g_wine_node_count = 0
    nodes_to_process = False
  for node in max_match:
    if node[0][0] == "w": 
      wine = node[0]
      person = node[1]
    elif node[0][0] == "p": 
      person = node[0]
      wine = node[1]

    person_id = long(person.replace("p",""))
Esempio n. 42
0
 def test_valid_matching(self):
     edges = [(1, 2), (1, 5), (2, 3), (2, 5), (3, 4), (3, 6), (5, 6)]
     G = nx.Graph(edges)
     matching = nx.maximal_matching(G)
     assert_true(nx.is_maximal_matching(G, matching))
Esempio n. 43
0
def train_val_test_split_adjacency(A, p_val=0.10, p_test=0.05, seed=0, neg_mul=1,
                                   every_node=True, connected=False, undirected=False,
                                   use_edge_cover=True, set_ops=True, asserts=False):
    """
    Split the edges of the adjacency matrix into train, validation and test edges
    and randomly samples equal amount of validation and test non-edges.

    Parameters
    ----------
    A : scipy.sparse.spmatrix
        Sparse unweighted adjacency matrix
    p_val : float
        Percentage of validation edges. Default p_val=0.10
    p_test : float
        Percentage of test edges. Default p_test=0.05
    seed : int
        Seed for numpy.random. Default seed=0
    neg_mul : int
        What multiplicity of negative samples (non-edges) to have in the test/validation set
        w.r.t the number of edges, i.e. len(non-edges) = L * len(edges). Default neg_mul=1
    every_node : bool
        Make sure each node appears at least once in the train set. Default every_node=True
    connected : bool
        Make sure the training graph is still connected after the split
    undirected : bool
        Whether to make the split undirected, that is if (i, j) is in val/test set then (j, i) is there as well.
        Default undirected=False
    use_edge_cover: bool
        Whether to use (approximate) edge_cover to find the minimum set of edges that cover every node.
        Only active when every_node=True. Default use_edge_cover=True
    set_ops : bool
        Whether to use set operations to construction the test zeros. Default setwise_zeros=True
        Otherwise use a while loop.
    asserts : bool
        Unit test like checks. Default asserts=False

    Returns
    -------
    train_ones : array-like, shape [n_train, 2]
        Indices of the train edges
    val_ones : array-like, shape [n_val, 2]
        Indices of the validation edges
    val_zeros : array-like, shape [n_val, 2]
        Indices of the validation non-edges
    test_ones : array-like, shape [n_test, 2]
        Indices of the test edges
    test_zeros : array-like, shape [n_test, 2]
        Indices of the test non-edges

    """

    assert p_val + p_test > 0
    assert A.max() == 1  # no weights
    assert A.min() == 0  # no negative edges
    assert A.diagonal().sum() == 0  # no self-loops
    assert not np.any(A.sum(0).A1 + A.sum(1).A1 == 0)  # no dangling nodes

    is_undirected = (A != A.T).nnz == 0

    if undirected:
        assert is_undirected  # make sure is directed
        A = sp.tril(A).tocsr()  # consider only upper triangular
        A.eliminate_zeros()
    else:
        if is_undirected:
            warnings.warn('Graph appears to be undirected. Did you forgot to set undirected=True?')

    np.random.seed(seed)

    E = A.nnz
    N = A.shape[0]

    s_train = int(E * (1 - p_val - p_test))

    idx = np.arange(N)

    # hold some edges so each node appears at least once
    if every_node:
        if connected:
            assert connected_components(A)[0] == 1  # make sure original graph is connected
            A_hold = minimum_spanning_tree(A)
        else:
            A.eliminate_zeros()  # makes sure A.tolil().rows contains only indices of non-zero elements
            d = A.sum(1).A1

            if use_edge_cover:
                hold_edges = np.array(list(nx.maximal_matching(nx.DiGraph(A))))
                not_in_cover = np.array(list(set(range(N)).difference(hold_edges.flatten())))

                # makes sure the training percentage is not smaller than N/E when every_node is set to True
                min_size = hold_edges.shape[0] + len(not_in_cover)
                if min_size > s_train:
                    raise ValueError('Training percentage too low to guarantee every node. Min train size needed {:.2f}'
                                     .format(min_size / E))

                d_nic = d[not_in_cover]

                hold_edges_d1 = np.column_stack((not_in_cover[d_nic > 0],
                                                 np.row_stack(map(np.random.choice,
                                                                  A[not_in_cover[d_nic > 0]].tolil().rows))))

                if np.any(d_nic == 0):
                    hold_edges_d0 = np.column_stack((np.row_stack(map(np.random.choice, A[:, not_in_cover[d_nic == 0]].T.tolil().rows)),
                                                     not_in_cover[d_nic == 0]))
                    hold_edges = np.row_stack((hold_edges, hold_edges_d0, hold_edges_d1))
                else:
                    hold_edges = np.row_stack((hold_edges, hold_edges_d1))

            else:
                # makes sure the training percentage is not smaller than N/E when every_node is set to True
                if N > s_train:
                    raise ValueError('Training percentage too low to guarantee every node. Min train size needed {:.2f}'
                                     .format(N / E))

                hold_edges_d1 = np.column_stack(
                    (idx[d > 0], np.row_stack(map(np.random.choice, A[d > 0].tolil().rows))))

                if np.any(d == 0):
                    hold_edges_d0 = np.column_stack((np.row_stack(map(np.random.choice, A[:, d == 0].T.tolil().rows)),
                                                     idx[d == 0]))
                    hold_edges = np.row_stack((hold_edges_d0, hold_edges_d1))
                else:
                    hold_edges = hold_edges_d1

            if asserts:
                assert np.all(A[hold_edges[:, 0], hold_edges[:, 1]])
                assert len(np.unique(hold_edges.flatten())) == N

            A_hold = edges_to_sparse(hold_edges, N)

        A_hold[A_hold > 1] = 1
        A_hold.eliminate_zeros()
        A_sample = A - A_hold

        s_train = s_train - A_hold.nnz
    else:
        A_sample = A

    idx_ones = np.random.permutation(A_sample.nnz)
    ones = np.column_stack(A_sample.nonzero())
    train_ones = ones[idx_ones[:s_train]]
    test_ones = ones[idx_ones[s_train:]]

    # return back the held edges
    if every_node:
        train_ones = np.row_stack((train_ones, np.column_stack(A_hold.nonzero())))

    n_test = len(test_ones) * neg_mul
    if set_ops:
        # generate slightly more completely random non-edge indices than needed and discard any that hit an edge
        # much faster compared a while loop
        # in the future: estimate the multiplicity (currently fixed 1.3/2.3) based on A_obs.nnz
        if undirected:
            random_sample = np.random.randint(0, N, [int(2.3 * n_test), 2])
            random_sample = random_sample[random_sample[:, 0] > random_sample[:, 1]]
        else:
            random_sample = np.random.randint(0, N, [int(1.3 * n_test), 2])
            random_sample = random_sample[random_sample[:, 0] != random_sample[:, 1]]

        test_zeros = random_sample[A[random_sample[:, 0], random_sample[:, 1]].A1 == 0]
        test_zeros = np.row_stack(test_zeros)[:n_test]
        assert test_zeros.shape[0] == n_test
    else:
        test_zeros = []
        while len(test_zeros) < n_test:
            i, j = np.random.randint(0, N, 2)
            if A[i, j] == 0 and (not undirected or i > j) and (i, j) not in test_zeros:
                test_zeros.append((i, j))
        test_zeros = np.array(test_zeros)

    # split the test set into validation and test set
    s_val_ones = int(len(test_ones) * p_val / (p_val + p_test))
    s_val_zeros = int(len(test_zeros) * p_val / (p_val + p_test))

    val_ones = test_ones[:s_val_ones]
    test_ones = test_ones[s_val_ones:]

    val_zeros = test_zeros[:s_val_zeros]
    test_zeros = test_zeros[s_val_zeros:]

    if undirected:
        # put (j, i) edges for every (i, j) edge in the respective sets and form back original A
        symmetrize = lambda x: np.row_stack((x, np.column_stack((x[:, 1], x[:, 0]))))
        train_ones = symmetrize(train_ones)
        val_ones = symmetrize(val_ones)
        val_zeros = symmetrize(val_zeros)
        test_ones = symmetrize(test_ones)
        test_zeros = symmetrize(test_zeros)
        A = A.maximum(A.T)

    if asserts:
        set_of_train_ones = set(map(tuple, train_ones))
        assert train_ones.shape[0] + test_ones.shape[0] + val_ones.shape[0] == A.nnz
        assert (edges_to_sparse(np.row_stack((train_ones, test_ones, val_ones)), N) != A).nnz == 0
        assert set_of_train_ones.intersection(set(map(tuple, test_ones))) == set()
        assert set_of_train_ones.intersection(set(map(tuple, val_ones))) == set()
        assert set_of_train_ones.intersection(set(map(tuple, test_zeros))) == set()
        assert set_of_train_ones.intersection(set(map(tuple, val_zeros))) == set()
        assert len(set(map(tuple, test_zeros))) == len(test_ones) * neg_mul
        assert len(set(map(tuple, val_zeros))) == len(val_ones) * neg_mul
        assert not connected or connected_components(A_hold)[0] == 1
        assert not every_node or ((A_hold - A) > 0).sum() == 0


    return train_ones, val_ones, val_zeros, test_ones, test_zeros
def matching(net):
    return setSize(nx.maximal_matching(net),net.number_of_edges(),'maximal_matching')   
Esempio n. 45
0
import random
import matplotlib.pyplot as plt
import numpy as np
g=nx.random_graphs.binomial_graph(1000, 0.01)
p1=0.1#bad match
p2=0.5#back to market
paces=range(10,1010,10)
ans={i:[]for i in paces}
for k in range(50):
    print k
    for pace in paces:
        pos=pace
        cur=[i for i in g.nodes() if i<pos]
        bad=0
        while True:
            match=nx.maximal_matching(g.subgraph(cur))
            for i in match:
                for j in i:
                    if random.random()>p1:
                        cur.remove(j)
                        continue
                    if random.random()>p2:
                        bad+=1
                        cur.remove(j)
            cur+=range(pos,1000)
            if pos>=1000:
                break
            pos=pos+1000
        bad+=len([i for i in cur if i<1000])
        ans[pace]+=[bad]
plt.plot(paces,[np.mean(ans[i]) for i in paces])
Esempio n. 46
0
def main():
    """The main function."""

    for edge_list in generate_edges():
        print(nx.maximal_matching(nx.Graph(edge_list)))
Esempio n. 47
0
def checkPolar_all(atom_coor,atomLabels, vecX, vecY, z_digit=4, dist_tol_rate=0.01, max_compare = float("Inf"), inverse_struc = False):
    # Description of the input variables:
    # - atom_coor: of the atoms, numpy.array(Natoms,3)
    # - atomLabels: numpy.array with integers denoting atom types, 
    #   i.e [0,1,1,0,2,...,natoms]. The order of the atoms is the same 
    #   as in positions array.
    # - atomTypes: dictionary that allows to decode entries in the atomLabels
    #   in terms of real chemical species. 
    #   Example:
    #    atomTypes = {0: 'Ga', 1: 'As', 2: 'H'}
    #    which means that integer 0 corresponds to "Ga", integer 1 to "As" and 2 to "H"
    #   Usage:
    #    find what is the atom type of the 3rd atom in the structure:
    #    atomLabels = [0,1,1,0,2]
    #    atom = atomLabels[2]  # remeberin Python we count from 0, so 3rd atom is 2nd in the structure
    #    type = atomTypes[atom]
    #    In this case atom will be set to "1", and type to "As"
    #
    # - vec_x: lattice vector X, numpy.array[x1, x2, x3]
    # - vec_y: lattice vector Y, numpy.array[y1, y2, y3]

    # first 180 primes
    primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069];

    nAtoms = len(atomLabels);
    # represent the atom types by prime numbers
    ele_n = np.empty([nAtoms, 1]); 
    ii=0;
    atomLabels = np.array(atomLabels);
    for i in xrange(min(atomLabels), max(atomLabels)+1):
        ele_n[atomLabels == i]= primes[ii];
        ii += 1;
    ele_n = np.outer(ele_n,ele_n);
    ele_n[range(nAtoms), range(nAtoms)] = 0;

    # build the distance matrix (size nAtoms*nAtoms, entry i,j represent for the distance between i-th atom and j-th atom)
    atom_dist = np.empty([nAtoms, nAtoms], dtype=float);
    for i in xrange(0, nAtoms):
        for j in xrange(i,nAtoms):
            atom_dist[i,j] = compute_min_dist(atom_coor[i, 0:2] - atom_coor[j, 0:2], vecX, vecY);
            atom_dist[i,j] = atom_dist[i,j]+(atom_coor[i, 2] - atom_coor[j, 2])**2;
            atom_dist[j,i] = atom_dist[i,j]
    atom_dist[range(nAtoms), range(nAtoms)] = -1; # avoid zero-division in later steps

    # round the z-coordinate
    atom_coor[:, 2] = np.around(atom_coor[:, 2], decimals = z_digit);
    # atoms with same cut_z coord are considered on the same "surface"
    # inverse_struc=False: the resut is ordered from small to large
    if inverse_struc:
        surface_z= np.squeeze(np.unique(atom_coor[:, 2], return_inverse=True))[0]; 
    else:
        surface_z= np.squeeze(np.unique(atom_coor[:, 2], return_inverse=False)); 

    surface_n=len(surface_z); # number of surfaces
    surface_thickness = surface_n;
    init_z = surface_z[-1]; # the first surface to consider
    firstRound = False;
    forDelete = np.zeros([nAtoms], dtype=bool);
    is_Polar = np.zeros([surface_n], dtype=bool);
    z_coords = surface_z;
    minDiffRate = np.empty([surface_n])
    typeDiff = np.zeros([surface_n], dtype=bool);

    for current_surface in xrange(surface_thickness-1): 
        if max_compare> (surface_n/2): # take advange of integer division
            max_compare=(surface_n/2);

        for nSurface in xrange(0,max_compare):
        #each row represents for an atom
        # the indices of atoms on the upper surface & lower surface
            u_lidx = atom_coor[:, 2]==surface_z[nSurface];
            l_lidx =atom_coor[:, 2]==surface_z[-nSurface-1];
            # if the number of atoms are differnent
            if sum(u_lidx) != sum(l_lidx):
                is_Polar[current_surface]=True;
                break;
               
            nAtomPerLayer = sum(u_lidx);

            data_upper_dist= atom_dist[u_lidx,:];
            data_lower_dist= atom_dist[l_lidx,:];

            # # can speed up the code if we only want to get polar/non-polar 
            # if np.setdiff1d(data_upper_dist,data_lower_dist):
            #     polar = True;
            #     break;


            data_upper_type= ele_n[u_lidx,:];
            data_lower_type= ele_n[l_lidx,:];

            # # can speed up the code if we only want to get polar/non-polar 
            # if np.setdiff1d(data_upper_type, data_lower_type).size:
            #     polar = True;
            #     break;

            # for each atom, sort the distance from this atom to the others (small to large)
            sort1idx_u = np.argsort(data_upper_dist, axis = 1);
            sort1idx_l = np.argsort(data_lower_dist,axis = 1);

            for i in xrange(nAtomPerLayer):
                data_upper_type[i,:] = data_upper_type[i,sort1idx_u[i,:]];
                data_lower_type[i,:] = data_lower_type[i,sort1idx_l[i,:]];
                data_upper_dist[i,:] = data_upper_dist[i,sort1idx_u[i,:]];
                data_lower_dist[i,:] = data_lower_dist[i,sort1idx_l[i,:]];

            # for each atom, sort the type from this atom to the others (small to large)
            sort2idx_u = np.argsort(data_upper_type, axis = 1);
            sort2idx_l = np.argsort(data_lower_type,axis = 1);
            for i in xrange(nAtomPerLayer):
                data_upper_type[i,:] = data_upper_type[i,sort2idx_u[i,:]];
                data_lower_type[i,:] = data_lower_type[i,sort2idx_l[i,:]];
                data_upper_dist[i,:] = data_upper_dist[i,sort2idx_u[i,:]];
                data_lower_dist[i,:] = data_lower_dist[i,sort2idx_l[i,:]];

            dist_diff = np.zeros([nAtomPerLayer,nAtomPerLayer], dtype = float); # rate of difference on distance
            type_ok = np.zeros([nAtomPerLayer,nAtomPerLayer], dtype = bool); # true if the type items are matching between a upper-atom and a lower-atom
            for idx_upper in xrange(nAtomPerLayer):
                for idx_lower in xrange(nAtomPerLayer):
                     dist_diff[idx_upper,idx_lower] = max(abs(np.divide(data_upper_dist[idx_upper,:]-data_lower_dist[idx_lower,:], data_upper_dist[idx_upper,:]+data_lower_dist[idx_lower,:])));
                     type_ok[idx_upper,idx_lower]= all(data_upper_type[idx_upper,:]==data_lower_type[idx_lower,:]);

            match_matrix = (dist_diff<=dist_tol_rate) & type_ok;

            g = networkx.to_networkx_graph(match_matrix); # 
            # find the maximal matching of graph g
            if len(networkx.maximal_matching(g))< nAtomPerLayer: 
                is_Polar[current_surface]=True;

                g = networkx.to_networkx_graph(type_ok);
                if len(networkx.maximal_matching(g))< nAtomPerLayer: 
                    typeDiff[current_surface] = True;
                    minDiffRate[current_surface] = float("nan");
                else:
                    minDiffRate[current_surface] = np.min([np.min(dist_diff), minDiffRate[current_surface]]);

                break;
            else:
                minDiffRate[current_surface] = float("nan");


            # END of nSurface loop


        data_delete = (atom_coor[:, 2]==surface_z[-1]);
        atom_dist = atom_dist[~data_delete,:];
        atom_dist = atom_dist[:,~data_delete];
        ele_n = ele_n[~data_delete,:];
        ele_n = ele_n[:,~data_delete];
        atom_coor = atom_coor[~data_delete,:];
        surface_n=surface_n-1;
        surface_z = np.delete(surface_z, -1);

    minDiffRate[-1] = float("nan")
    is_Polar = is_Polar[::-1];
    minDiffRate = minDiffRate[::-1]
    typeDiff = typeDiff[::-1]

    return is_Polar, z_coords, minDiffRate, typeDiff
def get_driver_nodes(DG):
    '''Return the driver nodes number and driver nodes from a DiGraph DG

    Basic Idea:
    Given a graph DG, create a new undirected bipartite graph, BG
    suppose DG has n nodes, the the BG has 2*n nodes, the first n nodes [0, n)
    form the left parts of BG, the [n, 2*n) nodes form the right part of BG,
    for each edge form DG, say, 1-->3, add edges in BG 1---(3+n)
    then call the maximum matching algorithm find the matched nodes
    All the unmatched nodes are the driver nodes we are looking for

    Parameters
    ----------
    DG: networkx.DiGraph, directed graph, node number start from 0

    Returns
    -------
    driver node num:    the number of driver nodes
    driver nodes:       the driver nodes we are looking for

    Notes:
    -------
    The index of nodes in DG must start from 0, 1, 2, 3...

    References:
    -----------
    [1] Yang-Yu Liu, Jean-Jacques Slotine, Albert L. Barabasi. Controllability
        of complex networks. Nature, 2011.
    '''
    assert(nx.is_directed(DG))

    nodeNum = DG.number_of_nodes()
    edgeNum = DG.number_of_edges()

    # convert to a bipartite graph
    G = nx.Graph()
    left_nodes  = ['a'+str(node) for node in G.nodes()]
    right_nodes = ['b'+str(node) for node in G.nodes()]       
    G.add_nodes_from(left_nodes)
    G.add_nodes_from(right_nodes)
    for edge in DG.edges():
        da = 'a' + str(edge[0])
        db = 'b' + str(edge[1])
        G.add_edge(da, db)

    assert(nx.is_bipartite(G))
    # maximum matching algorithm
    matched_edges = nx.maximal_matching(G)

    # find all the matched and unmatched nodes
    matched_nodes = [int(edge[0][1:]) if edge[0][0] == 'b' else int(edge[1][1:]) for edge in matched_edges]
    unmatched_nodes = [node for node in DG.nodes() if node not in matched_nodes]
    unmatched_nodes_num = len(unmatched_nodes)

    # perfect matching
    isPerfect = False
    if unmatched_nodes_num == 0:
        print '>>> Perfect Match Found ! <<<'
        isPerfect = True
        unmatched_nodes_num = 1
        unmatched_nodes = [0]
        
    return (isPerfect, unmatched_nodes_num, unmatched_nodes)
Esempio n. 49
0
def checkPolar(atom_coor,atomLabels, vecX, vecY, z_digit=4, dist_tol_rate=0.01, max_compare = float("Inf"), inverse_struc = False):
    # Description of the input variables:
    # - atom_coor: of the atoms, numpy.array(Natoms,3)
    # - atomLabels: numpy.array with integers denoting atom types, 
    #   i.e [0,1,1,0,2,...,natoms]. The order of the atoms is the same 
    #   as in positions array.
    # - atomTypes: dictionary that allows to decode entries in the atomLabels
    #   in terms of real chemical species. 
    #   Example:
    #    atomTypes = {0: 'Ga', 1: 'As', 2: 'H'}
    #    which means that integer 0 corresponds to "Ga", integer 1 to "As" and 2 to "H"
    #   Usage:
    #    find what is the atom type of the 3rd atom in the structure:
    #    atomLabels = [0,1,1,0,2]
    #    atom = atomLabels[2]  # remeberin Python we count from 0, so 3rd atom is 2nd in the structure
    #    type = atomTypes[atom]
    #    In this case atom will be set to "1", and type to "As"
    #
    # - vec_x: lattice vector X, numpy.array[x1, x2, x3]
    # - vec_y: lattice vector Y, numpy.array[y1, y2, y3]

    #  Return values are 
    #  polar = {True,False} - is structure polar or not
    #  periodicity = 0  - double number saying what is the periodicity of the structure in angstrom
    #  minDiffRate - double number saying what is the minimal distance rate found during the checking procedure (especially useful for understanding the polar structures)
    
    periodicity = float("nan")


    # first 180 primes
    primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069];

    nAtoms = len(atomLabels);
    # represent the atom types by prime numbers
    ele_n = np.empty([nAtoms, 1]); 
    ii=0;
    atomLabels = np.array(atomLabels);
    for i in xrange(min(atomLabels), max(atomLabels)+1):
        ele_n[atomLabels == i]= primes[ii];
        ii += 1;
    ele_n = np.outer(ele_n,ele_n);
    ele_n[range(nAtoms), range(nAtoms)] = 0;

    # build the distance matrix (size nAtoms*nAtoms, entry i,j represent for the distance between i-th atom and j-th atom)
    atom_dist = np.empty([nAtoms, nAtoms], dtype=float);
    for i in xrange(0, nAtoms):
        for j in xrange(i,nAtoms):
            atom_dist[i,j] = compute_min_dist(atom_coor[i, 0:2] - atom_coor[j, 0:2], vecX, vecY);
            atom_dist[i,j] = atom_dist[i,j]+(atom_coor[i, 2] - atom_coor[j, 2])**2;
            atom_dist[j,i] = atom_dist[i,j]
    atom_dist[range(nAtoms), range(nAtoms)] = -1; # avoid zero-division in later steps

    # round the z-coordinate
    atom_coor[:, 2] = np.around(atom_coor[:, 2], decimals = z_digit);
    # atoms with same cut_z coord are considered on the same "surface"
    # inverse_struc=False: the resut is ordered from small to large
    if inverse_struc:
        surface_z= np.squeeze(np.unique(atom_coor[:, 2], return_inverse=True))[0]; 
    else:
        surface_z= np.squeeze(np.unique(atom_coor[:, 2], return_inverse=False)); 

    surface_n=len(surface_z); # number of surfaces
    init_z = surface_z[-1]; # the first surface to consider
    firstRound = False;
    forDelete = np.zeros([nAtoms], dtype=bool);

    while(surface_n>=2 and not(abs(surface_z[0]-surface_z[-1])<abs(init_z-surface_z[-1]) and not(firstRound))): # the first round non-polar must be found within the upper half of the structure
        if max_compare> (surface_n/2): # take advange of integer division
            max_compare=(surface_n/2);
        polar=False;
        doCompare = True;
        minDiffRate = 1
        typeDiff = False

        if firstRound:
            if abs(init_z-surface_z[-1]) < perodicity_lower_bound:
                doCompare = False;

        if doCompare:
            for nSurface in xrange(0,max_compare):
            #each row represents for an atom
            # the indices of atoms on the upper surface & lower surface
                u_lidx = atom_coor[:, 2]==surface_z[nSurface];
                u_lidx = u_lidx [~forDelete];
                l_lidx =atom_coor[:, 2]==surface_z[-nSurface-1];
                l_lidx = l_lidx[~forDelete];
                # if the number of atoms are different
                if sum(u_lidx) != sum(l_lidx):
                    polar=True;
                    break;
                   
                nAtomPerLayer = sum(u_lidx);

                data_upper_dist= atom_dist[u_lidx,:];
                data_lower_dist= atom_dist[l_lidx,:];

                # # can speed up the code if we only want to get polar/non-polar 
                # if np.setdiff1d(data_upper_dist,data_lower_dist):
                #     polar = True;
                #     break;


                data_upper_type= ele_n[u_lidx,:];
                data_lower_type= ele_n[l_lidx,:];

                # # can speed up the code if we only want to get polar/non-polar 
                # if np.setdiff1d(data_upper_type, data_lower_type).size:
                #     polar = True;
                #     break;

                # for each atom, sort the distance from this atom to the others (small to large)
                sort1idx_u = np.argsort(data_upper_dist, axis = 1);
                sort1idx_l = np.argsort(data_lower_dist,axis = 1);

                for i in xrange(nAtomPerLayer):
                    data_upper_type[i,:] = data_upper_type[i,sort1idx_u[i,:]];
                    data_lower_type[i,:] = data_lower_type[i,sort1idx_l[i,:]];
                    data_upper_dist[i,:] = data_upper_dist[i,sort1idx_u[i,:]];
                    data_lower_dist[i,:] = data_lower_dist[i,sort1idx_l[i,:]];

                # for each atom, sort the type from this atom to the others (small to large)
                sort2idx_u = np.argsort(data_upper_type, axis = 1);
                sort2idx_l = np.argsort(data_lower_type,axis = 1);
                for i in xrange(nAtomPerLayer):
                    data_upper_type[i,:] = data_upper_type[i,sort2idx_u[i,:]];
                    data_lower_type[i,:] = data_lower_type[i,sort2idx_l[i,:]];
                    data_upper_dist[i,:] = data_upper_dist[i,sort2idx_u[i,:]];
                    data_lower_dist[i,:] = data_lower_dist[i,sort2idx_l[i,:]];

                dist_diff = np.zeros([nAtomPerLayer*2,nAtomPerLayer*2], dtype = float); # rate of difference on distance
                type_ok = np.zeros([nAtomPerLayer*2,nAtomPerLayer*2], dtype = bool); # true if the type items are matching between a upper-atom and a lower-atom
                for idx_upper in xrange(nAtomPerLayer):
                    for idx_lower in xrange(nAtomPerLayer):
                         dist_diff[idx_upper,nAtomPerLayer+idx_lower] = max(abs(np.divide(data_upper_dist[idx_upper,:]-data_lower_dist[idx_lower,:], data_upper_dist[idx_upper,:]+data_lower_dist[idx_lower,:])));
                         type_ok[idx_upper,nAtomPerLayer+idx_lower]= all(data_upper_type[idx_upper,:]==data_lower_type[idx_lower,:]);

                dist_diff = dist_diff + np.transpose(dist_diff);
                type_ok = type_ok + np.transpose(type_ok);
                match_matrix = (dist_diff<=dist_tol_rate) & type_ok;

                g = networkx.to_networkx_graph(match_matrix); 
                # find the maximal matching of graph g
                if len(networkx.maximal_matching(g))< nAtomPerLayer: 
                    polar=True;

                    g = networkx.to_networkx_graph(type_ok);
                    if len(networkx.maximal_matching(g))< nAtomPerLayer: 
                        typeDiff = True;
                        minDiffRate = float("nan");
                    else:
                        minDiffRate = np.min([np.min(dist_diff), minDiffRate]);

                    break;
                
                # END of nSurface loop

            if not(polar) and not(firstRound): # first round NonPolar
                firstRound = True
                layer_thickness = 0
                minNP_z = np.array([surface_z[-1]])
                perodicity_lower_bound = abs(init_z - minNP_z); # the periodicity should be larger than this
            else:
                if not(polar) and firstRound and (abs(minNP_z[0] - surface_z[-1])>perodicity_lower_bound): # the second round non-polar
                    minNP_z = np.append(minNP_z, surface_z[-1]);
                    layer_thickness = layer_thickness + 1;
                    z_thickness = minNP_z[0]-minNP_z[-1];
                    minDiffRate = float("nan")
                    #  vz(3) = z_thickness;
                    #  isNP = ismember(atom_coor(:,3), minNP_z);
                    #  minNPStruc= atom_coor(isNP,:);
                    #  minNPStruc(:,3)= minNPStruc(:,3) - minNP_z(end);
                    #  atom_type = atom_type(isNP);
                    #  atom_cell=[num2cell(minNPStruc) atom_type];
                    
                    #  # create a new txt file that contains the maximal non-polar structure
                    # isWin = ~isempty(strfind(computer, 'PCWIN'));
                    # [pathstr,name,ext] = fileparts(filepath);
                    # mkdir(pathstr,'minNonPolar5');
                    # if isWin
                    #   pathstr=strcat(pathstr, '\minNonPolar5');
                    # else
                    #    pathstr=strcat(pathstr, '/minNonPolar5');
                    # end
                    # oldpath=cd(pathstr);
                    # fileID=fopen([name '-minNonPolar5' ext], 'w+');
                    # formatSpec1='lattice_vector \t %f \t %f \t %f \n';
                    # fprintf(fileID,formatSpec1,vx);
                    # fprintf(fileID,formatSpec1,vy);
                    # fprintf(fileID,formatSpec1,vz);
                    # formatSpec2='atom \t %f \t %f \t %f \t %s \n';
                    
                    # nrows= size(atom_cell,1);
                    # for row = 1:nrows:
                    #     fprintf(fileID,formatSpec2,atom_cell{row, :});
                    # fclose(fileID);
                    # #movefile([name '-nonpolar' ext], pathstr);
                    # cd(oldpath);
                    
                    # top_z=minNP_z(1);
                    return polar, z_thickness, minDiffRate, typeDiff
        
            if polar and firstRound:
                layer_thickness = layer_thickness + 1;
                minNP_z = np.append(minNP_z,surface_z[-1]);
            #pdb.set_trace();

        data_delete = (atom_coor[:, 2]==surface_z[-1]);
        data_delete = data_delete[~forDelete];
        forDelete= np.squeeze(forDelete | (atom_coor[:, 2]==surface_z[-1]));
        atom_dist = atom_dist[~data_delete,:];
        atom_dist = atom_dist[:,~data_delete];
        ele_n = ele_n[~data_delete,:];
        ele_n = ele_n[:,~data_delete];
        #pdb.set_trace();
        surface_n=surface_n-1;
        surface_z = np.delete(surface_z, -1);
        #pdb.set_trace();

    
    z_thickness=float("nan");
    layer_thickness = float("nan");
    #top_z = float("nan");
    #perodicity_lower_bound = float("nan");

    return polar, z_thickness, minDiffRate, typeDiff
Esempio n. 50
0
def BnB(filename, cutoff, randseed):
    G = nx.Graph()
    f = open('%s.graph'%filename,'r')
    content = f.readlines()
    num_vertices = int(content[0].split(" ")[0])
    num_edges = int(content[0].split(" ")[1])

    for i in range (1, num_vertices+1):
        G.add_node(i)
        try:
            edges = [int(item) for item in content[i].strip().split(" ")]
            for e in edges:
                G.add_edge(i,e)
        except ValueError:
                pass  


    G_Remaining = dc(G)
    #best_initial = len(G.nodes())
    best_initial = len(min_weighted_vertex_cover(G, None))
    degree_sorted_nodes = sorted(G.degree(), key=G.degree().get)
    V_remaining = []
    #V_remaining = set()
    for item in degree_sorted_nodes:
        #V_remaining.add(item)
        V_remaining.append(item)

    q = Queue.LifoQueue()
    I = []
    q.put((I, V_remaining, G_Remaining))
    VC = min_weighted_vertex_cover(G, None)
    start = time.time()
    elapsed  = 0
    while(not q.empty() and elapsed < cutoff):

        Inc, V_rem, G_rem = q.get()

        if not G_rem.edges():
            if len(Inc) < best_initial:
                best_initial = len(Inc)
                VC = Inc
        else:
            if V_rem:
                v = V_rem.pop()  
                if (len(Inc) + len(nx.maximal_matching(G_rem))) <= best_initial:
                    V_I = Inc
                    V_I = V_I + G_rem.neighbors(v)
                    V_R = V_rem
                    V_R = [item for item in V_rem if item not in G_rem.neighbors(v)]
                    G_pass = dc(G_rem)
                    G_pass.remove_nodes_from(G_rem.neighbors(v)) 
                    q.put((dc(V_I), dc(V_R), dc(G_pass)))
                
                G_rem.remove_node(v)
                Inc.append(v)
                if(len(Inc) + len(nx.maximal_matching(G_rem))) <= best_initial:
                    q.put((dc(Inc), dc(V_rem), dc(G_rem)))
        elapsed = (time.time() - start)
    
    output_sol = open('%s_BnB_%d_%d.sol'%(filename, cutoff, randseed), 'w')
    output_sol.write(str(len(VC)) + "\n" + str(VC).strip('[]'))
    output_trace = open("%s_BnB_%d_%d.trace" %(filename, cutoff, randseed), 'a')
    output_trace.write(str(elapsed)+" "+str(len(VC)))

    print VC
    print len(VC)
    print elapsed
Esempio n. 51
0
 def test_single_edge_matching(self):
     # In the star graph, any maximal matching has just one edge.
     G = nx.star_graph(5)
     matching = nx.maximal_matching(G)
     assert_equal(1, len(matching))
     assert_true(nx.is_maximal_matching(G, matching))