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
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