Пример #1
0
    def setUp(self):
        self.graph = Graph()
        self.emptyGraph = Graph()
        self.values = [3, 1, 4, 5, 9, 2, 6, 8, 7, 0]
        self.pairs = [(3, 4), (2, 9), (2, 4)]

        for n in self.values:
            self.graph.add_node(n)

        for n1, n2 in self.pairs:
            self.graph.add_edge(n1, n2)

        self.values.sort()
 def test_weighted_vertices(self):
     g = Graph.from_file_weighted_vertices('graph_weighted_vertices')
     self.assertListEqual(dijkstra(g, 0, 7), [0, 1, 7])
     self.assertListEqual(dijkstra(g, 0, 6), [0, 1, 7, 6])
     self.assertListEqual(dijkstra(g, 0, 2), [0, 3, 2])
     self.assertListEqual(dijkstra(g, 4, 5), [4, 1, 0, 3, 5])
     self.assertListEqual(dijkstra(g, 4, 2), [4, 7, 6, 2])
     self.assertListEqual(dijkstra(g, 4, 7), [4, 7])
def test_bfs():
    a = Graph(["0", "1", "2", "3", "5", "6"], [("0", "1"), ("1", "2"),
                                               ("1", "6"), ("2", "5"),
                                               ("2", "3")])

    assert bfs(a, "0", "7", set()) is False
    assert bfs(a, "0", "6", set()) is True
    assert bfs(a, "0", "3", set()) is True
    assert bfs(a, "0", "2", set()) is True
Пример #4
0
 def __init__(self, id_, name, electrical_system, province, commune,
              cross_sectional_area, receptor):
     self.id_structure = id_
     self.name = name
     self.electrical_system = electrical_system
     self.province = province
     self.commune = commune
     self.cross_sectional_area = cross_sectional_area
     self.connected_to = Graph(id_, self)
     self.receptor = receptor
     self.max_of_parents = inf
     self.power_consumed = 0.0  # potencia que se necesita para funcionar
     self.parents_data = List()
     self.received_power = 0.0
     self._demanded_power = 0.0  # Guarda el valor de la demanda,
     # así este solo se calcula una vez
     self.received = False
     self.extra_energy = 0
Пример #5
0
def maybe_remove_duplicate_edges(graph: Graph):
    if graph.is_oriented:
        return graph

    new_edges = []
    for edge in graph.edges:
        if not _has_adjacent_edge(edge, new_edges):
            new_edges.append(edge)

    graph.edges = new_edges
    return graph
Пример #6
0
def dfs(graph: Graph, start_node: str, target_node: str, visited_nodes: set):
    stack = Stack()
    stack.push(start_node)

    while not stack.is_empty():
        current = stack.pop()
        if current == target_node:
            return True

        adj = graph.get_edges_node(current)
        for node in adj:
            if node not in visited_nodes:
                stack.push(node)
    return False
Пример #7
0
 def __init__(self, config, passenger_generator=PoissonPassengerGenerator):
     """
     Read configuration and do sth with it
     :param config
     :type config: Config
     """
     Bus.BUS_COUNTER = 0
     self.finished = False
     self.steps = -1
     self.__buses = []
     self.__lines = []
     self.__stops = {}
     self.__create_stops(config.stops)
     self.__graph = Graph.from_config(config.graph_dict)
     self.__create_lines(config.lines_dict)
     self.__passengers_generator = passenger_generator(
         config.traffic_data_dict)
def bfs(graph: Graph, start_node: str, target_node: str, visited_nodes: set):
    queue = Queue()
    queue.enqueue(start_node)

    while not queue.is_empty():
        current = queue.deque()

        if current == target_node:
            return True

        adj = graph.get_edges_node(current)
        for node in adj:
            if node not in visited_nodes:

                queue.enqueue(node)
        visited_nodes.add(current)

    return False
def get_mst_kruskal(graph):
    # create a new graph structure to hold the MST
    mst = Graph()
    # create and a disjoint set
    # and populate it with all the vertices in the graph
    disjoint_set = DisjointSet()
    for i in range(len(graph)):
        disjoint_set.add(i)

    # create a list of edges and sort it in descending order
    edges = [(u, v, w) for u, adjacencies in graph.adjacencies.items()
             for v, w in adjacencies.items()]

    # iterate over the edge list
    # we first sort the edge list by ascending weight
    for edge in sorted(edges, key=lambda edge: edge[2], reverse=True):
        # isolate the components of this edge
        u, v, w = edge

        # for each vertex in the edge,
        # find the parent in each set
        u_parent = disjoint_set.find(u)
        v_parent = disjoint_set.find(v)

        # if two vertices share the same parent,
        # they have already been added to the MST
        # since we don't want to create cycles, we skip adding edges that join
        # vertices that have already been joined to the MST
        if u_parent.id != v_parent.id:
            # if the vertices haven't been joined to the MST...
            # ...we add that edge to the MST
            mst.addEdge(u, v, w)
            # and add it to the disjoint set to help track which vertices
            # have been added to the MST
            disjoint_set.union(u, v)

    return mst
Пример #10
0
 def test_kruskal(self):
     mst_total_weight = 23
     g = Graph.from_file('graph_MST')
     result = kruskal(g)
     self.assertEqual(result, mst_total_weight)
Пример #11
0
 def test_dijkstra(self):
     g = Graph.from_file('graph_shortest_path')
     result = dijkstra(g, 0, 7)
     self.assertListEqual(result, [0, 1, 7])
     result = dijkstra(g, 0, 4)
     self.assertListEqual(result, [0, 1, 7, 4])
Пример #12
0
 def test_bfs(self):
     g = Graph.from_file('graph_bfs')
     result = bfs(g, 0)
     self.assertDictEqual(result, {1: 0, 2: 1, 4: 0, 3: 4, 5: 0})
Пример #13
0
from data_structures import Graph, Stack


def dfs(graph: Graph, start_node: str, target_node: str, visited_nodes: set):
    stack = Stack()
    stack.push(start_node)

    while not stack.is_empty():
        current = stack.pop()
        if current == target_node:
            return True

        adj = graph.get_edges_node(current)
        for node in adj:
            if node not in visited_nodes:
                stack.push(node)
    return False


a = Graph(["0", "1", "2", "3", "5", "6"], [
    ("0", "1"), ("1", "3"), ("2", "3"), ("2", "5"), ("1", "6")])


print(dfs(a, "0", "3", visited_nodes=set()))

Пример #14
0
    graph -- Graph -- graph structure of sentences
    Postondition:
    returns Nothing
    creates html file in same directory 
    """
    f = open(file_name + ".html", "w+")
    f.write("<!DOCTYPE html>")
    f.write("<html><body><ul>")
    f.write(graph.to_html_structure(graph.root))
    f.write("</ul></body></html>")
    f.close()


# TEST
if __name__ == "__main__":
    graph = Graph()
    graph.add_node("Root**")
    graph.add_node("Suptopic1*")
    graph.add_node("Suptopic2*")
    graph.add_node("sentence1")
    graph.add_node("sentence2")
    graph.add_node("sentence3")
    graph.add_node("sentence4")
    graph.add_node("sentence5")
    graph.add_node("sentence6")
    graph.add_node("sentence7")

    graph.set_root("Root**")
    graph.add_child_edges("Root**", "Suptopic1*")
    graph.add_child_edges("Root**", "Suptopic2*")
    graph.add_child_edges("Suptopic1*", "sentence1")
Пример #15
0
 def test_prims(self):
     mst_total_weight = 23
     g = Graph.from_file('graph_MST')
     result = prim(g, 0)
     self.assertEqual(result, mst_total_weight)
Пример #16
0
class TestGraph(unittest.TestCase):

    def setUp(self):
        self.graph = Graph()
        self.emptyGraph = Graph()
        self.values = [3, 1, 4, 5, 9, 2, 6, 8, 7, 0]
        self.pairs = [(3, 4), (2, 9), (2, 4)]

        for n in self.values:
            self.graph.add_node(n)

        for n1, n2 in self.pairs:
            self.graph.add_edge(n1, n2)

        self.values.sort()

    def test_add_node(self):
        '''Test adding nodes to a graph.'''
        # implicitly test Graph.nodes() as well
        self.assertEqual(self.graph.nodes(), self.values)
        self.assertEqual(self.emptyGraph.nodes(), [])

        # test adding a duplicate node
        self.graph.add_node(0)
        self.assertEqual(self.graph.nodes(), self.values)

    def test_add_edge(self):
        '''Test adding edges to a graph (w/o using has_edge).'''
        test = set([])  # create a set listing edges as tuples

        for n1, edges in self.graph.Nodes.iteritems():
            for n2 in edges:
                pair = (n1, n2)
                test.add((min(pair), max(pair)))

        # ensure that setUp appropriately added edges
        self.assertEqual(test, set(self.pairs))

        # test adding an existent edge
        self.graph.add_edge(3, 4)
        self.assertTrue(3 in self.graph.Nodes[4])
        self.assertTrue(4 in self.graph.Nodes[3])

        # test adding an edge to a non-existent node
        self.graph.add_edge(3, 10)
        self.assertTrue(3 in self.graph.Nodes[10])
        self.assertTrue(10 in self.graph.Nodes[3])
        self.assertEqual(self.graph.nodes(), range(11))

        # test adding an edge to multiple non-existent nodes
        self.emptyGraph.add_edge(2, 1)
        # self.assertEqual(self.emptyGraph.edges(), [set((2, 1))])
        self.assertTrue(2 in self.emptyGraph.Nodes[1])
        self.assertTrue(1 in self.emptyGraph.Nodes[2])
        self.assertEqual(self.emptyGraph.nodes(), [1, 2])

    def test_del_node(self):
        '''Test deleting nodes from a graph.'''
        self.graph.del_node(1)
        self.graph.del_node(4)
        self.assertEqual(self.graph.nodes(), [0, 2, 3, 5, 6, 7, 8, 9])
        self.assertFalse(4 in self.graph.Nodes[2])
        self.assertFalse(4 in self.graph.Nodes[3])

        # test deleting fron an empty graph
        with self.assertRaises(ValueError):
            self.emptyGraph.del_node(0)

    def test_del_edge(self):
        '''Test deleting edges from a graph.'''
        # test deleting an existent edge
        self.graph.del_edge(3, 4)
        self.assertFalse(3 in self.graph.Nodes[4])
        self.assertFalse(4 in self.graph.Nodes[3])

        # ensure that the nodes remained intact
        self.assertEqual(self.graph.nodes(), self.values)

        # test deleting a non-existent edge between existent nodes
        with self.assertRaises(ValueError):
            self.graph.del_edge(1, 2)

        # test deleting an edge between non-existent nodes
        with self.assertRaises(ValueError):
            self.emptyGraph.del_edge(1, 2)

    def test_has_node(self):
        '''Test checking whether a graph contains certain nodes.'''
        for n in self.values:
            self.assertTrue(self.graph.has_node(n))

        self.assertFalse(self.graph.has_node(99))
        self.assertFalse(self.emptyGraph.has_node(99))

    def test_neighbors(self):
        '''Test listing the neighbors of nodes in a graph.'''
        self.assertEqual(self.graph.neighbors(0), [])
        self.assertEqual(self.graph.neighbors(3), [4])
        self.assertEqual(self.graph.neighbors(4), [2, 3])

        # test listing neighbors for non-existent nodes
        with self.assertRaises(ValueError):
            self.emptyGraph.neighbors(99)

    def test_is_adjacent(self):
        '''Test checking whether two nodes are adjacent.'''
        self.assertFalse(self.graph.is_adjacent(0, 9))
        self.assertTrue(self.graph.is_adjacent(4, 3))

        # test checking adjacency with non-existent nodes
        with self.assertRaises(ValueError):
            self.emptyGraph.is_adjacent(0, 99)
Пример #17
0
    def kmeans_merge_clustering(self,
                                sentences,
                                vectors,
                                graph=None,
                                num_clusters=None):
        """does recursive kmeans merge clustering
        
        Preconditions:
        sentences -- list -- list of sentences
        vectors -- 2d numpy array -- vectors
        graph -- Graph() -- for recursion
        num_clusters -- int -- number of clusters
        Postconditions:
        returns graph (Graph()) structure of sentence nodes
        """

        if num_clusters == None:
            num_clusters = self.pick_number_clusters(vectors)

        if graph == None:
            graph = Graph()
            for s in sentences:
                graph.add_node(s)

        table = Table(sentences, vectors)

        parent_sentences = []
        parent_vectors = []

        labels, centroids = self.train(vectors, num_clusters)

        label_dict = {}
        for i in range(num_clusters):
            label_dict[i] = []

        for i in range(vectors.shape[0]):
            label_dict[labels[i]].append(vectors[i])

        #determine the new_sentences
        for i in range(num_clusters):
            min_vector = self.find_closest_vector(centroids[i], label_dict[i])

            #found the min_vector, so go add entry to table and make parent
            graph.add_node(table.retrieve_sentence(min_vector) + "*")
            parent_sentences.append(table.retrieve_sentence(min_vector) + "*")
            parent_vectors.append(np.array(centroids[i], copy=True))

            #add edges to the graph, parent to child
            for v in label_dict[i]:
                graph.add_child_edges(parent_sentences[i],
                                      table.retrieve_sentence(v))

        vectors = np.array(parent_vectors, copy=True)

        # base case
        if num_clusters == 1:
            graph.set_root(parent_sentences[0])
            return graph
        # recursive case
        else:
            return self.kmeans_merge_clustering(parent_sentences, vectors,
                                                graph)
 def __init__(self):
     self.graph = Graph()
Пример #19
0
class Entity:
    def __init__(self, id_, name, electrical_system, province, commune,
                 cross_sectional_area, receptor):
        self.id_structure = id_
        self.name = name
        self.electrical_system = electrical_system
        self.province = province
        self.commune = commune
        self.cross_sectional_area = cross_sectional_area
        self.connected_to = Graph(id_, self)
        self.receptor = receptor
        self.max_of_parents = inf
        self.power_consumed = 0.0  # potencia que se necesita para funcionar
        self.parents_data = List()
        self.received_power = 0.0
        self._demanded_power = 0.0  # Guarda el valor de la demanda,
        # así este solo se calcula una vez
        self.received = False
        self.extra_energy = 0

    @property
    def current_power(self):
        if isinstance(self, Consumer) and self.received_power > 30:
            raise ElectricalOverload("Añadir",
                                     f"{self._demanded_power - 30} mW")
        available = self.received_power - self.power_consumed
        if available <= 0:
            return 0
        return available

    @property
    def used_power(self):
        used = self.received_power - self.current_power
        if used < 0:
            return self.received_power
        return used

    @property
    def demanded_power(self):
        """
        Retorna la potencia demandada por el nodo actual mas la potencia
        demandada por los hijos de este considerando la perdida de energia
        """
        total_power = self.power_consumed
        for i in self.connected_to:
            total_power += self.power_required_to_send(i)
            # resistencia
        if len(self.parents_data) > 0:
            self._demanded_power = total_power / len(self.parents_data)
            if self._demanded_power > 30 and isinstance(self, Consumer):
                raise ElectricalOverload("Add_connection",
                                         f"{self._demanded_power - 30} mW")
            return total_power / len(self.parents_data)  # Se divide el gasto
        # entre los padres del nodo
        self._demanded_power = total_power  # Asi se accede más rapido a este
        #  valor
        if self._demanded_power > 30 and isinstance(self, Consumer):
            raise ElectricalOverload("Add_connection",
                                     f"{self._demanded_power - 30} mW")
        return total_power

    @property
    def drained_energy(self):
        total_drained = 0
        direct_connnection = self.find_direct_connection()
        if direct_connnection is None:
            print("Casa aislada")
            return 0
        first = 0
        second = 1
        while first < len(direct_connnection) - 1:
            total_drained += (
                direct_connnection[first].value.get_relative_power_to_send(
                    direct_connnection[second].value) *
                direct_connnection[second].value.get_resistance(
                    direct_connnection[first].value))
            # Se suma: Potencia mandada * Resistenca = Potencia perdida en el
            #  cable
            first += 1
            second += 1
        return total_drained

    def find_direct_connection(self):  # Busca la conexion directa a una
        # elevadora
        if isinstance(self, LiftingStation):  # Caso base: Llegamos a la
            # estacion elevadora
            return List(self)
        for i in self.parents_data:  # De lo contrario buscamos en los padres
            result = i.value[0].value.find_direct_connection()
            if result is not None:
                result.append(self)  # Se agrega a si mismo y se retorna
                return result

    def power_required_to_send(self, element):  # Retorna
        # potencia requerida por un element que es hijo del nodo actual
        return element.demanded_power / (1 - element.get_resistance(self))

    def get_relative_power_to_send(self, element):
        # Emtrega la cantidad de energia que debe mandar  a element en relacion
        # a lo que están demandadando en total al nodo actual
        total = 0
        element_demand = element._demanded_power / (
            1 - element.get_resistance(self))
        for i in self.connected_to:
            total += i._demanded_power / (1 - i.get_resistance(self))
        return self.current_power * (element_demand / max(1, total))

    def get_resistance(self, from_):  # Entrega solo la potencia pérdida
        # entre el nodo actual y un padre
        RESISTIVITY = 0.0172
        for i in self.parents_data:
            if i.value[0].value == from_:
                return RESISTIVITY * i.value[1].value / i.value[2].value

    def use_extra_energy(self, demanded_power, power_to_send):
        if self.extra_energy == 0:
            return power_to_send  # Si es 0 no ocurre nada
        if demanded_power - power_to_send <= self.extra_energy:
            self.extra_energy -= demanded_power - power_to_send  # Se le resta
            # lo que se ocupa de esta sobra
            return demanded_power  # Se suple la demanda
        aditional = power_to_send + self.extra_energy  # Se usa extra
        self.extra_energy = 0  # Se usará toda
        return aditional

    def send_power(self, element):
        power_to_send = self.get_relative_power_to_send(element)
        # Se verifica que no se mande más de lo necesario
        if power_to_send > element._demanded_power / (
                1 - element.get_resistance(self)):
            self.extra_energy += power_to_send - (
                element._demanded_power / (1 - element.get_resistance(self)))
            element.received_power += element._demanded_power  # Se suple su
            # demanda
        else:
            element.received_power += self.use_extra_energy(
                element._demanded_power,
                power_to_send) * (1 - element.get_resistance(self))

    def distribute_power(self, to=None):
        # Primero el nodo le pide a todos sus padres que le manden energia
        if not self.received:
            for i in self.parents_data:
                i.value[0].value.distribute_power(self)
                # Luego de que ya le llega energía desde todos sus padres
                # entonces le manda a sus hijos
        self.received = True  # Ya recibio la energia asi que dejamos el
        # registro de que recibio completamente su energia
        if to is not None:
            for i in self.connected_to:
                if i == to:
                    self.send_power(i)
                    return

    def set_parent_data(self, element, distance):
        """
        Envia la informacion del padre a parents_data de element
        """
        data = List(self, distance, self.cross_sectional_area)
        element.parents_data.append(data)

    def delete_parent_data(self, element):
        index_ = 0
        for i in element.parents_data:
            if i.value[0].value == self:
                element.parents_data.remove(index_)
                return
            index_ += 1

    def quick_connection(self, element, distance):  # Funciona igual que
        # add_connection solo que se evita hacer comparaciones
        self.set_parent_data(element, distance)
        self.connected_to.add_node(element.id_structure, element)
        self.connected_to.add_connection(element.id_structure)

    def add_connection(self, element, distance):
        if (isinstance(element, TransmisionSubstation)
                or isinstance(element, DistributionSubstation)) and len(
                    element.parents_data) > 0:
            raise ForbbidenAction(
                "add_connection", "Subestaciones de "
                "transmision no admiten "
                "más de un padre")
        if ((isinstance(self, Consumer) or isinstance(self,
                                DistributionSubstation)) and isinstance(
            element, Consumer)) and \
                        self.commune != element.commune:
            raise ForbbidenAction(
                "add_connection", f"Imposible unir "
                f"{type(self)} con {type(element)} debido a "
                f"que son de distintas comunas")
        if self.electrical_system == element.electrical_system:
            if type(element) == self.receptor:
                if element not in self.connected_to:
                    self.connected_to.add_node(element.id_structure, element)
                    self.connected_to.add_connection(element.id_structure)
                    self.set_parent_data(element, distance)
                else:  # Si la conexion existe
                    raise ForbbidenAction("add_connection", f"El camino ya "
                                          f"existe")

                return
            raise ForbbidenAction(
                "add_connection", f"{type(self)} no "
                f"puede unirse a "
                f"{type(element)}")
        raise ForbbidenAction("add_connection", "Nodos de distintos sistemas "
                              "electricos")

    def remove_connection(self, element):
        if element in self.connected_to:
            self.connected_to.remove_connection(element.id_structure)
            self.delete_parent_data(element)
        else:
            raise ForbbidenAction("remove_connection", f"Camino no existente")

    def remove_self(self, liftings, transmisions, distributions, consumers):
        for i in self.parents_data:  # Se desconecta de los padres
            i.value[0].value.remove_connection(self)
        for i in self.connected_to:  # Se desconecta de los hijos
            self.remove_connection(i)
            if len(i.parents_data) == 0:  # En caso que el hijo se quede sin
                # padre también se extrae
                i.remove_self(liftings, consumers, distributions, consumers)
        # Finalmente el nodo se quita de la lista
        if isinstance(self, LiftingStation):
            liftings.remove(self.id_structure)
        elif isinstance(self, TransmisionSubstation):
            transmisions.remove(self.id_structure)
        elif isinstance(self, DistributionSubstation):
            distributions.remove(self.id_structure)
        elif isinstance(self, Consumer):
            consumers.remove(self.id_structure)

    def __eq__(self, other):
        return self.id_structure == other.id_structure