def random_connected_id(print_tries: bool = False):
     from classes.AdjacencyMatrix import AdjacencyMatrix
     adjacency_matrix = AdjacencyMatrix.create_unconnected_matrix()
     while not adjacency_matrix.is_connected():
         new_id = Id.random()
         adjacency_matrix = AdjacencyMatrix.parse(new_id)
         if print_tries:
             print("Trying initial id: " + str(new_id))
     return new_id
Beispiel #2
0
 def mutate(self):
     equal_list = []
     for i in range(len(self.ids)):
         id = self.ids[i]
         mutated_id = id.mutate()
         if mutated_id not in self.ids:
             adjacency_matrix = AdjacencyMatrix.parse(mutated_id)
             if adjacency_matrix.is_connected():
                 score = DegreeAndDiameterCalculator.calculate(
                     adjacency_matrix)
                 if self.is_score_better_than_self(score):
                     new_tree = GeneticTree([mutated_id],
                                            degree=score[0],
                                            diameter=score[1],
                                            score1=score[2] + score[3])
                     self.child = new_tree
                     self.iterations_without_change = 0
                     return new_tree
                 elif self.is_score_equal_than_self(score):
                     equal_list.append(mutated_id)
                     print("  Id " + str(id) + " (" + str(i) + "/" +
                           str(len(self.ids)) +
                           ") mutated to equal score id " + str(mutated_id))
     if len(equal_list) > 0:
         self.ids += equal_list
         self.iterations_without_change = 0
     else:
         self.iterations_without_change += 1
     return self
def recursively_create_ids(i: int, symbols_to_check: list, symbols: list):
    global num, results, test
    for symbol in symbols_to_check:
        if Symbol.check(symbols[-1] if len(symbols) > 0 else None, symbol):
            symbols.append(symbol)
            if i + 1 == wanted_length:
                id = Id(symbols)
                if id.check() is None:
                    # print(str(id))
                    adj_matrix = AdjacencyMatrix.parse(id)
                    if adj_matrix.is_connected():
                        score = DegreeAndDiameterCalculator.calculate(
                            adj_matrix)
                        score = score[0] + score[1]
                    else:
                        score = ((number_of_nodes - 1) * 2) + (
                            number_of_nodes - adj_matrix.
                            get_number_of_elements_from_biggest_component())
                    for substring_len in range(1, len(id) + 1):
                        for j in range(len(id) - substring_len + 1):
                            chars = str(Id(symbols[j:j + substring_len]))
                            if chars in results:
                                results[chars][0] += 1
                                results[chars][1] += score
                            else:
                                results[chars] = [1, score]
                            # print(" " + str(Id(chars)))
                num += 1
            else:
                recursively_create_ids(
                    i + 1,
                    Symbol.symbols() if i + 2 < wanted_length else
                    Symbol.ending_symbols(), symbols)
            symbols.pop()
Beispiel #4
0
 def __init__(self,
              ids: list,
              child=None,
              degree: int = -1,
              diameter: int = -1,
              score1: int = -1):
     self.ids = ids
     self.child = child
     if degree == -1:
         score = DegreeAndDiameterCalculator.calculate(
             AdjacencyMatrix.parse(ids[0]))
         degree = score[0]
         diameter = score[1]
         score1 = score[2] + score[3]
     self.degree = degree
     self.diameter = diameter
     self.score1 = score1
     self.iterations_without_change = 0
Beispiel #5
0
    def test_is_matrix_connected(self):

        self.assertTrue(AdjacencyMatrix([[0]]).is_connected())
        self.assertTrue(AdjacencyMatrix([[0, 1], [1, 0]]).is_connected())
        self.assertTrue(
            AdjacencyMatrix([[0, 1, 1], [1, 0, 1], [1, 1, 0]]).is_connected())
        self.assertTrue(
            AdjacencyMatrix([[0, 1, 0], [1, 0, 1], [0, 1, 0]]).is_connected())
        self.assertTrue(
            AdjacencyMatrix([[0, 1, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1],
                             [0, 1, 1, 0]]).is_connected())

        self.assertFalse(
            AdjacencyMatrix([[0, 1, 0], [1, 0, 0], [0, 0, 0]]).is_connected())
        self.assertFalse(
            AdjacencyMatrix([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1],
                             [0, 0, 1, 0]]).is_connected())
        self.assertFalse(
            AdjacencyMatrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1],
                             [0, 0, 1, 0]]).is_connected())
Beispiel #6
0
class DegreeAndDiameterCalculatorTest(unittest.TestCase):

    # Custom matrix in order test better the functions:
    #
    #      1---2-----5
    #     /     \    |
    #    0       3---4---6
    #     \     /
    #      9---7---8
    #
    custom = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0],
              [0, 1, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0, 1, 0, 0],
              [0, 0, 0, 1, 0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 1, 1],
              [0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 0]]
    custom = AdjacencyMatrix(custom)

    custom_distance_1_pairs = [[0, 1], [0, 9], [1, 2], [2, 3], [2, 5], [3, 4],
                               [3, 7], [4, 5], [4, 6], [7, 8], [7, 9]]
    custom_distance_2_pairs = [[0, 2], [0, 7], [1, 3], [1, 5], [1, 9], [2, 4],
                               [2, 7], [3, 5], [3, 6], [3, 8], [3, 9], [4, 7],
                               [5, 6], [8, 9]]
    custom_distance_3_pairs = [[0, 3], [0, 5], [0, 8], [1, 4], [1, 7], [2, 6],
                               [2, 8], [2, 9], [4, 8], [4, 9], [5, 7], [6, 7]]
    custom_distance_4_pairs = [[0, 4], [1, 6], [1, 8], [5, 8], [5, 9], [6, 8],
                               [6, 9]]

    @staticmethod
    def triangular_neighbours(matrix):
        len_matrix = len(matrix)
        number_of_neighbours = {}
        for i in range(0, len_matrix):
            number_of_neighbours[i] = sum(matrix[i])
        n = 0
        for x in range(0, len_matrix):
            for y in range(x + 1, len_matrix):
                n += (number_of_neighbours[x] + number_of_neighbours[y]) / 2
        return n

    @staticmethod
    def triangular(n):
        return (n * (n - 1)) / 2

    @staticmethod
    def create_fully_connected_matrix(size):
        matrix = []
        for i in range(size):
            matrix.append([1] * size)
            matrix[i][i] = 0
        return AdjacencyMatrix(matrix)

    def check_paths_list(self, matrix: list, path_list: list, length: int):
        for i in range(len(path_list)):
            self.assert_shortest_path_length(matrix, path_list[i][0],
                                             path_list[i][1], length)

    def assert_shortest_path_length(self, matrix: list, a: int, b: int,
                                    length: int):
        self.assertEqual(
            DegreeAndDiameterCalculator.shortest_path_length_between_two_nodes(
                matrix, a, b), length)

    def create_and_check_fully_connected_matrix(self, size: int):
        matrix = DegreeAndDiameterCalculatorTest.create_fully_connected_matrix(
            size)
        for a in range(3):
            for b in range(a + 1, 3):
                self.assert_shortest_path_length(matrix, a, b, 1)

    def test_shortest_path_length_between_two_nodes(self):

        # On any all-connected matrix, all shortest paths should be length=1
        self.create_and_check_fully_connected_matrix(3)
        self.create_and_check_fully_connected_matrix(6)
        self.create_and_check_fully_connected_matrix(11)

        square = [[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]]

        # On square matrix, the shortest path between opposite nodes should be length=2
        self.check_paths_list(square, [[0, 2], [1, 3]], 2)
        # and length=1 on adjacent nodes
        self.check_paths_list(square, [[0, 1], [0, 3], [1, 2], [2, 3]], 1)

        # On the custom matrix, we first we check adjacent nodes...
        self.check_paths_list(self.custom, self.custom_distance_1_pairs, 1)
        # then we check node pair at distance 2...
        self.check_paths_list(self.custom, self.custom_distance_2_pairs, 2)
        # distance 3...
        self.check_paths_list(self.custom, self.custom_distance_3_pairs, 3)
        # distance 4...
        self.check_paths_list(self.custom, self.custom_distance_4_pairs, 4)
        # and finally distance 5 (the matrix diameter)
        self.assert_shortest_path_length(self.custom, 0, 6, 5)

    def check_calculate_on_fully_connected_matrix(self, size):
        matrix = DegreeAndDiameterCalculatorTest.create_fully_connected_matrix(
            size)
        triangular_size = DegreeAndDiameterCalculatorTest.triangular(size)
        calculate = DegreeAndDiameterCalculator.calculate
        self.assertEqual(
            calculate(matrix),
            [size - 1, 1, (size - 1) * triangular_size, triangular_size])

    def test_calculate(self):

        total_diameter = len(self.custom_distance_1_pairs) + (
            len(self.custom_distance_2_pairs) *
            2) + (len(self.custom_distance_3_pairs) *
                  3) + (len(self.custom_distance_4_pairs) * 4) + 5
        total_degree = DegreeAndDiameterCalculatorTest.triangular_neighbours(
            self.custom)
        calculate = DegreeAndDiameterCalculator.calculate
        self.assertEqual(calculate(self.custom),
                         [3, 5, total_degree, total_diameter])
Beispiel #7
0
 def create_fully_connected_matrix(size):
     matrix = []
     for i in range(size):
         matrix.append([1] * size)
         matrix[i][i] = 0
     return AdjacencyMatrix(matrix)