Example #1
0
def coloring(graph: Graph) -> Optional[int]:
    """The algorithm for coloring a graph"""
    if graph.size() == 0:
        return 0
    if not sum((sum(graph.to_matrix(with_weight=False), []))):
        for v in graph.vertexes_coordinates.values():
            v.color = generate_color(1)
        return 1
    colors: Dict[str, int] = {}
    degrees: List[Tuple[str, int]] = __get_degrees(graph)
    colors[degrees[0][0]] = 1

    while len(colors) != len(degrees):
        for vertex_name, _ in degrees:
            neighbor_colors = [
                colors.get(name) for name in graph.vertexes[vertex_name]
                if colors.get(name) is not None
            ]
            if not neighbor_colors:
                neighbor_colors = [0]
            color = 0
            for i in range(1, max(neighbor_colors) + 2):
                if i not in neighbor_colors:
                    color = i
                    break
            colors[vertex_name] = color

    for vertex in graph.vertexes_coordinates.values():
        vertex.color = generate_color(colors[vertex.name])

    return max(colors.values())
Example #2
0
 def load(graph: Graph, file_name: str):
     graph.clear()
     # получаем данные из файла
     # vertexes, v_coordinates = LoadGraph.__split_file(file_name)
     with open(file_name, 'r') as file:
         data = json.load(file)
         try:
             graph.vertexes = data['vertexes']
         except KeyError:
             return False
         # загружем данные о координатах или генерируем, если их нет
         if 'coordinates' in data:
             coordinates = data['coordinates']
             for d in coordinates:
                 graph.vertexes_coordinates[d['name']] = Vertex(
                     d['name'], d['x'], d['y'])
         else:
             for v in graph.vertexes:
                 graph.vertexes_coordinates[v] = Vertex(
                     v, random.randint(0, 100), random.randint(0, 100))
         if 'oriented' in data:
             graph.oriented = data['oriented']
         if 'weighted' in data:
             graph.weighted = data['weighted']
         if 'path' in data:
             graph.path = data['path']
     graph.update()
     return True
def test_8():
    graph = Graph()

    actual = graph.get_nodes()
    expected = None

    assert actual == expected
def test_depth_first_1():
    graph = Graph()
    node_1 = graph.add_node('')
    actual = graph.depth_first(node_1)
    expected = [node_1]

    assert actual == expected
def test_breadth_first_1():
    graph = Graph()
    node_1 = graph.add_node('1')
    actual = graph.breadth_first(node_1)
    expected = [node_1]

    assert actual == expected
class TestGraphConstructionAndParsing(unittest.TestCase):
    """ Tests for graph construction and parsing.

	Tests for graph construction and parsing.
	Tests include tests vertices and edges construction.

	"""
    def setUp(self):
        self.graph = Graph()
        self.graph.load("../json/test_data.json")

    def test_vertices_construction(self):
        self.assertTrue("MEX" in self.graph.vertices.keys())
        self.assertTrue("LIM" in self.graph.vertices.keys())
        self.assertTrue("SCL" in self.graph.vertices.keys())

    def test_edges_construction(self):
        edges = []
        for edge in self.graph.edges.values():
            edges.append(edge.departure.code + " -> " + edge.destination.code +
                         ", " + str(edge.distance))
        edges.sort()
        self.assertEqual(edges, [
            'LIM -> MEX, 24530', 'LIM -> SCL, 2453', 'MEX -> LIM, 24530',
            'MEX -> SCL, 4800', 'SCL -> LIM, 2453', 'SCL -> MEX, 4800'
        ])
Example #7
0
 def setUp(self):
     f = open('assets/data/map_data.json', 'r')
     decoded = json.loads(f.read())
     self.g = Graph()
     self.g.build_nodes(decoded['metros'])
     self.g.build_edges(decoded['routes'])
     self.utils = GraphUtils()
Example #8
0
    def test_add_node(self):
        graph = Graph()
        graph.add_node(1)
        graph.add_node(2)

        self.assertEqual(graph.nodes, {1: [], 2: []})
        self.assertRaises(Exception, Graph.add_node, 1)
Example #9
0
    def teste_kruskal_mst_algorithm(self):
        '''Kruskal's algorithm uses Disjoint Set under the hook'''
        edges = [
            ('a', 'b', 4),
            ('a', 'h', 8),
            ('h', 'b', 11),
            ('h', 'i', 7),
            ('h', 'g', 1),
            ('i', 'g', 6),
            ('i', 'c', 2),
            ('b', 'c', 8),
            ('c', 'f', 4),
            ('g', 'f', 2),
            ('d', 'f', 14),
            ('c', 'd', 7),
            ('d', 'e', 9),
            ('e', 'f', 10),
        ]

        graph = Graph()
        for v, u, w in edges:
            graph.add_edge(v, u, weight=w)

        tree = kruskal(graph)

        nro_edges = gg_edges_number(tree)
        cost = gg_total_weight(tree)

        self.assertEqual(nro_edges, 8)
        self.assertEqual(cost, 37)
        self.assertFalse(has_cycle(graph))
Example #10
0
def test_size():
    graph = Graph()
    graph.add_node('a')
    graph.add_node('b')
    expected = 2
    actual = graph.size()
    assert actual == expected
Example #11
0
def test_size_fail():
    graph = Graph()
    graph.add_node('a')
    graph.add_node('b')
    expected = 3
    actual = graph.size()
    assert actual != expected
Example #12
0
 def test_fill_in_graph_with_words(self):
     graph = Graph()
     graph = fill_in_graph_with_words(
         graph, ["ratata", "ratta", "atata", "ratt", "att", "a"])
     self.assertEqual(3, len(graph.get_vertices_with_edge()))
     self.assertSetEqual({"ratata", "ratta", "ratt"},
                         set(graph.get_vertices_with_edge()))
Example #13
0
def isomorphic(first: Graph, second: Graph) -> str:
    first_vector, second_vector = __get_rib_vector(first), __get_rib_vector(
        second)

    if len(first_vector) != len(second_vector):
        return 'Сильная неизоморфность\nВектора степеней не равны'

    first_vector.sort()
    second_vector.sort()
    if first_vector != second_vector:
        return f'Сильная неизоморфность\nВектора степеней не равны\n{first_vector}\n{second_vector}'

    first_vector, second_vector = __get_weight_vector(
        first), __get_weight_vector(second)

    if len(first_vector) != len(second_vector):
        return 'Сильная неизоморфность\nВектора степеней не равны'

    first_vector.sort()
    second_vector.sort()
    if first_vector != second_vector:
        return f'Сильная неизоморфность\nВектора степеней не равны\n{first_vector}\n{second_vector}'

    first_matrix = first.to_matrix(with_weight=True)
    second_matrix = second.to_matrix(with_weight=True)

    size = first.size()
    p = [[0 for i in range(size)] for i in range(size)]
    if backtrack(first_matrix, second_matrix, p, 1) is not None:
        return 'Графы изоморфны'
    else:
        return 'Графы не изоморфны'
Example #14
0
    def test_get_vertex(self):
        g = Graph()
        vertex = g.add_vertex('v1')

        self.assertEqual(vertex, g.get_vertex('v1'))
        self.assertEqual(vertex, g.get_vertex(vertex))
        self.assertRaises(ValueError, g.get_vertex, 'v2')
Example #15
0
 def setUp(self):
     country1 = '{[(5,3),(7,3),(5,5)],[(5,5),(7,7),(9,5),(7,3)]}' \
                ',{[(1,1),(4,1),(4,3),(1,3)],[(2,3),(2,5),(5,5)' \
                ',(5,3)],[(4,0),(7,0),(7,3),(4,3)]},{[(9,5),' \
                '(11,7),(9,9),(7,7)]},{[(8,4),(8,0),(7,0)]},' \
                '{[(4, 8),(4,5),(7,7),(6,9)]},' \
                '{[(9, 7),(12,9),(14,6),(11,5)]}'
     country2 = '{[(3,1),(9,2),(3,-6),(3,-5),(1,-5),(1,-2)],' \
                '[(7,4),(7,6),(9,6),(9,4)]},' \
                '{[(1,-2),(3,1),(2,3),(-6,0),(-5,-2),(-3,-4)]},' \
                '{[(1,-2),(-3,-4),(-5,-7),(-3,-10),' \
                '(3,-6),(3,-5),(1,-5),(1,-2)]},' \
                '{[(-3,-10),(-8,-12),(-7,-17),(-2,-14)]},' \
                '{[(12,-5),(14,-9),(11,-12),(8,-8)]},' \
                '{[(11,-12),(8,-8),(4,-12),(6,-16)]}'
     three1 = Parser(country1).get_tree()
     three2 = Parser(country2).get_tree()
     self.vertices1 = list()
     for country in three1:
         self.vertices1.append(CountryVertex(country))
     self.graph1 = Graph(self.vertices1)
     self.vertices2 = list()
     for country in three2:
         self.vertices2.append(CountryVertex(country))
     self.graph2 = Graph(self.vertices2)
Example #16
0
def test_get_nodes():
    graph = Graph()
    a = graph.add_node('a')
    b = graph.add_node('b')
    actual = graph.get_nodes()
    expected = ['a', 'b']
    assert actual == expected
Example #17
0
def g7():
    g = Graph()
    vert = []
    for i in range(1):
        vert.append(g.insert_vertex(i))

    return g, vert[0]
Example #18
0
    def test_get_direction_same_y(self):
        """
		Test that when getting the distance between two points with the same y-coordinate, the x-distance is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual(1, round(graph._get_distance((0, 0), (1, 0)), 5))
Example #19
0
def test_add_two_vertices():
    g = Graph()
    v1 = g.add_vertex('A')
    v2 = g.add_vertex('B')
    assert v1.value == 'A'
    assert v1 in g.get_vertices()
    assert v2.value == 'B'
    assert v2 in g.get_vertices()
def test_7():
    graph = Graph()
    vertex = graph.add_node('first node')

    actual = graph.get_nodes()
    expected = {vertex:0}.keys()

    assert actual == expected
Example #21
0
    def test_get_direction_same_y_normalized(self):
        """
		Test that when getting the direction between two points with the same y-coordinate, the normalized x-direction is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual((1, 0), graph._get_direction((0, 0), (2, 0)))
Example #22
0
    def test_get_distance_same(self):
        """
		Test that when getting the distance between the same point, 0 is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual(0, round(graph._get_distance((1, 1), (1, 1)), 5))
Example #23
0
    def test_get_direction_same(self):
        """
		Test that when getting the direction between the same point, a zero tuple is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual((0, 0), graph._get_direction((1, 1), (1, 1)))
Example #24
0
    def test_get_angle_same(self):
        """
		Test that when the same points are given to calculate the angle, an angle of 0 is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual(0, round(graph._get_angle((1, 1), (1, 1)), 5))
Example #25
0
class Bot:
    def __init__(self, cfg_path):
        # constance.
        self.cfg_path = cfg_path
        self.init_sentence = "开场白:1"
        self.retrieve_sentence = "挽回:1"
        self.invite_sentence = "邀约:1"
        self.end_sentence = "结束:1"
        self.latest_response = ""
        self.global_events_cfg_path = os.path.join(self.cfg_path, 'global_events')

        self.conversations = []

        # class instance.
        self.graph = Graph(self.cfg_path, self.init_sentence)
        self.global_events = self._init_global_events()
        self.analyst = Analyst(self.cfg_path)

    def reset(self):
        return copy.deepcopy(self)

    def start(self):
        return self.answer(init=True)

    def answer(self, sentence=None, init=False):
        if not sentence and init:
            """初始化"""
            self.latest_response = self.graph.say(self.init_sentence)
            self.conversations.append([self.latest_response])
            return self.latest_response
        else:
            """global event"""
            event = self.global_events.answer(sentence)
            if event:
                response = self.global_events_action(event)
                self.conversations.append([sentence, response])
                return response
            else:
                """按照流程走"""
                self.latest_response = self.graph.answer(sentence)
                self.conversations.append([sentence, self.latest_response])
                return self.latest_response

    def _init_global_events(self):
        return GlobalEvent(os.path.join(self.global_events_cfg_path, 'global.json'))

    def global_events_action(self, event):
        if event == "不清楚":
            return self.latest_response
        if event == "拒绝":
            return self.graph.say(self.retrieve_sentence)
        if event == "邀约":
            return self.graph.say(self.invite_sentence)
        if event == "结束":
            return self.graph.say(self.end_sentence)

    def get_label(self):
        return self.analyst.analyze(self.conversations)
Example #26
0
def test_get_neighbors():
    g = Graph()
    apple = g.add_vertex('apple')
    banana = g.add_vertex('banana')
    cucumber = g.add_vertex('cucumber')
    g.add_edge(apple, banana, 4)
    g.add_edge(apple, cucumber, 5)
    neighbors = g.get_neighbors(apple)
    assert neighbors == [(banana, 4), (cucumber, 5)]
Example #27
0
    def test_get_elevation_same_y(self):
        """
		Test that when getting the elevation of two points with the same y-coordinate, an angle of 0 degrees is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual(0, graph._get_elevation((0, 1), (1, 1)))
        self.assertEqual(0, graph._get_elevation((0, 1), (-1, 1)))
Example #28
0
    def test_get_elevation_same(self):
        """
		Test that when getting the elevation of two identical points, an angle of 0 is returned.
		"""

        viz = drawable.Drawable(plt.figure(figsize=(10, 5)))
        graph = Graph(viz)
        self.assertEqual(0, graph._get_elevation((0, 0), (0, 0)))
        self.assertEqual(0, graph._get_elevation((1, 1), (1, 1)))
Example #29
0
def generate_graph(number=100, directed=False):
    g = Graph(directed)
    vertexes = _generate_vertexes(g, number)
    for i in range(number):
        start = 0 if directed else i
        for j in range(start, number):
            if (i != j and bool(random.getrandbits(1))):
                g.insert_edge(vertexes[i], vertexes[j])
    return g
def test_add_node():  # test 1

    graph = Graph()

    expected = 'ayman'

    actual = graph.add_node('ayman').value

    assert actual == expected
def test_size_empty():  # return 0 if its empty graph

    graph = Graph()

    expected = 0

    actual = graph.size()

    assert actual == expected
Example #32
0
    def test_add_vertex(self):
        g = Graph()
        g.add_vertex('v1')
        self.assertEqual(1, len(g.vertices))
        self.assertRaises(ValueError, g.add_vertex, 'v1')

        vertex = Vertex('v2')
        g.add_vertex(vertex)
        self.assertEqual(2, len(g.vertices))
        self.assertRaises(ValueError, g.add_vertex, vertex)
Example #33
0
def load_graph(*file_addr):
    """Initialize a Graph object, and load graph info including vertices and edges into the Graph object from the specified file paths.

    Args:
        file_addr: Specified file paths containing a JSON string.

    Returns:
        A graph object with info loaded from specified file path.
    """
    graph = Graph()
    for addr in file_addr:
        graph.load(addr)
    return graph
Example #34
0
    def test_get_successor_predecessor(self):
        g = Graph()
        v1 = g.add_vertex('v1')
        v2 = g.add_vertex('v2')
        v3 = g.add_vertex('v3')
        e1 = g.add_edge(v1, v2)
        e2 = g.add_edge(v1, v3)
        e3 = g.add_edge(v2, v3)

        self.assertEqual(2, len(v1.get_successors()))
        self.assertEqual(1, len(v2.get_successors()))
        self.assertEqual(0, len(v3.get_successors()))

        self.assertEqual(0, len(v1.get_predecessors()))
        self.assertEqual(1, len(v2.get_predecessors()))
        self.assertEqual(2, len(v3.get_predecessors()))
Example #35
0
 def setUp(self):
   f = open('assets/data/map_data.json', 'r')
   decoded = json.loads(f.read())
   self.g = Graph()
   self.g.build_nodes(decoded['metros'])
   self.g.build_edges(decoded['routes'])
   self.utils = GraphUtils()
Example #36
0
def get_MST_Kruskal(graph):
    graph.sort_edges()
    sorted_edges = graph.edges

    mst = Graph()

    #  koloruje graf
    graph.set_nodes_id()

    for edge in sorted_edges:
        if edge.has_different_ids():
            #  jeżeli tak zamieniamy wszystkie id takie jak wezła koncowego na takie jak wezła poczatkowego w grafi
            graph.change_all_ids(edge.end_node.id, edge.start_node.id)
            mst.add_edge(edge)

    return mst
Example #37
0
 def setUp(self):
     # It is all same with non-directed graph, test of vertex and edge covered that
     self.graph = Graph(True)
     self.test_vertex = Vertex("A", directed=True)
     self.graph._nodes["A"] = self.test_vertex
     self.test_vertex2 = Vertex("C", directed=True)
     self.graph._nodes["C"] = self.test_vertex2
    def construct_triangle_network(self):
        """Constructs a triangle, clearly not bipartite"""
        network = Graph()
        n1 = Node(1)
        n2 = Node(2)
        n3 = Node(3)

        network.add_node(n1)
        network.add_node(n2)
        network.add_node(n3)

        network.add_edge(UndirectedEdge(n1, n2))
        network.add_edge(UndirectedEdge(n2, n3))
        network.add_edge(UndirectedEdge(n3, n1))

        return network
Example #39
0
    def test_add_edge(self):
        g = Graph()
        g.add_vertex('v1')
        g.add_vertex('v2')
        g.add_vertex('v3')
        g.add_vertex('v4')

        edge = g.add_edge('v1', 'v2')
        self.assertEqual(1, len(g.edges))
        self.assertEqual(1, len(g.get_vertex('v1').neighbors))
        self.assertEqual(1, len(g.get_vertex('v2').neighbors))
        self.assertTrue(g.get_vertex('v1') in edge.get_vertices())
        self.assertTrue(g.get_vertex('v2') in edge.get_vertices())

        edge = g.add_edge('v3', 'v4', label='foo', value=10)
        self.assertEqual('foo', edge.label)
        self.assertEqual(10, edge.value)
Example #40
0
def KruskalMST(g):
    c = []  # empty set of clusters
    for v in g.vertices:
        c.append(Graph(v))
    q = sorted(g.edges, reverse=True) # use the edge weights as keys
    T = Graph() # empty tree
    counter = 0
    while len(T) < len(g) - 1:
        counter += 1
        e = q.pop()
        origGraph = graphWithVertex(c, e.origin)
        destGraph = graphWithVertex(c, e.destination)
        if origGraph is not None and destGraph is not None:
            if origGraph is not destGraph:
                T.addEdge(e)
                # remove the graphs for union
                c.remove(origGraph)
                c.remove(destGraph)
                c.append(origGraph.getUnion(destGraph))
        T.render('Step {}'.format(counter))
    return T
Example #41
0
    def test_remove_vertex(self):
        g = Graph()
        vertex1 = g.add_vertex('v1')
        vertex2 = g.add_vertex('v2')
        g.add_vertex('v3')
        edge1 = g.add_edge('v1', 'v2')
        edge2 = g.add_edge('v1', 'v3')
        edge3 = g.add_edge('v2', 'v3')

        g.remove_vertex('v3')
        self.assertEqual(2, len(g.vertices))
        self.assertEqual(1, len(g.edges))
        self.assertTrue('v3' not in g.vertices)
        self.assertEqual(1, len(vertex1.neighbors))
        self.assertEqual(1, len(vertex2.neighbors))
Example #42
0
def get_MST_Prim(graph):
    mst = Graph()

    #  node poczatkowy
    node = graph.nodes[0]

    #  znajduje wszystkie krawedzie zawiedające node
    edges = graph.get_edges_with_nodes([node])
    edges.sort(key=lambda e: e.weight)

    # dodaje najlzejsza krawędź do mst
    edge_to_add = edges[0]
    mst.add_edge(edge_to_add)

    #zaznaczam nody jako zużyte
    graph.set_node_id(edge_to_add.start_node, 1)
    graph.set_node_id(edge_to_add.end_node, 1)

    while len(mst.edges) < len(graph.nodes)-1:
        #  znajdujemy zużyte nody (dla uproszczenia z mst)
        nodes = mst.nodes

        #  zanajdujemy krawedzie z zuzytymi wierzchołkami
        edges = graph.get_edges_with_nodes(nodes)

        #  usuwam krawedzie z dwoma zużytymi nodami
        edges = get_edges_with_one_used_node(edges)

        #  znajduje najlżejszą krawedz
        edges.sort(key=lambda e: e.weight)
        edge_to_add = edges[0]
        mst.add_edge(edge_to_add)

        #  zaznaczam nody jako zużyte
        graph.set_node_id(edge_to_add.start_node, 1)
        graph.set_node_id(edge_to_add.end_node, 1)

    return mst
class TestGraphConstructionAndParsing(unittest.TestCase):
	""" Tests for graph construction and parsing.

	Tests for graph construction and parsing.
	Tests include tests vertices and edges construction.

	"""
	def setUp(self):
		self.graph = Graph()
		self.graph.load("../json/test_data.json")


	def test_vertices_construction(self):
		self.assertTrue("MEX" in self.graph.vertices.keys())
		self.assertTrue("LIM" in self.graph.vertices.keys())
		self.assertTrue("SCL" in self.graph.vertices.keys())


	def test_edges_construction(self):
		edges = []
		for edge in self.graph.edges.values():
			edges.append(edge.departure.code + " -> " + edge.destination.code + ", " + str(edge.distance))
		edges.sort()
		self.assertEqual(edges, ['LIM -> MEX, 24530', 'LIM -> SCL, 2453', 'MEX -> LIM, 24530', 'MEX -> SCL, 4800', 'SCL -> LIM, 2453', 'SCL -> MEX, 4800'])
Example #44
0
    def test_remove_edge(self):
        g = Graph()
        vertex1 = g.add_vertex('v1')
        vertex2 = g.add_vertex('v2')
        vertex3 = g.add_vertex('v3')
        edge1 = g.add_edge(vertex1, vertex2)
        edge2 = g.add_edge(vertex2, vertex3)

        g.remove_edge(edge1)
        self.assertEqual(1, len(g.edges))
        self.assertTrue(edge1 not in g.edges)
        self.assertTrue(vertex2 not in vertex1.neighbors)

        g.remove_edge_between('v2', vertex3)
        self.assertEqual(0, len(g.edges))
        self.assertTrue(edge2 not in g.edges)
        self.assertTrue(vertex3 not in vertex2.neighbors)
Example #45
0
    def __init__(self, file_path):
        """ Constructor, initialize all of necessary data structures, and loads all data from database in them

            Object has trie - which is used for storing all words and data about word origin, graph which is used
            for path linking (database linking in operative memory), file_list and file_words_list which are side
            lists used for some internal manipulations, and io - (IOAdapter instance) which is used for printing
            out information (results of search)

            Args:
                file_path - path to database (with html files)
        """

        self._trie = Trie()
        self._graph = Graph(directed=True)
        self._file_list, self._file_words_list = [], []
        self._io = Search.IOAdapter(self._file_list, file_path)

        self.__load_data(os.path.abspath(file_path), Parser())
Example #46
0
from algorithms.kurskal import get_MST_Kruskal
from algorithms.prim import get_MST_Prim

from graph.egde import Edge
from graph.graph import Graph
from graph.node import Node

__author__ = 'Jakub'


if __name__ == '__main__':
    graph = Graph()

    graph.add_edge(Edge(Node("1"), Node("2"), 1))
    graph.add_edge(Edge(Node("1"), Node("3"), 2))

    graph.add_edge(Edge(Node("4"), Node("1"), 2))
    graph.add_edge(Edge(Node("1"), Node("5"), 6))

    graph.add_edge(Edge(Node("2"), Node("4"), 4))
    graph.add_edge(Edge(Node("2"), Node("5"), 5))

    graph.add_edge(Edge(Node("3"), Node("4"), 3))
    graph.add_edge(Edge(Node("4"), Node("5"), 3))

    # graph.add_edge(Edge(Node("a"), Node("b"), 4))
    # graph.add_edge(Edge(Node("a"), Node("e"), 1))
    # graph.add_edge(Edge(Node("a"), Node("f"), 2))
    #
    # graph.add_edge(Edge(Node("b"), Node("c"), 2))
    # graph.add_edge(Edge(Node("b"), Node("e"), 2))
Example #47
0
class TestGraphQuery(unittest.TestCase):
	""" Tests for graph queries.

	Tests for graph queries.
	Tests include testsing longest edge, shortest edge, average edge distance, biggest vertex,
	smallest vertex, average vertex size, continents info, hub cities, and map url.

	"""
	def setUp(self):
		self.graph = Graph()
		self.graph.load("../json/test_data.json")


	def test_longest_edge(self):
		longest_edge = sorted(self.graph.calculate_longest_edge(), key=lambda x: x.departure.code)
		self.assertEqual(longest_edge[0].departure.code, "LIM")
		self.assertEqual(longest_edge[1].departure.code, "MEX")
		self.assertEqual(longest_edge[0].distance, 24530)


	def test_shortest_edge(self):
		shortest_edge = sorted(self.graph.calculate_shortest_edge(), key=lambda x: x.departure.code)
		self.assertEqual(shortest_edge[1].departure.code, "SCL")
		self.assertEqual(shortest_edge[0].departure.code, "LIM")
		self.assertEqual(shortest_edge[0].distance, 2453)


	def test_average_distance(self):
		average_distance = self. graph.calculate_average_distance()
		self.assertEqual(int(average_distance), 10594)


	def test_biggest_vertex(self):
		biggest_vertex = self.graph.calculate_biggest_vertex()
		self.assertEqual(biggest_vertex.code, "MEX")


	def test_smallest_vertex(self):
		smallest_vertex =self.graph.calculate_smallest_vertex()
		self.assertEqual(smallest_vertex.code, "SCL")


	def test_average_size(self):
		average_size = self. graph.calculate_average_vertex_size()
		self.assertEqual(int(average_size), 12816666)


	def test_continents_info(self):
		continents_dict = self.graph.calculate_continents_info()
		self.assertTrue("South America" in continents_dict.keys())
		self.assertTrue("North America" in continents_dict.keys())
		cities = []
		for value in continents_dict.values():
			for city in value:
				cities.append(city.code)
		self.assertTrue("MEX" in cities)
		self.assertTrue("SCL" in cities)
		self.assertTrue("LIM" in cities)


	def test_hub_cities(self):
		hub_cities = self.graph.calculate_hub_cities()
		hub_cities = [hub_cities[0].code, hub_cities[1].code, hub_cities[2].code]
		self.assertTrue("MEX" in hub_cities)
		self.assertTrue("SCL" in hub_cities)
		self.assertTrue("MEX" in hub_cities)


	def test_map_url(self):
		url = self.graph.generate_map_url()
		self.assertTrue("MEX-SCL" in url)
		self.assertTrue("LIM-MEX" in url)
		self.assertTrue("SCL-LIM" in url)


	def test_add_vertex(self):
		self.assertTrue(self.graph.add_vertex(city))
		self.assertTrue("CMI" in self.graph.vertices.keys())
		self.assertEqual(self.graph.vertices["CMI"].name, "Champaign")


	def test_add_edge(self):
		self.assertTrue(self.graph.add_vertex(city))
		self.assertFalse(self.graph.add_edge("CMI", "PAR", 30000))
		self.assertTrue(self.graph.add_edge("CMI", "MEX", 30000))
		edges = []
		for edge in self.graph.edges.values():
			edges.append(edge.departure.code + " -> " + edge.destination.code + ", " + str(edge.distance))
		edges.sort()
		self.assertEqual(edges, ['CMI -> MEX, 30000', 'LIM -> MEX, 24530', 'LIM -> SCL, 2453', 'MEX -> LIM, 24530', 'MEX -> SCL, 4800', 'SCL -> LIM, 2453', 'SCL -> MEX, 4800'])


	def test_remove_edge(self):
		self.assertFalse(self.graph.remove_edge("CMI", "PAR"))
		self.assertTrue(self.graph.add_vertex(city))
		self.assertTrue(self.graph.add_edge("CMI", "MEX", 30000))
		self.assertTrue(self.graph.remove_edge("CMI", "MEX"))
		edges = []
		for edge in self.graph.edges.values():
			edges.append(edge.departure.code + " -> " + edge.destination.code + ", " + str(edge.distance))
		edges.sort()
		self.assertEqual(edges, ['LIM -> MEX, 24530', 'LIM -> SCL, 2453', 'MEX -> LIM, 24530', 'MEX -> SCL, 4800', 'SCL -> LIM, 2453', 'SCL -> MEX, 4800'])


	def test_remove_vertex(self):
		self.assertFalse(self.graph.remove_vertex("PAR"))
		self.assertTrue(self.graph.add_vertex(city))
		self.assertTrue(self.graph.add_edge("CMI", "MEX", 30000))
		self.assertTrue(self.graph.remove_vertex("CMI"))
		self.assertFalse("CMI" in self.graph.vertices.keys())
		edges = []
		for edge in self.graph.edges.values():
			edges.append(edge.departure.code + " -> " + edge.destination.code + ", " + str(edge.distance))
		edges.sort()
		self.assertEqual(edges, ['LIM -> MEX, 24530', 'LIM -> SCL, 2453', 'MEX -> LIM, 24530', 'MEX -> SCL, 4800', 'SCL -> LIM, 2453', 'SCL -> MEX, 4800'])


	def test_save_to_disk(self):
		test_string = '{"metros": [{"code": "LIM", "continent": "South America", "coordinates": {"S": 12, "W": 77}, "country": "PE", "name": "Lima", "population": 9050000, "region": 1, "timezone": -5}, {"code": "MEX", "continent": "North America", "coordinates": {"N": 19, "W": 99}, "country": "MX", "name": "Mexico City", "population": 23400000, "region": 1, "timezone": -6}, {"code": "SCL", "continent": "South America", "coordinates": {"S": 33, "W": 71}, "country": "CL", "name": "Santiago", "population": 6000000, "region": 1, "timezone": -4}], "routes": [{"distance": 24530, "ports": ["LIM", "MEX"]}, {"distance": 2453, "ports": ["LIM", "SCL"]}, {"distance": 24530, "ports": ["MEX", "LIM"]}, {"distance": 4800, "ports": ["MEX", "SCL"]}, {"distance": 2453, "ports": ["SCL", "LIM"]}, {"distance": 4800, "ports": ["SCL", "MEX"]}]}'
		json_string = json.dumps(self.graph.convert_to_json(), sort_keys=True)
		self.assertEqual(json_string, test_string)


	def test_route_info(self):
		route = ['MEX', 'SCL', 'LIM']
		self.assertTrue(self.graph.is_valid_route(route))
		cost, time = self.graph.calculate_route_info(route)
		self.assertEqual(cost, 2415.90)
		self.assertEqual(time, 12.57)
		self.graph.remove_edge("MEX", "SCL")
		self.assertFalse(self.graph.is_valid_route(route))


	def test_shortest_path(self):
		shortest_path = ['MEX', 'SCL', 'LIM']
		route = self.graph.calculate_shortest_path(['MEX', 'LIM'])
		self.assertEqual(route, shortest_path)
		self.assertTrue(self.graph.add_vertex(city))
		route = self.graph.calculate_shortest_path(['MEX', 'CMI'])
		self.assertEqual(route, None)
Example #48
0
class Search(object):
    """ Main class for search.

        When instanced it creates all structures necessary for internal work, and does initial
        database reading and parsing.

        It contains bunch of 'private' methods used for internal operating, and one 'public' method
        which should be used for searching words and syntagms, and one static public method for writing out
        base instructions for users.

        USE:
            s = Search(path_to_database)
            Search.print_instruction()
            s.find_expression(expression)
    """

    def __init__(self, file_path):
        """ Constructor, initialize all of necessary data structures, and loads all data from database in them

            Object has trie - which is used for storing all words and data about word origin, graph which is used
            for path linking (database linking in operative memory), file_list and file_words_list which are side
            lists used for some internal manipulations, and io - (IOAdapter instance) which is used for printing
            out information (results of search)

            Args:
                file_path - path to database (with html files)
        """

        self._trie = Trie()
        self._graph = Graph(directed=True)
        self._file_list, self._file_words_list = [], []
        self._io = Search.IOAdapter(self._file_list, file_path)

        self.__load_data(os.path.abspath(file_path), Parser())

    def __load_data(self, file_path, parser):
        """ Recursion based method, which goes DFS search and parses all html files found

            For each html (htm) file found in database structure, two methods are called, handle_links, and
            handle_words, which then does all work with words found in file and links found in file.

            Args:
                file_path - path to file (folder) which should be read
                parser - Parser instance which is used to parse html files and extract words and links from them
        """

        if os.path.isfile(file_path) and file_path.split(".")[-1] in ['html', 'htm']:
            links, words = parser.parse(file_path)
            self.__handle_links(file_path, links)
            self.__handle_words(file_path, words)
        elif os.path.isdir(file_path):
            for child in os.listdir(file_path):
                self.__load_data(os.path.join(file_path, child), parser)
        return

    def __handle_links(self, file_path, links):
        """ Method which turns given path and links into graph nodes, and binds them into Search graph

            It creates graph_node with file_path as key if it doesn't already exist, and then connects it
            with all links (which also are turned into graph_node new one if it doesn't exists), with outgoing
            edges (which indicates that current file_path node is pointing to other nodes (links)

            Args:
                file_path - path to file from which are read links
                links -  links on which currently read file pointing
        """

        file_path = os.path.abspath(file_path)
        if self._graph.get_node(file_path) is None:
            self._graph.create_node(file_path)
        for link in links:
            link = os.path.abspath(link)
            if self._graph.get_node(link) is None:
                self._graph.create_node(link)
            self._graph.connect_nodes(self._graph.get_node(file_path), self._graph.get_node(link))

    def __handle_words(self, file_path, words):
        """ Method which stores all words into trie and sets its origin with some additional data

            First it appends file_path graph node to Search file_list and number of words from that path
            into Search file_words_list. Then it adds each word into trie and sets last character additional data
            to dictionary, in which then adds file_path (index from file_list) as a key and list of indexes
            where word is found as a value (used later in syntax search)

            Args:
                file_path - path to file from which are read words
                words - list of all words from file (at given file_path)
        """

        self._file_list.append(self._graph[file_path])
        self._file_words_list.append(len(words))
        for index, word in enumerate(words):
            # time_h = datetime.datetime.now()
            # self._trie.has_word(word)                               # 00:12.5
            # Utils.sum8 += datetime.datetime.now() - time_h
            # if not self._trie.has_word(word):
            #     time_hh = datetime.datetime.now()
            #     self._trie.add_word(word)                           # 00:01.36
            #     Utils.sum5 += datetime.datetime.now() - time_hh
            #     time_hh = datetime.datetime.now()
            #     self._trie.get_node(word).set_data({})              # 00:00.4
            #     Utils.sum6 += datetime.datetime.now() - time_hh
            #
            # if self._trie.get_node(word).get_data().get(file_path) is None:
            # time_l = datetime.datetime.now()
            # self._trie.get_node(word).get_data()[len(self._file_list) - 1] = c[word]  # 00:13.3
            # Utils.sum7 += datetime.datetime.now() - time_l

            node = self._trie.add_word(word)
            if node.get_data() is None:
                node.set_data({})
            try:
                node.get_data()[len(self._file_list) - 1].append(index)
            except KeyError:
                node.get_data()[len(self._file_list) - 1] = [index]

    def __search_word(self, word, words):
        """ Method which finds given word in Search trie

            Args:
                word - (string) which should be looked for
                words - (dict) dictionary in which will all results be putted

            Return:
                Dictionary set as additional data for given word in trie if such word exists, or
                empty dictionary if it doesn't
        """

        res_node = self._trie.get_node(word).get_data() if self._trie.get_node(word) is not None else {}
        words[word] = res_node if res_node is not None else {}
        return res_node if res_node is not None else {}

    def __search_syntagm(self, key, words_, escape_sequence):
        """ Method for searching syntagms.

            First it gets syntagm for search from escape_sequence dictionary, then creates list of words files
            which contains all of those words, and then for each file (which contains all words) it goes through
            list of word results, and checks if there is any index series, where each next word has index + 1

            When ever found such series, number of showing up times raises by one, and current file index is
            added to final_list dictionary (which will be returned). Also words dictionary is with key as key
            and final_list as value.

            Args:
                key - escape key found (recognizes) for which there is an syntax
                words_ - dictionary which should be filled with results for given key
                escape_sequence - dictionary with syntagms which are hidden by key

            Return:
                final_list (dict) which contains all files where syntagm is found as keys, and
                how many times it shows up as value
        """

        words = escape_sequence[key[1:]].split()
        res_list = self.find_expression(escape_sequence[key[1:]], True)
        final_list = {}
        word_list = []
        for word in words:
            word_list.append(self.__search_word(word, words_))

        for index, element in enumerate(res_list):
            indexes = {}
            for index2, word_res_list in enumerate(word_list):
                try:
                    indexes[index2] = word_list[index2][element]
                except KeyError:
                    indexes[index2] = []
            add_const, show_up = 1, 0
            bool_flag = True
            for index2 in indexes[0]:
                bool_flag = True
                while add_const < len(words):
                    if index2 + add_const in indexes[add_const]:
                        add_const += 1
                    else:
                        bool_flag = False
                        break
                if bool_flag:
                    show_up += 1
            if bool_flag:
                final_list[element] = show_up

        words_[key] = final_list
        return final_list

    def find_expression(self, expression, side=False):
        """ Method which should be used (only) from outside. It finds expression and prints out results

            First it creates all necessary dictionaries (which are used by other methods), and using PostfixParser
            parses expression into postfix list. Then for each element calls either search_word or search_syntagm
            depending on element type, and those search results sets into new postfix list, which then passes
            to PostfixParser calculate_postfix (LIST) to get final results.

            In the end it sends those results to sort method which sorts it by priority and calls printing method.

            Args:
                expression - expression to be found
                side - (bool) flag which indicates if results should be printed or just returned

            Return:
                final result list (passed to sort method if side is False)

            Raise:
                Nothing by it self, but other methods called from here can raise:
                InvalidInput - if expression can not be parsed
                QuitRequested - if QUIT exception found
        """

        escape_sequences, words = {}, {}
        postfix_list = PostfixParser.convert_postfix(expression, escape_sequences)
        side_list = []

        for el in postfix_list:
            side_list.append(el)

        for index, element in enumerate(side_list):
            if element not in PostfixParser.OPERATORS.keys():
                if element.startswith(PostfixParser.KEY_SIGN):
                    side_list[index] = self.__search_syntagm(element, words, escape_sequences).keys()
                else:
                    side_list[index] = self.__search_word(element, words).keys()

        final_list = PostfixParser.calculate_postfix_list(side_list, range(len(self._file_list)))

        if side:
            return final_list

        return self.__sort_result(final_list, postfix_list, words)

    def __sort_result(self, final_list, postfix_list, words):
        """ Sorting method, sorts list of results, and sends it to printing method, so it can be printed out.

            It calls method calculate_page_priority which calculates priority for each one file (path) from
            given final_list, and postfix_list, and then, sorts final list using those values as comparison
            parameters. (It uses built in sort method)

            In the end it calls IOAdapter method for printing out results.

            Args:
                final_list - list get by find_expression method, which contains list of all files which
                        fit in search request
                postfix_list - token list in postfix order, used in calculate_page_priority
                words -  list of all words and syntagms search results, so that when calculating priorities
                        it doesn't have to search them again
        """

        priority_list = self.__calculate_page_priority(final_list, postfix_list, words)
        final_list.sort(key=lambda item: priority_list[item], reverse=True)
        self._io.print_results(final_list, priority_list)

    def __calculate_page_priority(self, final_list, postfix_list, words):
        """ Method which calculates each element from final_list summed priority

            It calculates page priority based on three parameters, word count in given file, number of links
            which points to given file, and word count in those links. It uses 1 : 0.7 : 0.4 ratio.

            It uses calculate_word_priority method to get word count (which follows logic in expression)

            Args:
                final_list - list of all files which fit search result
                postfix_list - token list in postfix order (needed for calculate_word_count)
                words - dictionary which contains all search results for all words so that word count
                        doesn't have to be calculated again

            Return:
                Dictionary whit all files from final_list as keys and theirs priority as values
        """

        priority_list = {}

        for index in final_list:
            given_file, number_of_links, other_files = 0, 0, 0

            given_file = self.__calculate_word_priority(postfix_list, self._file_list[index], words)

            number_of_links = self._file_list[index].get_number_of_edges(where_to=Vertex.INCOMING)

            for node in self._file_list[index].get_all_connected_nodes(where_to=Vertex.INCOMING):
                other_files += self.__calculate_word_priority(postfix_list, node, words)

            priority_list[index] = given_file + 0.7 * number_of_links + 0.4 * other_files

        return priority_list

    def __calculate_word_priority(self, postfix_list, graph_node, words):
        """ Method for calculating word count priority part, following expression logic

            It goes through postfix_list and creates new one by changing all words with their count
            (based on words dictionary) which is then passed to PostfixParser calculate_postfix (INT) method,
            which then returns number (presenting current page word count priority)

            Args:
                postfix_list - token list in postfix order
                graph_node - Graph node form Search file_list for which words should be calculated
                words - dictionary which contains all word search results, so that it doesn't have to be calculated
                        again

            Return:
                Number which presents word count part of priority for given node
        """

        side_list = []
        for el in postfix_list:
            side_list.append(el)

        for i, el in enumerate(side_list):
            if el not in PostfixParser.OPERATORS.keys():
                try:
                    if side_list[i].startswith(PostfixParser.KEY_SIGN):
                        side_list[i] = words[self._file_list.index(graph_node)][side_list[i]]
                    else:
                        side_list[i] = len(words[el])
                # KeyError - if word is in trie but doesn't show in current node (path)
                # AttributeError - if word is not in trie at all
                except (KeyError, AttributeError):
                    side_list[i] = 0
        return PostfixParser.calculate_postfix_list(side_list, self._file_words_list[self._file_list.index(graph_node)],
                                                    PostfixParser.INT)

    @staticmethod
    def print_instruction():
        """ Static method for printing out instructions so that user knows how to use this class """

        Search.IOAdapter.print_instruction()

    class IOAdapter(object):
        """ Inner Class which is used to be output stream adapter for Search class

            When instanced it gets file_list which it uses to decode list of results which should be printed out,
            and file_path which is path user typed in, which it uses for parsing abspath so that output looks better.

            It shouldn't be used from outside, it is just inside Search class
        """

        def __init__(self, file_list, file_path):
            """ Constructor which sets given attributes as instance attributes

                Args:
                    file_list - list which is used for mapping results with Vertex instances
                    file_path - path typed in by user (which shouldn't be printed out)
            """
            self._file_path = file_path
            self._file_list = file_list

        def print_results(self, final_list, priority_dictionary):
            """ Method which prints out results with their priorities

                Args:
                    final_list - list of indexes (which presents files) which should be printed
                    priority_dictionary - dictionary which maps indexes with their priority
            """
            print
            print "Rezultati pretrage: "
            Search.IOAdapter._print_break()

            if len(final_list) == 0:
                print "Za unete reci ne postoje rezultati."
            else:
                for index, result in enumerate(final_list):
                    print str(index + 1) + ") " + "%-40s | %8d |" % (
                        os.path.relpath(self._file_list[result].get_key(), self._file_path),
                        priority_dictionary[result])

            Search.IOAdapter._print_break()
            print

        @staticmethod
        def print_instruction():
            """ Static method which prints out instruction (hard coded) """

            print '\nUputstvo za upotrebu: '
            print 'Unosenjem vise od jedne reci razdvojene razmakom (ili skupom razmaka) dobicete'
            print 'skup fajlova u kojima se nalaze sve reci.\n'
            print 'Kljucne reci za logicke operature su "AND", "OR" i "NOT" (ili "&", "|", "!").'
            print '"NOT" operator se posmatra kao unarni operator najviseg prioriteta, dok su "AND"'
            print 'i "OR" binarni operatori nizeg prioriteta ("AND" > "OR").\n'
            print 'Za pretrazivanje sintagmi, zeljenu sintagmu zapisite pod navodnicima.\n'

        @staticmethod
        def _print_break():
            """ Static method which prints break line (100 times '*') """

            print '*' * 100
Example #49
0
class MyTestCase(unittest.TestCase):

    def setUp(self):
        # It is all same with non-directed graph, test of vertex and edge covered that
        self.graph = Graph(True)
        self.test_vertex = Vertex("A", directed=True)
        self.graph._nodes["A"] = self.test_vertex
        self.test_vertex2 = Vertex("C", directed=True)
        self.graph._nodes["C"] = self.test_vertex2

    def tearDown(self):
        self.graph = None

    def test_get_node_all_cases(self):
        # may or may not be true, because of order (dictionary doesn't keep order)
        # self.assertEqual(self.graph.get_all_nodes(), [self.test_vertex, self.test_vertex2])
        self.assertIs(self.graph.get_node("A"), self.test_vertex)
        self.assertIsNone(self.graph.get_node("B"))
        self.assertIs(self.graph["A"], self.test_vertex)

        with self.assertRaises(Exception):
            self.graph["B"]

    def test_add_node(self):
        v = Vertex("B", directed=True)

        self.graph._add_node(v)
        # self.assertEqual(self.graph.get_all_nodes(), [self.test_vertex, self.test_vertex2, v])
        self.assertIs(self.graph.get_node("B"), v)
        self.assertIs(self.graph["B"], v)

        with self.assertRaises(TypeError):
            self.graph._add_node("D")

    def test_node_connecting(self):

        self.graph.connect_nodes(self.test_vertex, self.test_vertex2)

        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.test_vertex.get_all_connected_nodes(where_to=Vertex.OUTGOING), [self.graph["C"]])
        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.INCOMING), 0)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.OUTGOING), 0)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph.get_node("C").get_all_connected_nodes(where_to=Vertex.INCOMING), [self.test_vertex])

        self.graph.connect_nodes(self.graph["C"], self.graph["A"])

        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.test_vertex.get_all_connected_nodes(where_to=Vertex.OUTGOING), [self.graph["C"]])
        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph.get_node("C").get_all_connected_nodes(where_to=Vertex.INCOMING), [self.test_vertex])

    def test_node_connecting_fails_and_both_ways(self):

        self.graph.connect_both_ways(self.test_vertex, self.test_vertex2)

        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.test_vertex.get_all_connected_nodes(where_to=Vertex.OUTGOING), [self.graph["C"]])
        self.assertEqual(self.test_vertex.get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph.get_node("C").get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph.get_node("C").get_all_connected_nodes(where_to=Vertex.INCOMING), [self.test_vertex])

        with self.assertRaises(Exception):
            self.graph.connect_nodes(self.test_vertex, self.test_vertex2)

        with self.assertRaises(TypeError):
            self.graph.connect_nodes("A", "C")

        with self.assertRaises(Exception):
            self.graph.connect_both_ways(self.test_vertex, Vertex("B"))

    def test_exists_and_direction(self):
        self.assertTrue(self.graph.is_directed())
        self.assertTrue(self.graph.exists("A"))
        self.assertFalse(self.graph.exists("B"))

    def test_create_node(self):
        self.graph.create_node("B")

        self.assertTrue(self.graph.exists("B"))

        with self.assertRaises(Exception):
            self.graph.create_node("B")

    def test_remove_node(self):
        self.graph.create_node("B")
        self.graph.create_node("D")

        self.graph.connect_nodes(self.graph["A"], self.graph["B"])
        self.graph.connect_nodes(self.graph["A"], self.graph["D"])
        self.graph.connect_nodes(self.graph["B"], self.graph["C"])
        self.graph.connect_nodes(self.graph["D"], self.graph["B"])

        self.assertEqual(self.graph["A"].get_number_of_edges(where_to=Vertex.OUTGOING), 2)
        self.assertEqual(self.graph["A"].get_number_of_edges(where_to=Vertex.INCOMING), 0)
        self.assertEqual(self.graph["B"].get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph["B"].get_number_of_edges(where_to=Vertex.INCOMING), 2)
        self.assertEqual(self.graph["C"].get_number_of_edges(where_to=Vertex.OUTGOING), 0)
        self.assertEqual(self.graph["C"].get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph["D"].get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph["D"].get_number_of_edges(where_to=Vertex.INCOMING), 1)

        self.graph.remove_node("D")

        self.assertEqual(self.graph["A"].get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph["A"].get_number_of_edges(where_to=Vertex.INCOMING), 0)
        self.assertEqual(self.graph["B"].get_number_of_edges(where_to=Vertex.OUTGOING), 1)
        self.assertEqual(self.graph["B"].get_number_of_edges(where_to=Vertex.INCOMING), 1)
        self.assertEqual(self.graph["C"].get_number_of_edges(where_to=Vertex.OUTGOING), 0)
        self.assertEqual(self.graph["C"].get_number_of_edges(where_to=Vertex.INCOMING), 1)

        with self.assertRaises(KeyError):
            self.graph["D"]

        with self.assertRaises(KeyError):
            self.graph.remove_node("D")
true_G = data_frame['G'].values
# Modify the distribution to move away from desired and lets see if it can recover
P_DI_G = np.array([
                   [[0.3,0.4,0.3],[0.25,0.5,0.25],[0.1,0.1,0.8]],
                   [[0.4,0.4,0.2],[0.3,0.4,0.3],[0.25,0.35,0.4]],
                   [[0.6,0.2,0.2],[0.7,0.15,0.15],[0.4,0.3,0.3]],
                 ])
P_G_R = np.array([[0.5,0.3,0.2],[0.4,0.3,0.3],[0.2,0.2,0.6]])
'''
    Note: We modified P_DI_G and P_G_R only as these are the parameters that are
    to be tuned. These are the only parameters that include Grade (G) and thus
    these are the only unknown CPD tables as Grade is hidden.
'''

######################## Initialize the Factor Graph ######################
graph = Graph()

# add variable nodes
G = graph.add_var_node('Grade',3) # Grade on GPA scale - 0 - 1.5(0)/ 1.5 - 3(1)/3 - 4(2)
D = graph.add_var_node('Course Difficulty',3) # Easy(0)/ Moderate(1) / Hard(2)
I = graph.add_var_node('Intelligence', 3) # Poor(0) / Average(1) / Exceptional(2)
R = graph.add_var_node('Recommondation Letter', 3) # Bad(0) / Average(1) / Excellent(2)
S = graph.add_var_node('SAT Performance', 3) # Poor(0)/ Average(1) / Excellent(1)

for iteration in range(0,10):
    print 'Iteration :', iteration
    # Expectation Step - Initialize Grade using the sum-product algorithm using Bel-Prop
    # Form the factor graph from the present distribution
    graph.add_factor_node(P_DI_G, D, I, G)
    graph.add_factor_node(P_G_R, G, R)
    graph.add_factor_node(P_I_S, I, S)
    def construct_bp_network(self):
        network = Graph()
        n1 = Node(1)
        n2 = Node(2)
        n3 = Node(3)
        n4 = Node(4)
        n5 = Node(5)
        n6 = Node(6)

        # Add nodes to graph
        network.add_node(n1)
        network.add_node(n2)
        network.add_node(n3)
        network.add_node(n4)
        network.add_node(n5)
        network.add_node(n6)

        # Add edges in zig-zag pattern
        network.add_edge(UndirectedEdge(n1, n2))
        network.add_edge(UndirectedEdge(n2, n3))
        network.add_edge(UndirectedEdge(n3, n4))
        network.add_edge(UndirectedEdge(n4, n5))
        network.add_edge(UndirectedEdge(n5, n6))

        return network
	def setUp(self):
		self.graph = Graph()
		self.graph.load("../json/test_data.json")
from graph.graph import Graph
import numpy as np

graph = Graph()

# add variable nodes
G = graph.add_var_node('Grade',2)
D = graph.add_var_node('Course Difficulty',2)
I = graph.add_var_node('Intelligence', 2)
# connecting factor
P_G_DI = np.array([[[0.5,0.1],[0.9,0.4]],[[0.5,0.9],[0.1,0.6]]])
graph.add_factor_node(P_G_DI, G, D, I)
# run sum-product and get marginals for variables
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']

# reset before altering graph further
graph.reset_all_messages()
################ UPON EXPLICIT CONDITIONING #############

# condition on variables
graph.vars['Intelligence'].condition(1)
graph.vars['Course Difficulty'].condition(0)
# Now compute all marginals using sum product
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']
Example #54
0
n2 = 'Should fulfill commitments'
n12 = 'Bomb detonated with collatoral damage'
n11 = 'Mission ended without collatoral damage'
paths = [(top, n1), (top, n2), (n1, n11), (n1, n12)]
c1 = pydot.graph_from_edges(paths)
c1.write_jpeg('concern_tree1.jpg', prog='dot')

from graph.graph import Graph
G = {'y': {'s': 7, 'v': 6}, 'x': {'y': 2, 'u': 3, 'v': 9}, 's': {'x': 5, 'u': 10}, 'u': {'x': 2, 'v': 1}, 'v': {'y': 4}}
H = {'y': ('s', 'v'), 'x': ('y', 'u', 'v'), 's': ('x', 'u'), 'u': ['x', 'v'], 'v': 'y'} 
I = {
    'ontology': {'choice 1': 7, 'choice 2': 6},
    'choice 1': {'subchc 11': 1, 'subchc 12': 13},
    'choice 2': {'subchc 21': 4, 'subchc 22': 2},
}
G = Graph(G)
H = Graph(H)
I = Graph(I)
dot1 = I.fastGetDot()
dot1.write_jpeg('concern_tree1_dot.jpg', prog='dot')
dot1.write_jpeg('concern_tree1_neat.jpg', prog='neato')
dot2 = H.getDot()
dot2.write_jpeg('concern_tree2.jpg', prog='dot')

from adytum.math.graph import Graph
G = {
    'ontology': {'choice 1': 7, 'choice 2': 6, 'choice 3': 2, 'choice 4': 3},
    'choice 1': {'subchc 11': 1, 'subchc 12': 13},
    'choice 2': {'subchc 21': 4, 'subchc 22': 2},
    'choice 3': {'subchc 31': 10, 'subchc 32': 8, 'subchc 33': 5, 'subchc 22': 1},
    'choice 4': {'subchc 21': 4},
Example #55
0
class TestFlightGraph(TestCase):
  def setUp(self):
    f = open('assets/data/map_data.json', 'r')
    decoded = json.loads(f.read())
    self.g = Graph()
    self.g.build_nodes(decoded['metros'])
    self.g.build_edges(decoded['routes'])
    self.utils = GraphUtils()

  def testInit(self):
    assert (self.g.nodes.get('ALG').name == 'Algiers')

  def testEdgeDestinations(self):
    assert (self.g.nodes.get('CHI').get_destinations() == ['MEX', 'LAX', 'SFO', 'YYZ', 'ATL'])

  def testAddCity(self):
    data = {'code': 'CBS', 'name': 'Test City', 'country': 'US', 'continent': 'Europe',
            'timezone': 0, 'coordinates': 'adssa', 'population': 3, 'region': 'south'}
    print(data)
    self.g.add_node(data)
    assert self.g.get_node_from_code('CBS').name == 'Test City'

  def testAddRoute(self):
    self.g.add_route('TYO', 'YYZ', 2000)
    node = self.g.get_node_from_code('TYO')
    e = Edge('YYZ', 2000)
    bool = False
    for edge in node.edges:
      if e.destination == edge.destination and e.distance == edge.distance:
        bool = True
        break
    assert bool == True

  def testRemoveRoute(self):
    self.g.add_route('TYO', 'YYZ', 2000)
    self.g.remove_route('TYO', 'YYZ')
    node = self.g.get_node_from_code('TYO')
    e = Edge('YYZ', 2000)
    bool = False
    for edge in node.edges:
      if e.destination == edge.destination and e.distance == edge.distance:
        bool = True
        break
    assert bool != True

  def testEditCity(self):
    data = {'code': 'CHI', 'name': 'Test City', 'country': 'US', 'continent': 'Europe',
            'timezone': 0, 'coordinates': 'adssa', 'population': 3, 'region': 'south'}
    self.g.edit_node(data)
    assert self.g.get_node_from_code('CHI').name == 'Test City'
Example #56
0
def buildAtomTraceGraph(ag, tracedAtoms, pairScores = None, weighting = TRACE_GRAPH_WEIGHTS_UNWEIGHTED,
                        sources = None, target = None, minCommonAtoms = 1, skipnodes = set(),
                        reactionDirConstraints = {}):
    g = Graph()
    #ccc = 0
    for u in ag.edges:
        #ccc += 1
        #print ccc, len(ag.edges)
        types = ag.atomTypes[u]
        for v in ag.edges[u]:
            pairs = ag.edges[u][v]

            # Each molecule pair might have multiple rpairs
            for pair in pairs:

                amtypes = ag.atomMapTypes[pair]
                tracedCount = 0
                for type in amtypes:
                    if type in tracedAtoms:
                        tracedCount += 1
               
                if tracedCount < minCommonAtoms: # Does this rpair carry enough traced atoms?
                    continue 

                # Find out the score of this rpair
                if weighting == TRACE_GRAPH_WEIGHTS_RSCORE:
                    assert(pairScores)
                    if pair in pairScores:
                        #print pairScores[pair]
                        score = convScore(pairScores[pair])
                        #score = 1
                    else:
                        score = convScore(NONE_SCORE)
                elif weighting == TRACE_GRAPH_WEIGHTS_NATOMS:
                    #score = 2**(-tracedCount)     # As described in the 03/2009 manuscript
                    score = 1.0 / tracedCount
                    #score = 1.0
                elif weighting == TRACE_GRAPH_WEIGHTS_UNWEIGHTED:
                    score = 1.0
                else:
                    print "unknown TRACE_GRAPH_SCORE: %d" % (TRACE_GRAPH_SCORE)
                    assert(0)

                # Generate edges for each mapped atom pair of this rpair
                amap = ag.atomMap[pair]

                for src in amap:

                    if types[src] not in tracedAtoms:
                        continue

                    tgt = amap[src]

                    srcnode = "%s-%d" % (u, src)
                    tgtnode = "%s-%d" % (v, tgt)
                    fwdpair = "%s_f-%d-%d" % (pair, src, tgt)
                    revpair = "%s_r-%d-%d" % (pair, src, tgt)

                    if srcnode in skipnodes or tgtnode in skipnodes:
                        continue

                    # forward direction
                    g.addEdge(srcnode, fwdpair, score)
                    g.addEdge(fwdpair, tgtnode, 0.0)

                    # reverse direction
                    g.addEdge(tgtnode, revpair, score)
                    g.addEdge(revpair, srcnode, 0.0)

    # Add source and target root nodes, if necessary
    if sources != None:
        for source in sources: # source = mol
            g.addEdge("root", source, 0.0)
            for i in sources[source]: # i = mol-atom
                g.addEdge(source, i)
                if target != None:
                    g.addEdge(i, target, DUMMY_DIST)
    if target != None:
        for i in range(ag.atomCount[target]):
            g.addEdge("%s-%d" % (target, i + 1), target, 0.0)
            g.addEdge(target, "%s-%d" % (target, i + 1), DUMMY_DIST)
    return g