예제 #1
0
def create_initial_solution(instance, path):

	oligos = instance.oligos
	result_length = instance.result_length
	oligos_len = len(oligos[0].nuc)

	overlaps_pairs = create_overlaps_hash(oligos)

	start = time()
	starting_oligo = choose_starting_oligo(oligos, overlaps_pairs)
	sequence, overlaps = make_starting_solution(starting_oligo, result_length, oligos_len, overlaps_pairs)
	stop = time()

	elapsed_time = round(stop-start,2)

	solution = Solution()
	solution.sequence = sequence
	solution.overlaps = overlaps


	log_to_file (instance, solution, overlaps, sequence, oligos_len, path, elapsed_time, "INITIAL")

	return solution
예제 #2
0
    def transform(solution):
        new_solution = Solution(solution)
        used_oligos = filter(lambda x: x.used, instance.oligos)
        unused_oligos = filter(lambda x: not x.used, instance.oligos)

        def choose_used():
            probability = 0.8 * ((float(len(used_oligos)) / len(used_oligos + unused_oligos)) ** 2)
            dice = random.random()
            return (dice < probability)

        if len(used_oligos) == 0: choose_from = unused_oligos
        elif len(unused_oligos) == 0: choose_from = used_oligos
        else: choose_from = used_oligos if choose_used() else unused_oligos
        chosen_oligo = random.choice(choose_from)

        new_oligo_pos = -1
        # print len(solution.overlaps)
        if len(solution.overlaps) > 0:
            tabu_filtered_overlaps = filter(lambda x: x not in tabu_overlaps, solution.overlaps)
            min_overlap = min(tabu_filtered_overlaps, key=lambda(o1,o2,len,pos): len)
            # Add overlap to tabu list if exceeded limit
            global revert_attempts, max_revert_attempts
            if revert_attempts >= max_revert_attempts:
                revert_attempts = 0
                tabu_overlaps.append(min_overlap)
            left_trailing = -1 * solution.overlaps[0][3]
            right_trailing = -1 * (len(instance.solution.sequence) - solution.overlaps[-1][3] - 2 * oligo_length + solution.overlaps[-1][2])
            o1, o2, overlap_len, o1_pos = min_overlap

            # print overlap_len, left_trailing, right_trailing

            while not (new_oligo_pos in range(0, len(solution.sequence) - oligo_length + 1)):
                if (overlap_len <= min(left_trailing, right_trailing)) or (left_trailing == 0 and right_trailing == 0):
                    # print "Inserting in the middle"
                    # calculate offset defined as distance from the overlap's beginning
                    offset = random.randint(0, oligo_length + o1.overlap(o2)) - oligo_length
                    new_oligo_pos = o1_pos + oligo_length - overlap_len + offset

                elif (overlap_len > left_trailing) and (overlap_len > right_trailing):
                    # print "Inserting in random trailing space"
                    # left_index = random.randint(0, -1 * left_trailing)
                    # right_index = random.randint(len(solution.sequence) - oligo_length - (-1 * right_trailing) + 1, len(solution.sequence) - oligo_length + 1)
                    left_index = 0
                    right_index = len(solution.sequence) - oligo_length
                    new_oligo_pos = random.choice([left_index, right_index])

                elif overlap_len > left_trailing:
                    # print "Inserting in left trailing space"
                    # new_oligo_pos = random.randint(0, -1 * left_trailing)
                    new_oligo_pos = 0

                elif overlap_len > right_trailing:
                    # print "Inserting in right trailing space"
                    # new_oligo_pos = random.randint(len(solution.sequence) - oligo_length - (-1 * right_trailing) + 1, len(solution.sequence) - oligo_length + 1)
                    new_oligo_pos = len(solution.sequence) - oligo_length

                else:
                    new_oligo_pos = random.randint(0, len(solution.sequence) - oligo_length)
        else:
            new_oligo_pos = random.randint(0, len(solution.sequence) - oligo_length)
        # print "Inserting %s at %d" % (chosen_oligo, new_oligo_pos)

        new_oligo_end = new_oligo_pos + (oligo_length - 1)

        # this is some info returned for reverting changes
        old_overlaps = copy(solution.overlaps)
        old_oligo_usage = { oligo: oligo.used_times for oligo in instance.oligos }

        # substitute the newly chosen oligo into the sequence
        new_solution.sequence = solution.sequence[:new_oligo_pos] + chosen_oligo.nuc + solution.sequence[new_oligo_end + 1:]
        # print new_solution.sequence

        # calculate new usage of oligos
        new_overlaps = []
        previous = None
        for oligo in instance.oligos: oligo.used_times = 0
        for i in range(len(new_solution.sequence) - oligo_length + 1):
            nuc = new_solution.sequence[i:i+oligo_length]
            if instance.oligos_dict.has_key(nuc):
                oligo = instance.oligos_dict[nuc]
                oligo.used_times += 1
                if previous == None: # next iteration if it's the first found oligo
                    previous = (oligo, i)
                    continue
                else:
                    prev_oligo, prev_pos = previous
                    overlap_len = oligo_length - i + prev_pos
                    new_overlaps.append((prev_oligo, oligo, overlap_len, prev_pos))
                    previous = (oligo, i)

        x = len(filter(lambda o: o.used, instance.oligos))
        # print x, "used out of", len(instance.oligos)
        if x > len(instance.oligos):
            raw_input()

        new_solution.overlaps = new_overlaps

        return new_solution, old_overlaps, old_oligo_usage

        pass