Exemplo n.º 1
0
    def random_strategy(self, chain):
        """
        Put chain in random mode
        """
        random_point = tuple(map(lambda x: x/2, self.box_size))
        while self.is_occupied(random_point) or not Lattice.is_valid_coordinate(random_point):
            random_point = tuple([ random.randrange(0, self.box_size[x]) for x in range(3) ])

        if __debug__: logging.info("Chain start point: %d, %d, %d" % random_point)

        f_monomer = chain.chain[0]
        f_monomer.position = random_point
        f_monomer._open = random_point
        chain[0] = f_monomer

        for idx in range(1, chain._total_length):
            prev_monomer = chain.chain[idx - 1]
            monomer = chain.chain[idx]

            not_found = True
            direction_list = range(0, Lattice.z)
            direction_list_idx = Lattice.z
            while not_found:
                try:
                    direction_idx = random.randrange(0, direction_list_idx)
                except:
                    return False
                direction = direction_list[direction_idx]

                pos = Lattice.get_coordinate(prev_monomer._position, direction)
                open_pos = Lattice.get_open_coordinate(prev_monomer._open, direction)

                if pos in chain.positions_list or  \
                    (self.number_of_chains > 1 and self.is_occupied(pos)):

                    not_found = True
                    direction_list.remove(direction)
                    direction_list_idx -= 1
                else:
                    not_found = False

            monomer.position = pos
            monomer.open_position = open_pos
            #monomer.next_direction = None
            prev_monomer.next_monomer = monomer
            prev_monomer.next_direction = direction

            chain[idx] = monomer
            chain.chain[idx-1] = prev_monomer

        ## rebuild directions
        for idx in range(1, chain._total_length):
            p = chain.chain[idx - 1]
            m = chain.chain[idx]
            d = p.neighbours_position.index(m._position)
            p.next_direction = d
            chain.chain[idx - 1].next_direction = d

        chain.chain[-1].next_direction = 0

        if __debug__: logging.info('Chain inside box, length=%d' % chain.length)
        return chain
Exemplo n.º 2
0
    def greedy_strategy(self, chain):
        """
        Put chain in the box based on a greedy strategy
        """
        random_point = tuple(map(lambda x: x/2, self.box_size))
        while self.is_occupied(random_point) or not Lattice.is_valid_coordinate(random_point):
            random_point = tuple([ random.randrange(0, self.box_size[x]) for x in range(3) ])

        f_monomer0 = chain.chain[0]
        f_monomer0.position = random_point
        f_monomer0._open = random_point
        chain[0] = f_monomer0

        next_direction = random.randrange(0, Lattice.z)

        f_monomer1 = chain.chain[1]
        f_monomer1.position = Lattice.get_coordinate(random_point, next_direction)
        f_monomer1._open = Lattice.get_open_coordinate(random_point, next_direction)
        chain[1] = f_monomer1
        chain[0].next_direction = next_direction

        pos_list = [f_monomer0._position, f_monomer1._position]

        direction_list = range(0, Lattice.z)
        for idx in range(2, chain._total_length):
            prev_monomer = chain.chain[idx - 1]
            monomer = chain.chain[idx]
            min_energy = self.calculate_chain_energy(chain)
            min_pos = None
            min_open_pos = None
            min_dir = 0

            np.random.shuffle(direction_list)

            last_valid_pos = None
            last_valid_open_pos = None

            for dir in direction_list:
                pos = Lattice.get_coordinate(prev_monomer._position, dir)
                open_pos = Lattice.get_open_coordinate(prev_monomer._open, dir)
                if pos in chain.positions_list or \
                    (self.number_of_chains > 1 and self.is_occupied(pos)) or \
                    pos in pos_list:
                    pass
                else:
                    last_valid_pos = pos
                    last_valid_open_pos = open_pos
                    monomer.position = pos
                    monomer._open = open_pos
                    chain[idx] = monomer
                    m_e = self.calculate_chain_energy(chain, slice=[0, idx+1])
                    if min_energy > m_e:
                        min_energy = m_e
                        min_pos = pos
                        min_open_pos = open_pos
                        min_dir = dir

            monomer.position = min_pos if min_pos else last_valid_pos
            monomer._open = min_open_pos if min_open_pos else last_valid_open_pos
            chain[idx] = monomer

            prev_monomer.next_direction = min_dir
            chain[idx - 1] = prev_monomer

        ## rebuild directions
        for idx in range(1, chain._total_length):
            p = chain.chain[idx - 1]
            m = chain.chain[idx]
            d = p.neighbours_position.index(m._position)
            p.next_direction = d
            chain.chain[idx - 1].next_direction = d

        if __debug__: logging.info("Greedy strategy, chain with min energy: %f" % \
                self.calculate_chain_energy(chain))
        return chain