Пример #1
0
def bipartite(graph: Graph, start: Graph.Vertex, x: List, y: List,
              discover: Dict):
    """

    :param graph: grafo non diretto
    :param start: nodo di partenza
    :param x: partizione sinistra dei nodi
    :param y: partizione destra dei nodi
    :param discover: nodi visitati
    :return: true se è bipartito, false se non lo è
    """
    level = [start]
    i = 0
    while len(level) > 0:
        next_level = []
        i = (i + 1) % 2
        for vertex in level:
            for edges in graph.incident_edges(vertex):
                opposite_vertex = edges.opposite(vertex)
                if opposite_vertex not in discover:
                    discover[opposite_vertex] = i
                    if i % 2 == 0:
                        x.append(opposite_vertex)
                    else:
                        y.append(opposite_vertex)
                    next_level.append(opposite_vertex)
                elif discover[opposite_vertex] == (i + 1) % 2:
                    # L'ho inserito nell'altro insieme e ora devo inserirlo in i ==> Errore
                    return False
        level = next_level
    return True
Пример #2
0
def bipartite_connected(
    g: Graph, s: Graph.Vertex, discovered: Set[Graph.Vertex]
) -> Optional[Tuple[List[Graph.Vertex], List[Graph.Vertex]]]:
    """
    :param g: grafo non orientato
    :param s: vertice di partenza
    :param discovered: set di nodi già visitati
    :return: restituisce le due partizioni altrimenti None
    """
    colour = {s: 0}  # assegno al primo vertice colore 0
    q = [s]  # creo una coda con i vertici da considerare
    x = [s]  # creo la sotto-partizione 1 con assegnato il primo vertice
    y = []  # creo la sotto- partizione 2

    while q:  # finché la coda non è vuota
        current = q.pop()  # prendo il vertice da elaborare
        next_colour = 1 - colour[
            current]  # i vertici opposti avranno colore opposto al vertice corrente
        for dest in g.incident_edges(
                current):  # considero tutti gli archi uscenti
            v = dest.opposite(current)  # e mi prendo il vertice opposto
            if v not in discovered:  # se è la prima volta che vedo quel vertice
                discovered.add(v)  # lo segno come visitato
                colour[v] = next_colour  # gli assegno il nuovo colore
                if next_colour == 0:  # se 0
                    x.append(v)  # lo assegno alla prima sotto-partizione
                else:  # altrimenti
                    y.append(v)  # lo assegno alla seconda sotto-partizione
                q.append(
                    v
                )  # il vertice visitato dovrà essere considerato al prossimo ciclo
            elif colour[
                    v] != next_colour:  # altrimenti se ho già visto il vertice e il suo colore non è opposto al vertice corrente
                return None  # la componente connessa al vertice sorgente non è bipartibile
    return x, y  # se arrivo qui vuol dire che è bipartibile e restituisco le partizioni
Пример #3
0
def children(graph: Graph, root: Graph.Vertex, parent: Graph.Vertex):
    """ 
    Helper function.
    Return an iterator on the children of root,
    a children is defined as every neighbour except the vertex passed as parent
    """
    for edge in graph.incident_edges(root):
        opposite_vertex = edge.opposite(root)
        if opposite_vertex != parent:
            yield opposite_vertex
Пример #4
0
def bacefook_greedy_algorithm(graph: Graph):
    """
        greedy algorithm to compute the minimum number of nodes
        with software

        map structure:

        -Key store all vertices of the graph
        -Value is a dict

            dict structure:

            -token store locator from priority queue
            -so_sw_count store the number of adj nodes
            -has_sw bool if the node has the software

        Priority queue store all the nodes of the graph ordered by number of adj nodes
    """
    priority_queue = AdaptableHeapPriorityQueue()
    map = {}
    for v in graph.vertices():
        token = priority_queue.add(-graph.degree(v), v)
        map[v] = {
            'token': token,
            'no_sw_count': graph.degree(v),
            'has_sw': False
        }

    for i in range(0, graph.vertex_count()):
        k, v = priority_queue.remove_min()
        if graph.degree(v) == 0:
            continue
        if k == 0:
            break
        map[v]['has_sw'] = True
        for e in graph.incident_edges(v):
            adj_v = e.opposite(v)
            if not map[adj_v]['has_sw']:
                map[adj_v]['no_sw_count'] -= 1
                priority_queue.update(map[adj_v]['token'],
                                      -map[adj_v]['no_sw_count'], adj_v)

    return {v._element: map[v]['has_sw'] for v in map}