Exemple #1
0
    def test_permutate_method_with_multiple_results(self):
        permutator = FastColorPermutator()
        aspiration_criteria = AspirationCriteria(None, None)
        aspiration_criteria.is_permutation_allowed = Mock(return_value=True)
        n1 = Node(color=3, node_id=3)
        n2 = Node(color=3, node_id=5)
        n3 = Node(color=3, node_id=7)
        n4 = Node(color=3, node_id=9)
        n5 = Node(color=3, node_id=10)
        n1.add_edges([n2])
        n2.add_edges([n1, n3])
        n3.add_edges([n2, n4])
        n4.add_edges([n3, n5])
        n5.add_edges([n4])

        permutations, best_score = permutator.permutate(
            n1, [3, 4], aspiration_criteria)

        self.assertEqual(-1, best_score)
        self.assertEqual(3, len(permutations))
        self.assertEqual(n2, permutations[0][0])
        self.assertEqual(4, permutations[0][1])
        self.assertEqual(n3, permutations[1][0])
        self.assertEqual(4, permutations[1][1])
        self.assertEqual(n4, permutations[2][0])
        self.assertEqual(4, permutations[2][1])
Exemple #2
0
    def test_is_in_short_term_memory_method(self):
        self.memory.clear_memory()

        n1 = Node(1, 18)
        n2 = Node(2, 33)
        n3 = Node(3, 52)
        n4 = Node(4, 89)

        self.memory.add_to_memory(n1, 2)
        n1_2_in_memory_first = self.memory.is_in_short_term_memory(n1, 2)
        self.memory.add_to_memory(n2, 3)
        n1_2_in_memory_second = self.memory.is_in_short_term_memory(n1, 2)
        n2_3_in_memory_first = self.memory.is_in_short_term_memory(n2, 3)
        self.memory.add_to_memory(n3, 4)
        n1_2_in_memory_third = self.memory.is_in_short_term_memory(n1, 2)
        n2_3_in_memory_second = self.memory.is_in_short_term_memory(n2, 3)
        n3_4_in_memory_first = self.memory.is_in_short_term_memory(n3, 4)
        self.memory.add_to_memory(n4, 1)
        n1_2_in_memory_fourth = self.memory.is_in_short_term_memory(n1, 2)
        n2_3_in_memory_third = self.memory.is_in_short_term_memory(n2, 3)
        n3_4_in_memory_second = self.memory.is_in_short_term_memory(n3, 4)
        n4_1_in_memory_first = self.memory.is_in_short_term_memory(n4, 1)

        self.assertTrue(n1_2_in_memory_first)
        self.assertTrue(n1_2_in_memory_second)
        self.assertTrue(n2_3_in_memory_first)
        self.assertTrue(n1_2_in_memory_third)
        self.assertTrue(n2_3_in_memory_second)
        self.assertTrue(n3_4_in_memory_first)
        self.assertFalse(n1_2_in_memory_fourth)
        self.assertTrue(n2_3_in_memory_third)
        self.assertTrue(n3_4_in_memory_second)
        self.assertTrue(n4_1_in_memory_first)
Exemple #3
0
    def test_clone_method(self):
        n1 = Node(1, 123)
        n2 = Node(2, 456)
        n3 = Node(3, 789)
        n4 = Node(4, 333)
        n1.add_edges([n2, n3, n4])
        n2.add_edges([n1, n4])
        n3.add_edges([n1, n4])
        n4.add_edges([n1, n2, n3])

        cloned_n3 = GraphCloner.clone(n3)
        cloned_n1 = cloned_n3.get_node_of_id(123)
        cloned_n2 = cloned_n3.get_node_of_id(456)
        cloned_n3 = cloned_n3.get_node_of_id(789)
        cloned_n4 = cloned_n3.get_node_of_id(333)

        self.assertNotEqual(n3, cloned_n3)
        self.assertEqual(789, cloned_n3.node_id)
        self.assertEqual(3, cloned_n3.color)
        self.assertEqual(2, len(cloned_n3.edges))
        self.assertNotEqual(n4, cloned_n4)
        self.assertEqual(333, cloned_n4.node_id)
        self.assertEqual(4, cloned_n4.color)
        self.assertEqual(3, len(cloned_n4.edges))
        self.assertNotEqual(n1, cloned_n1)
        self.assertEqual(123, cloned_n1.node_id)
        self.assertEqual(1, cloned_n1.color)
        self.assertEqual(3, len(cloned_n1.edges))
        self.assertNotEqual(n2, cloned_n2)
        self.assertEqual(789, cloned_n3.node_id)
        self.assertEqual(2, cloned_n2.color)
        self.assertEqual(2, len(cloned_n2.edges))
Exemple #4
0
    def test_search_method_with_easy_substitutions(self):
        search_performer = GraphColoringSearchPerformer(
            StopCriteria(10, 10), 3)
        n1 = Node('red')
        n2 = Node('red')
        n3 = Node('red')
        n4 = Node('red')
        n5 = Node('red')
        n1.add_edges([n2, n3])
        n2.add_edges([n1, n4])
        n3.add_edges([n1, n4])
        n4.add_edges([n2, n3, n5])
        n5.add_edges([n4])

        search_result = search_performer.search(n1, ['red', 'green'])
        n1_in_search_result = search_result.get_node_of_id(n1.node_id)
        n2_in_search_result = search_result.get_node_of_id(n2.node_id)
        n3_in_search_result = search_result.get_node_of_id(n3.node_id)
        n4_in_search_result = search_result.get_node_of_id(n4.node_id)
        n5_in_search_result = search_result.get_node_of_id(n5.node_id)

        self.assertIsNotNone(n1_in_search_result)
        self.assertIsNotNone(n2_in_search_result)
        self.assertIsNotNone(n3_in_search_result)
        self.assertIsNotNone(n4_in_search_result)
        self.assertIsNotNone(n5_in_search_result)
        self.assertEqual('green', n1_in_search_result.color)
        self.assertEqual('red', n2_in_search_result.color)
        self.assertEqual('red', n3_in_search_result.color)
        self.assertEqual('green', n4_in_search_result.color)
        self.assertEqual('red', n5_in_search_result.color)
Exemple #5
0
    def greedy_search(self, fc_feats, att_feats, vocab, max_seq_length):
        fc_feats, att_feats, p_att_feats = self._prepare_feature(
            fc_feats, att_feats)

        states_r, probs_r = self.from_scratch(fc_feats, att_feats)
        logprob, word_idx_r = probs_r.max(dim=1)
        lex_r = vocab.idx2word[word_idx_r.item()]
        word_idx_r = torch.LongTensor([word_idx_r])

        node_r = TensorNode(Node(lex_r, 1, ""))
        node_r.word_idx = word_idx_r
        node_r.h = states_r
        node_r.logprob = logprob.item()

        tree = Tree()
        tree.root = node_r
        tree.nodes.update({node_r.idx - 1: node_r})

        queue = Queue()
        queue.put(tree.root)
        # print(tree.root.lex)
        while not queue.empty() and len(tree.nodes) <= max_seq_length:
            node = queue.get()

            if node.lex == '<EOB>':
                continue

            idx = len(tree.nodes) + 1
            lc = TensorNode(Node("", idx, ""))
            lc.parent = node
            self.complete_node(lc, vocab, att_feats, p_att_feats)
            node.lc = lc
            lc.depth = node.depth + 1

            mc = TensorNode(Node("", idx + 1, ""))
            mc.parent = node
            mc.left_brother = lc
            self.complete_node(mc, vocab, att_feats, p_att_feats)
            node.mc = mc
            mc.depth = node.depth + 1
            lc.right_brother = mc

            rc = TensorNode(Node("", idx + 2, ""))
            rc.parent = node
            rc.left_brother = mc
            self.complete_node(rc, vocab, att_feats, p_att_feats)
            node.rc = rc
            rc.depth = node.depth + 1
            mc.right_brother = rc

            tree.nodes.update({lc.idx - 1: lc})
            tree.nodes.update({mc.idx - 1: mc})
            tree.nodes.update({rc.idx - 1: rc})

            queue.put(lc)
            queue.put(mc)
            queue.put(rc)

        return tree
Exemple #6
0
    def test_permutate_method(self):
        n1 = Node(1, node_id=1)
        n2 = Node(2, node_id=2)
        n3 = Node(3, node_id=3)
        n1.add_edges([n2])
        n2.add_edges([n3])
        n3.add_edges([n1])

        permutations = self.color_permutator.permutate(n1, [1, 2, 3])

        self.assertEqual(6, len(permutations))

        self.assertEqual(2, permutations[0].get_node_of_id(1).color)
        self.assertEqual(1, permutations[0].get_node_of_id(1).previous_color)
        self.assertEqual(2, permutations[0].get_node_of_id(2).color)
        self.assertEqual(2, permutations[0].get_node_of_id(2).previous_color)
        self.assertEqual(3, permutations[0].get_node_of_id(3).color)
        self.assertEqual(3, permutations[0].get_node_of_id(3).previous_color)

        self.assertEqual(3, permutations[1].get_node_of_id(1).color)
        self.assertEqual(1, permutations[1].get_node_of_id(1).previous_color)
        self.assertEqual(2, permutations[1].get_node_of_id(2).color)
        self.assertEqual(2, permutations[1].get_node_of_id(2).previous_color)
        self.assertEqual(3, permutations[1].get_node_of_id(3).color)
        self.assertEqual(3, permutations[1].get_node_of_id(3).previous_color)

        self.assertEqual(1, permutations[2].get_node_of_id(1).color)
        self.assertEqual(1, permutations[2].get_node_of_id(1).previous_color)
        self.assertEqual(1, permutations[2].get_node_of_id(2).color)
        self.assertEqual(2, permutations[2].get_node_of_id(2).previous_color)
        self.assertEqual(3, permutations[2].get_node_of_id(3).color)
        self.assertEqual(3, permutations[2].get_node_of_id(3).previous_color)

        self.assertEqual(1, permutations[3].get_node_of_id(1).color)
        self.assertEqual(1, permutations[3].get_node_of_id(1).previous_color)
        self.assertEqual(3, permutations[3].get_node_of_id(2).color)
        self.assertEqual(2, permutations[3].get_node_of_id(2).previous_color)
        self.assertEqual(3, permutations[3].get_node_of_id(3).color)
        self.assertEqual(3, permutations[3].get_node_of_id(3).previous_color)

        self.assertEqual(1, permutations[4].get_node_of_id(1).color)
        self.assertEqual(1, permutations[4].get_node_of_id(1).previous_color)
        self.assertEqual(2, permutations[4].get_node_of_id(2).color)
        self.assertEqual(2, permutations[4].get_node_of_id(2).previous_color)
        self.assertEqual(1, permutations[4].get_node_of_id(3).color)
        self.assertEqual(3, permutations[4].get_node_of_id(3).previous_color)

        self.assertEqual(1, permutations[5].get_node_of_id(1).color)
        self.assertEqual(1, permutations[5].get_node_of_id(1).previous_color)
        self.assertEqual(2, permutations[5].get_node_of_id(2).color)
        self.assertEqual(2, permutations[5].get_node_of_id(2).previous_color)
        self.assertEqual(2, permutations[5].get_node_of_id(3).color)
        self.assertEqual(3, permutations[5].get_node_of_id(3).previous_color)
Exemple #7
0
    def test_color_classes_method(self):
        n1 = Node(color='#')
        n2 = Node(color='*')
        n3 = Node(color='#')
        n4 = Node(color='$')
        n1.add_edges([n2, n3, n4])
        n2.add_edges([n1, n3, n4])
        n3.add_edges([n1, n2, n4])
        n4.add_edges([n1, n2, n3])

        color_classes = n1.get_colors_count()

        self.assertEqual(3, color_classes)
Exemple #8
0
    def test_node_count_method(self):
        n1 = Node('a')
        n2 = Node('b')
        n3 = Node('c')
        n4 = Node('d')
        n5 = Node('e')
        n1.add_edges([n2, n5])
        n2.add_edges([n3])
        n3.add_edges([n4])

        node_count = n1.node_count()

        self.assertEqual(node_count, 5)
    def process_core(self, part, node_map, all_nodes, edges, d):
        from_nodes = []
        to_node = None

        for source in d['sources']:
            self.upsert_node(
                node_map, source)  # first, check and upsert if not in node_map
            from_nodes.append(node_map[source])

            if source.startswith('MODULE_'):
                self.connect_module_params(node_map, all_nodes,
                                           edges, node_map[source],
                                           d.get('params', []))

            if '.' in source:
                main_node_name = source.split('.')[0]

                if main_node_name in node_map:
                    edges.append(
                        Edge(node_map[main_node_name], node_map[source]))

        if len(from_nodes) == 0:
            from_nodes.append(node_map['last_node'])

        if d['assign_var']:
            attr = {}
            node_name = d['assign_var']

            if node_name in node_map:
                attr = node_map[node_name].attr

            # for those like PROCESS ... USING
            if 'using' in d:
                attr['using'] = d['using']

            new_node = Node(node_name, attr=attr)
            node_map[node_name] = new_node  # update
            to_node = new_node
        else:
            if not node_map['last_node']:
                new_node = Node("SCOPE_IMPLICIT")
                to_node = new_node
            else:
                to_node = node_map['last_node']

        for from_node in from_nodes:
            edges.append(Edge(from_node, to_node))
            all_nodes.append(from_node)

        all_nodes.append(to_node)
        node_map['last_node'] = to_node
Exemple #10
0
    def test_evaluate_method(self):
        r1 = Node('red')
        r2 = Node('red')
        r3 = Node('red')
        b1 = Node('blue')
        b2 = Node('blue')
        g1 = Node('green')
        g2 = Node('green')
        g3 = Node('green')
        r1.add_edges([g1, r2, b2])
        r2.add_edges([r1, r3, b2])
        r3.add_edges([r2, b1, g2])
        b1.add_edges([r3])
        b2.add_edges([r1, r2, g1, g3])
        g1.add_edges([r1, b2])
        g2.add_edges([r3, g3])
        g3.add_edges([g2, b2])

        evaluated_cost_r1 = CostEvaluator.evaluate(r1,
                                                   ['red', 'blue', 'green'])
        evaluated_cost_g3 = CostEvaluator.evaluate(g3,
                                                   ['blue', 'red', 'green'])

        self.assertEqual(evaluated_cost_r1, evaluated_cost_g3)
        self.assertEqual(-4, evaluated_cost_r1)
Exemple #11
0
    def test_is_graph_connected_method_positive(self):
        n1 = Node()
        n2 = Node()
        n3 = Node()
        n1.add_edges([n2, n3])
        n2.add_edges([n1])
        n3.add_edges([n1])

        n1_graph_connected = ConnectionValidator.is_graph_connected(n1, 3)
        n2_graph_connected = ConnectionValidator.is_graph_connected(n2, 3)
        n3_graph_connected = ConnectionValidator.is_graph_connected(n3, 3)

        self.assertTrue(n1_graph_connected)
        self.assertTrue(n2_graph_connected)
        self.assertTrue(n3_graph_connected)
Exemple #12
0
    def test_evaluate_method_second(self):
        n1 = Node('red')
        n2 = Node('green')
        n3 = Node('green')
        n4 = Node('red')
        n5 = Node('red')
        n1.add_edges([n2, n3])
        n2.add_edges([n1, n4])
        n3.add_edges([n1, n4])
        n4.add_edges([n2, n3, n5])
        n5.add_edges([n4])

        evaluated_cost = CostEvaluator.evaluate(n1, ['red', 'green'])

        self.assertEqual(-7, evaluated_cost)
Exemple #13
0
 def expand_node(self, nodeframes):
     real_children = set()
     for child in self.children:
         real_children.add(nodeframes[child].expand_node(nodeframes))
     return Node(self.name, self.type, real_children, self.neighbors,
                 self.checks, self.fixes, self.states, self.args,
                 self.grouping)
Exemple #14
0
def collate_fn(batch):
    if len(batch[0]) == 3:
        fc_feat, att_feat, trees = zip(*batch)
        fc_feat, att_feat = torch.from_numpy(np.stack(
            fc_feat, axis=0)), torch.from_numpy(np.stack(att_feat, axis=0))
        feats = (fc_feat, att_feat)
    elif len(batch[0]) == 2:
        fc_feat, trees = zip(*batch)
        fc_feat = torch.from_numpy(np.stack(fc_feat, axis=0))
        feats = (fc_feat, )
    else:
        raise ValueError

    root_lex = [tree.root.lex for tree in trees]
    root_lex = '(' + ' '.join(root_lex) + ')'
    root_node = TensorNode(Node(root_lex, 1, ""))
    root_node.word_idx = torch.from_numpy(
        np.stack([tree.root.word_idx for tree in trees], axis=0))

    batch_tree = Tree()
    batch_tree.root = root_node
    batch_tree.nodes.update({0: root_node})

    batch_tree_pad([n.root for n in trees], root_node, batch_tree)
    batch_tree.update()

    return feats + (batch_tree, )
Exemple #15
0
    def test_set_color_method(self):
        n1 = Node(color='#')

        n1.set_color('?')

        self.assertEqual('?', n1.color)
        self.assertEqual('#', n1.previous_color)
Exemple #16
0
 def getSuccessors(
     self:  JPS,
     state: Node,
     goal:  Node,
     grid:  Map,
     k:     int,
 ) -> list:
     
     disallowed = self.getDisallowedDirections(state)
     
     successors = [
         self.getJumpPoint(state.i, state.j, delta[0], delta[1], goal, grid)
         for delta in grid.getAllowedMovements(state.i, state.j)
         if delta not in disallowed
     ]
     
     nodes = [
         Node(
             i      = successor[0],
             j      = successor[1],
             h      = self.h_func(successor[0], successor[1], goal.i, goal.j),
             parent = state,
             k      = k,
         )
         for successor in successors
         if successor is not None
     ]
     
     return nodes
Exemple #17
0
 def test_add_edges(self, w_graph):
     n6 = Node(6)
     w_graph.add_node(n6)
     w_graph.add_edge(5, 6)
     n5 = w_graph.get_by_idx(5)
     assert n6 in w_graph[n5]
     assert n5 not in w_graph[n6]
    def upsert_node(self, node_map, node_name):
        if node_name not in node_map:
            self.logger.info(
                'cannot find node [{}]! Probably source node.'.format(
                    node_name))

            node_map[node_name] = Node(node_name)
Exemple #19
0
    def __init__(self,
                 num_nodes=10,
                 directed=False,
                 weighted=False,
                 num_cycles=0):
        '''
        :param num_nodes: the number of nodes to include in the graph
        :param directed: True if the graph is directed, False otherwise
        :param weighted: True if the graph is weighted, False otherwise
        :param cycles: True if the graph has cycles, False otherwise

        every node will have between 1 and 3 other edges
        '''

        if num_nodes <= 0:
            raise ValueError("must enter a  number of nodes >= 1")

        self._directed = directed
        self._weighted = weighted
        self._num_cycles = num_cycles
        self._graph = []

        available = []
        # default node domain is integers from 0...num_nodes
        node_domain = [x for x in range(num_nodes)]
        for x in sample(node_domain, num_nodes):
            available.append(Node(x))

        self._generate_graph(available)
        if num_cycles > 0:
            self._set_cycles(num_cycles)
Exemple #20
0
    def test_get_node_of_id_method(self):
        n1 = Node(node_id=8)
        n2 = Node(node_id=9)
        n3 = Node(node_id=12)
        n4 = Node(node_id=1)
        n5 = Node(node_id=88)
        n1.add_edges([n5, n3])
        n2.add_edges([n4])
        n3.add_edges([n2, n1])
        n4.add_edges([n1, n5])

        self.assertEqual(n1, n1.get_node_of_id(8))
        self.assertEqual(n2, n1.get_node_of_id(9))
        self.assertEqual(n3, n1.get_node_of_id(12))
        self.assertEqual(n4, n1.get_node_of_id(1))
        self.assertEqual(n5, n1.get_node_of_id(88))
 def push(self, value):
     '''
     push method to add element to stack
     '''
     node = Node(value)
     node.next = self.top
     self.top = node
    def setNodesFromValuesAndConnections(
            self, values: list[T],
            connectionsPointers: list[list[int]]) -> None:
        """Give a Tree object some nodes.

        Args:
            values (List[T]): the value of each node.
            connectionsPointers (List[List[int]]): the connections that each node has.

        Setting a graph's nodes from provided data and connections:
        >>> maze = Graph[None]()
        >>> maze.setNodesFromValuesAndConnections([
        ...     None,
        ...     None,
        ...     None,
        ...     None,
        ...     None,
        ... ], [
        ...     [1, 4],
        ...     [0, 4],
        ...     [4, 3],
        ...     [2, 4],
        ...     [0, 1, 2, 3]
        ... ])
        >>> maze
        ['None -> [1, 4]', 'None -> [0, 4]', 'None -> [4, 3]', 'None -> [2, 4]', 'None -> [0, 1, 2, 3]']
        """

        for index, thisValue in enumerate(values):
            # make new `Node` with this value's data and left and right pointers
            thisNode: Node[T] = Node(data=thisValue,
                                     connections=connectionsPointers[index])
            self.__nodes.append(thisNode)  # append new node to `self.nodes`
Exemple #23
0
 def __a_star(v, u, queue):
     """ Runs the A* algorithm
     :param v: the current node
     :param u: the parent node
     :param queue: the current run's priority queue
     """
     queue.put(Node(v, parent=u, heuristics=True))
Exemple #24
0
 def __uniform_cost(v, u, queue):
     """" Runs the uniform cost algorithm
     :param v: the current node
     :param u: the parent node
     :param queue: the current run's priority queue
     """
     queue.put(Node(v, parent=u, heuristics=False))
Exemple #25
0
def create_node(idx, lex, word_idx, h, depth):
    node = TensorNode(Node(lex, idx, ""))
    node.label = lex + '-' + str(idx)
    node.word_idx = word_idx.clone()
    node.h = (h[0].clone(), h[1].clone())
    node.depth = depth
    return node
Exemple #26
0
    def clone_nodes(root_node):
        cloned_nodes = {}

        for node in root_node.iterator():
            cloned_node = Node(node.color, node.node_id)
            cloned_nodes[node] = cloned_node

        return cloned_nodes
Exemple #27
0
    def read_input_graph_and_color_set(self, file_name):
        self.reset_input()

        with open(file_name, 'r') as graph_file:
            for line in graph_file:
                if len(line) > 0:
                    first_character = line.strip()[0]

                    if first_character == 'p':
                        match_result = re.match('p edge (\d+) (\d+)',
                                                line.strip())

                        if match_result is not None:
                            nodes = int(match_result.groups()[0])
                            self.color_set = range(0, nodes)
                        else:
                            raise IOError('Invalid input format!')

                    elif first_character == 'e':
                        match_result = re.match('e (\d+) (\d+)', line.strip())

                        if match_result is not None:
                            first_edge_id, second_edge_id = match_result.groups(
                            )[0], match_result.groups()[1]

                            if first_edge_id not in self.id_to_note_mapping:
                                self.id_to_note_mapping[first_edge_id] = Node(
                                    color=random.choice(self.color_set),
                                    node_id=first_edge_id)
                            if second_edge_id not in self.id_to_note_mapping:
                                self.id_to_note_mapping[second_edge_id] = Node(
                                    color=random.choice(self.color_set),
                                    node_id=second_edge_id)
                        else:
                            raise IOError('Invalid input format!')

                        self.edge_ids.append([first_edge_id, second_edge_id])

        if len(self.id_to_note_mapping) == 0:
            raise Exception('Invalid input format!')

        for edge in self.edge_ids:
            self.id_to_note_mapping[edge[0]].add_edges(
                [self.id_to_note_mapping[edge[1]]])

        return self.id_to_note_mapping.items()[0][1], self.color_set
    def find_latest_node(self, target_name, nodes):
        for node in nodes[::-1]:
            if node.name == target_name:
                return node

        self.logger.warning(
            'cannot find node [{}]! Probably source node.'.format(target_name))

        return Node(target_name)
Exemple #29
0
    def test_permutate_method_with_single_result(self):
        permutator = FastColorPermutator()
        aspiration_criteria = AspirationCriteria(None, None)
        aspiration_criteria.is_permutation_allowed = Mock(return_value=True)
        n1 = Node(color=0, node_id=10)
        n2 = Node(color=0, node_id=20)
        n3 = Node(color=0, node_id=30)
        n1.add_edges([n2])
        n2.add_edges([n1, n3])
        n3.add_edges([n2])

        permutations, best_score = permutator.permutate(
            n1, [0, 7], aspiration_criteria)

        self.assertEqual(-5, best_score)
        self.assertEqual(1, len(permutations))
        self.assertEqual(n2, permutations[0][0])
        self.assertEqual(7, permutations[0][1])
Exemple #30
0
    def test_get_best_score_for_iteration_method_with_long_term_memory_usage(
            self):
        search_performer = GraphColoringSearchPerformer(
            StopCriteria(10, 10), 2)
        n1 = Node(1, 2)
        n2 = Node(1, 5)
        n3 = Node(1, 8)
        search_performer.memory.add_to_memory(n1, 2)
        search_performer.memory.add_to_memory(n2, 3)
        search_performer.memory.add_to_memory(n3, 4)
        search_performer.memory.add_to_memory(n1, 5)
        search_performer.memory.add_to_memory(n3, 6)
        search_performer.memory.add_to_memory(n1, 7)

        best_score_for_iteration = search_performer.get_best_permutation_for_iteration(
            [(n1, 3), (n2, 3), (n3, 3)])

        self.assertEqual(3, best_score_for_iteration[1])
        self.assertEqual(n2, best_score_for_iteration[0])