コード例 #1
0
ファイル: node_tests.py プロジェクト: manisero/SemesterIX
    def test_set_color_method(self):
        n1 = Node(color='#')

        n1.set_color('?')

        self.assertEqual('?', n1.color)
        self.assertEqual('#', n1.previous_color)
コード例 #2
0
ファイル: player.py プロジェクト: fras2560/Rampart
 def testShoot(self):
     self.player.cursor.move(0, 10)
     self.player.shoot_mode()
     self.keys[pygame.K_w] = 1
     self.player.player_control(self.keys, self.level)
     self.assertEqual({}, self.player.cannonballs)
     cannon = Node(x=0, y=0, terrain=CANNON,
                   player=1, images=self.terrain)
     cannon.unpaint()
     self.player.add_cannon(cannon)
     self.player.player_control(self.keys, self.level)
     expect = {}
     expect[(0, 0)] = self.player.cannonballs[(0, 0)]
     self.assertEqual(expect, self.player.cannonballs)
コード例 #3
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)
コード例 #4
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
コード例 #5
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
コード例 #6
0
    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)
コード例 #7
0
 def __getDistance(self, start: Node, goal: Node) -> float:
     """Calculates the cost of travelning between 2 nodes. Once done, the 
     value is stored in a matix so A* not needed to be run again."""
     distance = 0.0
     if self.costMatrix[start.get_id(), goal.get_id()] > -1:
         distance = self.costMatrix[start.get_id(), goal.get_id()]
     else:
         seq, distance = pf.a_star_search(self.graph, start, goal)
         self.costMatrix[start.get_id(), goal.get_id()] = distance
         self.costMatrix[goal.get_id(), start.get_id()] = distance
     return distance
コード例 #8
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])
コード例 #9
0
ファイル: base.py プロジェクト: hzfmax/path_planning
def findPathBase(
    solver:     BaseSolver,
    gridMap:    Map,
    start:      tuple,
    finish:     tuple,
    openType:   OpenBase,
    closedType: ClosedBase,
) -> tuple:
    
    k = 0
    
    openList   = openType()
    closedList = closedType()
    
    goalNode = Node(
        i=finish[0], j=finish[1],
        h=0, k=k,
    )
    startNode = Node(
        i=start[0], j=start[1],
        h=solver.h_func(
            start[0], start[1], finish[0], finish[1],
        ), k=k,
    )
    
    openList.addNode(startNode)
    
    while not openList.isEmpty():
        
        currentNode = openList.getBestNode()
        closedList.addNode(currentNode)
        
        if currentNode == goalNode:
            return (True, currentNode, closedList, openList)
        
        for tempNode in solver.getSuccessors(currentNode, goalNode, gridMap, k):
            if not closedList.wasExpanded(tempNode):
                openList.addNode(tempNode)
                
        k += 1
        
    return (False, None, closedList, openList)
コード例 #10
0
ファイル: buildGraph.py プロジェクト: probakilla/ap_foot
def buildGraph(problem, buildWith=ADJACENCY, defenderBuild=TRIANGLE_DEF):
    """
    Build a graph designed for the problem
        :param problem: An instance of the Problem class
        :param buildWith=ADJACENCY: Tells if the graph generated is with
            an adjacency matrix or not
        :param defenderBuild=TRIANGLE_DEF: Tell witch algorithm to use for
            generating the defenders
    """
    nodes = generateDefendersTriangle(
        problem) if defenderBuild == TRIANGLE_DEF else generateDefenders(
            problem)
    graph = GraphDict() if buildWith == DICT else GraphAdjacency()
    minDistance = 2 * problem.robot_radius

    shootings = list()
    for ofenderIdx in range(problem.getNbOpponents()):
        ofender = problem.getOpponent(ofenderIdx)
        for goal in problem.goals:
            for theta in np.arange(0.0, 2 * np.pi, problem.theta_step):
                goalIntersection = goal.kickResult(ofender, theta)
                if goalIntersection is not None:
                    atkNode = Node(ofender, theta)
                    graph.addNode(atkNode)
                    shootings.append({
                        "atk": atkNode,
                        "intersect": goalIntersection
                    })

    for defender in nodes:
        added = None
        for shoot in shootings:
            if getDistance(shoot["atk"].pos, defender) > minDistance:
                shootInterception = segmentCircleIntersection(
                    shoot["atk"].pos, shoot["intersect"], defender,
                    problem.robot_radius)
                if shootInterception is not None:
                    if added is None:
                        added = Node(defender)
                        graph.addNode(added)
                    graph.addEdge(shoot["atk"], added)
    return graph
コード例 #11
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])
コード例 #12
0
def batch_tree_pad(nodes, guard, tree):
    # nodes and tree are in the same position
    lc = [n.lc if n is not None else None for n in nodes]
    mc = [n.mc if n is not None else None for n in nodes]
    rc = [n.rc if n is not None else None for n in nodes]

    if not any(lc):
        return

    idx = len(tree.nodes) + 1

    lex = [n.lex if n is not None else '<PAD>' for n in lc]
    lex = '(' + ' '.join(lex) + ')'
    word_idx = [n.word_idx if n is not None else 3 for n in lc]
    new_lc = TensorNode(Node(lex, idx, ""))
    new_lc.word_idx = torch.LongTensor(word_idx)
    guard.lc = new_lc

    lex = [n.lex if n is not None else '<PAD>' for n in mc]
    lex = '(' + ' '.join(lex) + ')'
    word_idx = [n.word_idx if n is not None else 3 for n in mc]
    new_mc = TensorNode(Node(lex, idx + 1, ""))
    new_mc.word_idx = torch.LongTensor(word_idx)
    guard.mc = new_mc

    lex = [n.lex if n is not None else '<PAD>' for n in rc]
    lex = '(' + ' '.join(lex) + ')'
    word_idx = [n.word_idx if n is not None else 3 for n in rc]
    new_rc = TensorNode(Node(lex, idx + 2, ""))
    new_rc.word_idx = torch.LongTensor(word_idx)
    guard.rc = new_rc

    tree.nodes.update({new_lc.idx: new_lc})
    tree.nodes.update({new_mc.idx: new_mc})
    tree.nodes.update({new_rc.idx: new_rc})

    batch_tree_pad(lc, new_lc, tree)
    batch_tree_pad(mc, new_mc, tree)
    batch_tree_pad(rc, new_rc, tree)
コード例 #13
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 self.color_set is None:
                    color_classes_amount = int(line.strip())

                    if color_classes_amount <= 0:
                        raise Exception('Invalid input format!')

                    self.color_set = range(0, color_classes_amount)
                    continue

                edge = line.strip().split(',')

                if len(edge) != 2:
                    raise Exception('Invalid input format!')

                if edge[0] not in self.id_to_note_mapping:
                    self.id_to_note_mapping[edge[0]] = Node(
                        color=random.choice(self.color_set), node_id=edge[0])

                if edge[1] not in self.id_to_note_mapping:
                    self.id_to_note_mapping[edge[1]] = Node(
                        color=random.choice(self.color_set), node_id=edge[1])

                self.edge_ids.append(edge)

        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
コード例 #14
0
ファイル: graph.py プロジェクト: TitoGrine/IART_Project
    def __shortest_path(self, s, function):
        """ Runs a directed search algorithm
        :param s: starting node
        :param function: the specific search algorithm
        :return finishing node or None if not found
        """

        # Create a queue for BFS
        queue = PriorityQueue()
        queue.put(Node(s))

        # Mark the source node as
        # visited and enqueue it
        n = 0
        solution = None
        finished = False
        while not finished:

            # Dequeue a vertex from
            # queue and print it
            if len(queue.queue) == 0:
                break

            s = queue.get()
            # if s.state.move is not None:
            #     print("expanded " + str(s.state.move.starting_block) + str(s.state.move.move))
            for i in self.adding_edges(s):
                if self.validation_function(i):
                    solution = Node(i, parent=s)
                    finished = True
                    break
                else:
                    function(i, s, queue)
            n += 1
        print("Nodes expanded: " + str(n))
        return solution
コード例 #15
0
    def test_permutate_method_with_banned_transitions(self):
        n1 = Node(1, 18)
        n2 = Node(2, 23)
        n3 = Node(3, 51)
        n1.add_edges([n2])
        n2.add_edges([n3])
        n3.add_edges([n1])

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

        self.assertEqual(4, len(permutations))

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

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

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

        self.assertEqual(1, permutations[3].get_node_of_id(18).color)
        self.assertEqual(1, permutations[3].get_node_of_id(18).previous_color)
        self.assertEqual(2, permutations[3].get_node_of_id(23).color)
        self.assertEqual(2, permutations[3].get_node_of_id(23).previous_color)
        self.assertEqual(2, permutations[3].get_node_of_id(51).color)
        self.assertEqual(3, permutations[3].get_node_of_id(51).previous_color)
コード例 #16
0
ファイル: astar.py プロジェクト: hzfmax/path_planning
    def getSuccessors(
        self: AStar,
        state: Node,
        goal: Node,
        grid: Map,
        k: int,
    ) -> list:

        nodes = [
            Node(
                i=state.i + dx,
                j=state.j + dy,
                h=self.h_func(state.i + dx, state.j + dy, goal.i, goal.j),
                parent=state,
                k=k,
            ) for (dx, dy) in grid.getAllowedMovements(state.i, state.j)
        ]

        return nodes
コード例 #17
0
ファイル: TreeModel.py プロジェクト: mazm13/image2tree
    def greedy_search(self, fc_feat, vocab, max_seq_length):
        h_r, probs_r = self.from_scratch(fc_feat)
        _, 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 = h_r

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

        tree.model = self
        tree.vocab = vocab
        tree.max_seq_length = max_seq_length
        tree.bfs_breed()
        return tree
コード例 #18
0
ファイル: graph.py プロジェクト: SiThuc/EventDetector
    def generateNodes(self, inQueriedTweets):
        tweets = inQueriedTweets
        for tweet in tweets:
            entities = tweet.getEntities()
            #Nodes establishment
            for k in range(0, len(entities)):
                if not entities[k] in self._containedNode:
                    nNode = Node(entities[k], 1)
                    self._mNodes.append(nNode)
                    self._containedNode.add(entities[k])
                    self._buffEntityNode[entities[k]] = nNode
        print("Creating graph's node completed. Number of nodes:%d" %
              self.getNodeCnt())

        # initialize empty neighbor sets for each node
        for i in range(0, len(self._mNodes)):
            outEdges = set()
            inEdges = set()
            self._mOutEdges[self._mNodes[i].getName()] = outEdges
            self._mInEdges[self._mNodes[i].getName()] = inEdges
コード例 #19
0
ファイル: graph.py プロジェクト: TitoGrine/IART_Project
    def __run_graph(self, s, function):
        """ Runs a blind search algorithm
        :param s: starting node
        :param function: the specific blind search algorithm
        :return finishing node or None if not found
        """

        # Mark all the vertices as not visited
        visited = defaultdict(bool)

        # Create a queue for BFS
        queue = [Node(s, heuristics=False)]

        # Mark the source node as
        # visited and enqueue it
        visited[s] = True
        n = 0
        solution = None
        while True:

            # Dequeue a vertex from
            # queue and print it
            if len(queue) == 0:
                break

            s = queue.pop(0)
            for i in self.adding_edges(s):
                self.add_edge(s, i)
            # Get all adjacent vertices of the
            # dequeued vertex s. If a adjacent
            # has not been visited, then mark it
            # visited and enqueue it
            for i in self.graph[s]:
                if self.validation_function(i.state):
                    solution = s
                    break
                elif not visited[i]:
                    function(i, queue, visited, n)
            n += 1
        return solution
コード例 #20
0
    def process_output(self, part, node_map, all_nodes, edges):
        d = self.output.parse(part)
        self.logger.debug(d)

        to_node = Node(d['path'],
                       attr={
                           'type': 'output',
                           'style': 'filled',
                           'fillcolor': 'tomato'
                       })

        source_names = d['idents']

        if not source_names:
            from_node = node_map['last_node']
            edges.append(Edge(from_node, to_node))
        else:
            for source_name in source_names:
                from_node = node_map.get(source_name, node_map['last_node'])
                edges.append(Edge(from_node, to_node))

        all_nodes.append(to_node)
コード例 #21
0
 def test_enforce_integer_idx(self):
     with pytest.raises(TypeError):
         Node("not an index value")
コード例 #22
0
def bikers_from_json(json_data) -> Dict[int, Node]:
    bikers = {}
    keys = json_data.keys()  # type: str
    for i, key in enumerate(keys):
        bikers[i] = Node.node_by_name(json_data[key])
    return bikers
コード例 #23
0
from graph.node import Node
from graph.node import increment

leaf1 = Node("leaf1")
leaf2 = Node("leaf2")

root = Node("root", [leaf1, leaf1, leaf2])

print("graph before increment")
root.show()

# do this increment remotely:
increment(root)

print("graph after increment")
root.show()

コード例 #24
0
def distance(node1: Node, node2: Node) -> float:
    # This function does not give the graph distance, but the Euclidian distance.
    # That is, it's an underestimate of the travel distance, and therefore suitable as a heuristic.
    x1, y1 = node1.coordinates()
    x2, y2 = node2.coordinates()
    return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2))
コード例 #25
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))
コード例 #26
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)
コード例 #27
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)
コード例 #28
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)
コード例 #29
0
    def test_is_coloring_valid_method_positive(self):
        n1 = Node('red')
        n2 = Node('green')
        n3 = Node('green')
        n4 = Node('red')
        n5 = Node('green')
        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])

        coloring_valid = ColoringValidator.is_coloring_valid(n1)

        self.assertTrue(coloring_valid)
コード例 #30
0
ファイル: TreeModelMDSOB.py プロジェクト: mazm13/image2tree
    def _sample(self, fc_feats, vocab, max_seq_length):
        state_a = self.init_state(1)
        xt_a = self.fc_embed(fc_feats)
        state_f = self.init_state(1)
        xt_f = self.init_input(1)

        output, state = self.md_lstm(xt_a, xt_f, state_a, state_f)
        logits = self.logit(output)
        logprobs = F.log_softmax(logits, dim=1)

        logprob, word_idx_r = logprobs.max(dim=1)
        word_idx_r = torch.LongTensor([word_idx_r])

        node_r = TensorNode(Node("", 1, ""))
        node_r.word_idx = word_idx_r
        node_r.word_embed = self.embed(word_idx_r)
        # node_r.h = output, state
        node_r.h = state
        node_r.logprob = logprob.item()

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

        eob_idx = vocab('<EOB>')

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

            if node.word_idx.item() == eob_idx:
                continue

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

            mc = TensorNode(Node("", idx + 1, ""))
            mc.parent = node
            mc.left_brother = lc
            self.complete_node(mc)
            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)
            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)

        for node in tree.nodes.values():
            node.lex = vocab.idx2word[node.word_idx.item()]
            node.label = node.lex + '-' + str(node.idx)
        return tree
コード例 #31
0
 def n1(self):
     return Node(1)
コード例 #32
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))
コード例 #33
0
ファイル: graph.py プロジェクト: TitoGrine/IART_Project
 def add_edge(self, u, v):
     """ Function to add an edge to graph
     :param u: child node
     :param v: parent node
     """
     self.graph[u].append(Node(v, parent=u, heuristics=False))
コード例 #34
0
class GraphUtility(object):
    def __init__(self, nodes, edges):
        self.nu = NetworkXUtility()

        for node in nodes:
            self.nu.add_node(node, **node.attr)

        for edge in edges:
            self.nu.add_edge(edge.from_, edge.to_, **edge.attr)

    def to_gexf_file(self, dest_file):
        return self.nu.to_gexf(dest_file)

    def to_dot_file(self, dest_file):
        return self.nu.to_dot(dest_file)

    def dot_to_graphviz(self, dot_file_path, format='pdf'):
        s = Source.from_file(dot_file_path, format=format)
        s.render(dot_file_path, view=False)


if __name__ == '__main__':
    nodes = []
    edges = []

    nodes.append(Node('a'))
    nodes.append(Node('b'))

    edges.append(Edge('a', 'b'))

    GraphUtility(nodes, edges).to_gexf_file('d:/tmp/tt.gexf')
コード例 #35
0
    def test_permutate_method_with_banned_results(self):
        permutator = FastColorPermutator()
        n1 = Node(color=1, node_id=3)
        n2 = Node(color=1, node_id=5)
        n3 = Node(color=1, node_id=7)
        n4 = Node(color=1, node_id=9)
        n5 = Node(color=1, 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])
        aspiration_criteria = AspirationCriteria([(n2.node_id, 2), (n3.node_id, 2)], -1)

        permutations, best_score = permutator.permutate(n1, [1, 2], aspiration_criteria)

        self.assertEqual(-1, best_score)
        self.assertEqual(1, len(permutations))
        self.assertEqual(n4, permutations[0][0])
        self.assertEqual(2, permutations[0][1])
コード例 #36
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)
コード例 #37
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)
コード例 #38
0
    def test_next_method(self):
        n1 = Node('red', 1)
        n2 = Node('green', 2)
        n3 = Node('green', 3)
        n4 = Node('red', 4)
        n5 = Node('green', 5)
        n6 = Node('red', 6)
        n1.add_edges([n2, n3, n6])
        n2.add_edges([n1, n4])
        n3.add_edges([n1, n4])
        n4.add_edges([n2, n3, n5])
        n5.add_edges([n4])
        n6.add_edges([n1])
        iterator = NodeIterator(n1)

        self.assertEqual(n1, iterator.next())
        self.assertEqual(n2, iterator.next())
        self.assertEqual(n4, iterator.next())
        self.assertEqual(n3, iterator.next())
        self.assertEqual(n5, iterator.next())
        self.assertEqual(n6, iterator.next())
        self.assertRaises(StopIteration, iterator.next)
コード例 #39
0
    def test_search_method_trivially(self):
        search_performer = GraphColoringSearchPerformer(StopCriteria(10, 10), 4)
        n1 = Node('red')
        n2 = Node('green')
        n3 = Node('green')
        n4 = Node('red')
        n5 = Node('green')
        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('red', n1_in_search_result.color)
        self.assertEqual('green', n2_in_search_result.color)
        self.assertEqual('green', n3_in_search_result.color)
        self.assertEqual('red', n4_in_search_result.color)
        self.assertEqual('green', n5_in_search_result.color)
コード例 #40
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])
コード例 #41
0
ファイル: network.py プロジェクト: Jade-yhj/Kartemap
 def add_node(self, node):
     self.node_dict[node] = Node(node)
     self.num_nodes = len(self.node_dict)
     return self.node_dict[node]
コード例 #42
0
ファイル: TreeModelMDSOB.py プロジェクト: mazm13/image2tree
    def beam_search(self,
                    fc_feat,
                    vocab,
                    max_seq_length,
                    global_beam_size,
                    local_beam_size,
                    depth_normalization_factor=0.8):

        (h_r, c_r), logprobs_r = self.from_scratch(fc_feat)
        ys, ix = torch.sort(logprobs_r, 1, True)
        candidates = []
        for c in range(global_beam_size):
            local_logprob = ys[0, c].item()
            candidates.append({'c': ix[0, c], 'p': local_logprob})
        candidate_trees = []

        for c in range(global_beam_size):
            lex = vocab.idx2word[candidates[c]['c'].item()]
            node = TensorNode(Node(lex, 1, ""))
            node.word_idx = candidates[c]['c']
            node.h = h_r.clone(), c_r.clone()
            node.logprob = candidates[c]['p']
            tree = Tree()
            tree.root = node
            tree.logprob = candidates[c]['p']
            tree.nodes.update({node.idx - 1: node})
            candidate_trees.append(tree)

        # for t in range((max_seq_length - 1) // 3):
        completed_sentences = []

        # for t in range(10):
        while True:
            new_candidates = []
            for tree_idx, tree in enumerate(candidate_trees):
                # print(tree.__str__())
                # print([_node.lex for _node in tree.nodes.values()])
                dead_tree = True
                for node in tree.nodes.values():
                    if node.lc is None and node.lex != '<EOB>':
                        dead_tree = False
                if dead_tree:
                    temp_candidate_dict = {
                        'p': tree.logprob,
                        'idx': tree_idx,
                        'dead_tree': True
                    }
                    new_candidates.append(temp_candidate_dict)
                    print("done sentence: {}".format(tree.__str__()))
                    continue

                new_candidates_per_tree = []
                for node in tree.nodes.values():

                    current_depth = node.depth

                    # find L(local size) groups children of this node via chain beam search
                    if node.lc is not None or node.lex == '<EOB>':
                        continue
                    local_candidates = []

                    (hs, cs), logprobs = self.beam_step(
                        state_a=(node.h[0].clone(), node.h[1].clone()),
                        x_a=node.word_idx.clone())
                    ys, ix = torch.sort(logprobs, 1, True)
                    for c in range(local_beam_size):
                        local_logprob = ys[0, c].item()
                        local_candidates.append({
                            'c': ix[0, c],
                            'p': local_logprob,
                            'seq_p': [local_logprob]
                        })

                    # print("input: father ({}), left sibling (None)".format(node.lex))
                    # print("output candidates: {}".format([vocab.idx2word[cdd['c'].item()] for cdd in local_candidates]))

                    m_local_candidates = []
                    for c in range(local_beam_size):
                        (_h, _c), _logprobs = self.beam_step(
                            state_a=(node.h[0].clone(), node.h[1].clone()),
                            x_a=node.word_idx.clone(),
                            state_f=(hs.clone(), cs.clone()),
                            x_f=local_candidates[c]['c'].clone())
                        _ys, _ix = torch.sort(_logprobs, 1, True)
                        for q in range(local_beam_size):
                            local_logprob = _ys[0, q].item()
                            entry = {
                                'c': [local_candidates[c]['c'], _ix[0, q]],
                                'p':
                                local_logprob + local_candidates[c]['p'],
                                'seq_p':
                                local_candidates[c]['seq_p'] + [local_logprob],
                                'state': (_h, _c)
                            }
                            m_local_candidates.append(entry)

                            # print("input: father ({}), left sibling ({})".format(node.lex, vocab.idx2word[local_candidates[c]['c'].item()]))
                            # print("output candidates: {}".format(
                            #     [vocab.idx2word[cdd['c'][1].item()] for cdd in m_local_candidates]))

                    m_local_candidates = sorted(m_local_candidates,
                                                key=lambda x: -x['p'])
                    m_local_candidates = m_local_candidates[:local_beam_size]

                    # print([{'c': cdd['c'], 'p': cdd['p'], 'state_len': len(cdd['state']), 'state_0_len': len(cdd['state'][0])} for cdd in m_local_candidates])

                    r_local_candidates = []
                    for c in range(local_beam_size):
                        f_state = (m_local_candidates[c]['state'][0].clone(),
                                   m_local_candidates[c]['state'][1].clone())
                        (_h, _c), _logprobs = self.beam_step(
                            state_a=(node.h[0].clone(), node.h[1].clone()),
                            x_a=node.word_idx.clone(),
                            state_f=f_state,
                            x_f=m_local_candidates[c]['c'][-1])
                        _ys, _ix = torch.sort(_logprobs, 1, True)
                        for q in range(local_beam_size):
                            local_logprob = _ys[0, q].item()
                            entry = {
                                'c': [
                                    _.clone()
                                    for _ in m_local_candidates[c]['c']
                                ],
                                'p':
                                local_logprob + m_local_candidates[c]['p'],
                                'seq_p':
                                m_local_candidates[c]['seq_p'] +
                                [local_logprob],
                                'state':
                                [(m_local_candidates[c]['state'][0].clone(),
                                  m_local_candidates[c]['state'][1].clone()),
                                 (_h.clone(), _c.clone())]
                            }
                            entry['c'].append(_ix[0, q].clone())
                            r_local_candidates.append(entry)

                    r_local_candidates = sorted(r_local_candidates,
                                                key=lambda x: -x['p'])
                    r_local_candidates = r_local_candidates[:local_beam_size]

                    # print([{'c': cdd['c'], 'p': cdd['p'], 'state_len': len(cdd['state']), 'state_0_len': len(cdd['state'][0])} for cdd in r_local_candidates])

                    for candidate in r_local_candidates:
                        candidate['state'].insert(0, (hs, cs))
                        # this should be proceed after selecting top-L's combination
                        # candidate['p'] += tree.logprob
                        # candidate['idx'] = tree_idx
                        candidate['fid'] = node.idx
                        # candidate['dead_tree'] = False

                    new_candidates_per_tree.append(r_local_candidates)

                # Now we get a list with length of (len(nodes) - len(<EOB>))
                # And the number of combination is local_batch_size ** length

                # inefficient but accurate method, exhaustivity
                # still using beam search

                combination_candidates = []
                for i in range(len(new_candidates_per_tree)):
                    if i == 0:
                        for j in range(local_beam_size):
                            combination_candidates.append({
                                'p':
                                new_candidates_per_tree[i][j]['p'],
                                'seq': [j]
                            })
                        continue
                    new_combination_candidates = []
                    for p in range(local_beam_size):
                        for q in range(local_beam_size):
                            local_combination_logprob = new_candidates_per_tree[
                                i][q]['p'] + combination_candidates[p]['p']
                            local_seq = combination_candidates[p]['seq'] + [q]
                            new_combination_candidates.append({
                                'p': local_combination_logprob,
                                'seq': local_seq
                            })
                    new_combination_candidates = sorted(
                        new_combination_candidates, key=lambda x: -x['p'])
                    new_combination_candidates = new_combination_candidates[:
                                                                            local_beam_size]
                    combination_candidates = new_combination_candidates

                # print(len(combination_candidates))

                done_combination_candidates = []
                for i in range(local_beam_size):
                    done_combination_candidates.append({
                        'p':
                        combination_candidates[i]['p'] + tree.logprob,
                        'combination': [
                            new_candidates_per_tree[i][wi] for i, wi in
                            enumerate(combination_candidates[i]['seq'])
                        ],
                        'dead_tree':
                        False,
                        'idx':
                        tree_idx
                    })

                new_candidates.extend(done_combination_candidates)

            # print(len(new_candidates))
            new_candidates = sorted(new_candidates, key=lambda x: -x['p'])
            new_candidates = new_candidates[:global_beam_size]

            new_candidate_trees = []
            for _candidate in new_candidates:
                if _candidate['dead_tree']:
                    new_candidate_trees.append(
                        candidate_trees[tree_idx].clone())
                    continue

                tree_idx = _candidate['idx']
                new_tree = candidate_trees[tree_idx].clone()

                for candidate in _candidate['combination']:
                    f_node = new_tree.nodes[candidate['fid'] - 1]

                    # print(f_node.__repr__())
                    idx = len(new_tree.nodes) + 1
                    lex = [vocab.idx2word[_.item()] for _ in candidate['c']]
                    seq_p = candidate['seq_p']

                    lc = TensorNode(Node(lex[0], idx, ""))
                    lc.parent = f_node
                    lc.word_idx = candidate['c'][0].clone()
                    f_node.lc = lc
                    lc.depth = f_node.depth + 1
                    lc.h = tuple_clone(candidate['state'][0])
                    lc.logprob = seq_p[0]

                    mc = TensorNode(Node(lex[1], idx + 1, ""))
                    mc.parent = f_node
                    mc.left_brother = lc
                    mc.word_idx = candidate['c'][1].clone()
                    f_node.mc = mc
                    mc.depth = f_node.depth + 1
                    mc.h = tuple_clone(candidate['state'][1])
                    lc.right_brother = mc
                    mc.logprob = seq_p[1]

                    rc = TensorNode(Node(lex[2], idx + 2, ""))
                    rc.parent = f_node
                    rc.left_brother = mc
                    rc.word_idx = candidate['c'][2].clone()
                    f_node.rc = rc
                    rc.depth = f_node.depth + 1
                    rc.h = tuple_clone(candidate['state'][2])
                    mc.right_brother = rc
                    rc.logprob = seq_p[2]

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

                    new_tree.logprob += candidate['p']

                # with open('beam_search.dot', 'w') as f:
                #     f.write(new_tree.graphviz())
                #
                # exit(0)
                dead_tree = True
                for node in new_tree.nodes.values():
                    if node.lc is None and node.lex != '<EOB>':
                        dead_tree = False

                if dead_tree:
                    # new_tree.logprob /= len(new_tree.nodes)**3.0
                    completed_sentences.append(new_tree)
                else:
                    new_candidate_trees.append(new_tree)

            candidate_trees = new_candidate_trees

            # if len(candidate_trees) == 0:
            #     break
            break_flag = True
            for tree in candidate_trees:
                if len(tree.nodes) < max_seq_length:
                    break_flag = False
            if break_flag:
                break

        return candidate_trees, completed_sentences
コード例 #43
0
    def test_find_permutations_method_emergency_procedure(self):
        search_performer = GraphColoringSearchPerformer(StopCriteria(10, 10), 5)
        n1 = Node('red', 12)
        n2 = Node('red', 21)
        n3 = Node('red', 33)
        n4 = Node('red', 34)
        n5 = Node('red', 72)
        search_performer.memory.add_to_memory(n1, 'black')
        search_performer.memory.add_to_memory(n2, 'black')
        search_performer.memory.add_to_memory(n3, 'black')
        search_performer.memory.add_to_memory(n4, 'black')
        search_performer.memory.add_to_memory(n5, 'black')
        n1.add_edges([n2])
        n2.add_edges([n3])
        n3.add_edges([n4])
        n4.add_edges([n5])

        first_permutations = search_performer.find_permutations(n1, ['black', 'red'])[0]
        first_node, first_node_color = first_permutations[0]
        first_node.set_color(first_node_color)
        search_performer.memory.add_to_memory(first_node, first_node.previous_color)
        second_permutations = search_performer.find_permutations(first_node, ['black', 'red'])[0]
        second_node, second_node_color = second_permutations[0]
        second_node.set_color(second_node_color)
        search_performer.memory.add_to_memory(second_node, second_node.previous_color)
        third_permutations = search_performer.find_permutations(second_node, ['black', 'red'])[0]
        third_node, third_node_color = third_permutations[0]
        third_node.set_color(third_node_color)
        search_performer.memory.add_to_memory(third_node, third_node.previous_color)
        fourth_permutations = search_performer.find_permutations(third_node, ['black', 'red'])[0]
        fourth_node, fourth_node_color = fourth_permutations[0]
        fourth_node.set_color(fourth_node_color)
        search_performer.memory.add_to_memory(fourth_node, fourth_node.previous_color)
        fifth_permutations = search_performer.find_permutations(fourth_node, ['black', 'red'])[0]
        fifth_node, fifth_node_color = fifth_permutations[0]
        fifth_node.set_color(fifth_node_color)

        self.assertEqual(1, len(first_permutations))
        self.assertEqual(12, first_node.node_id)
        self.assertEqual('black', first_node.color)
        self.assertEqual(1, len(second_permutations))
        self.assertEqual(21, second_node.node_id)
        self.assertEqual('black', second_node.color)
        self.assertEqual(1, len(third_permutations))
        self.assertEqual(33, third_node.node_id)
        self.assertEqual('black', third_node.color)
        self.assertEqual(1, len(fourth_permutations))
        self.assertEqual(34, fourth_node.node_id)
        self.assertEqual('black', fourth_node.color)
        self.assertEqual(1, len(fifth_permutations))
        self.assertEqual(72, fifth_node.node_id)
        self.assertEqual('black', fifth_node.color)