#http://en.wikipedia.org/wiki/Partition_problem import random import logging logging.basicConfig(level = logging.DEBUG) log = logging.getLogger('partitionselection') CROSSOVER_FRACTION = 0.20 SELECTIVE_FRACTION = 0.50 VARIANTS = 5 POPULATION_SIZE = 20 ITERATIONS = 100 def crossover(a,b): ml = min([len(a), len(b)]) used_indices = [] for i in range(0, int(ml*CROSSOVER_FRACTION)): ra = random.randint(0,ml-1) while ra in used_indices: ra = random.randint(0,ml-1) a[ra], b[ra] = b[ra], a[ra] used_indices.append(ra) return (abs(sum(a)-sum(b)), a, b) def naturalselection(partition_traids): global least_diff new_partition_traids = partition_traids [:] for partition_traid in partition_traids: for i in range(VARIANTS): variant = crossover(*partition_traid[1:]) if variant[0]<least_diff: new_partition_traids.append(variant) new_partition_traids.sort() least_diff = new_partition_traids[0][0] remaining_partition_triads = new_partition_traids\ [:int(POPULATION_SIZE*SELECTIVE_FRACTION)] return remaining_partition_triads if __name__ == '__main__': least_diff = 99999999 import simplejson #assumes that the file named "population" has the raw #population, a python list dumped with simplejson population = simplejson.loads(file('population').read()) n = len(population) partition_a, partition_b = population[:n/2], population[n/2:] partition_traids = [(abs(sum(partition_a)-sum(partition_b)), partition_a, partition_b)] for i in range(ITERATIONS): partition_traids = naturalselection(partition_traids) print least_diff, partition_traids[0]