def show(layout, cost): print "Cost:", cost print print Model.displayLayout(layout) print print
def main(): seed = Layouts.QWERTY firstRow = 1 lastRow = 3 firstCol = (0, 0, 0, 0) lastCol = (len(seed[0])-1-0, len(seed[1])-1-0, len(seed[2])-1-0, len(seed[3])-1-0) firstFreeRow = 1 lastFreeRow = 3 if len(__import__('sys').argv) == 1: print "Building model from text on standard input...", model = Model(stdin.read()) print "Done." return else: print "Loading saved model...", model = Model.load(__import__('sys').argv[1]) print "Done." def mutateLayout(layout): if randint(0,5000) == 0: return choice(Layouts.layouts.values()) def doMutate(l): op = randint(0,10) if op == 0: row = randint(firstFreeRow, lastFreeRow) move = randint(1,4) l[row] = l[row][move:] + l[row][:move] elif op == 1: row = randint(firstFreeRow, lastFreeRow) move = randint(-4,-1) l[row] = l[row][move:] + l[row][:move] elif op == 2: r1 = randint(firstFreeRow, lastFreeRow) r2 = r1-1 if r1 > 1 else 2 c1, c2 = randint(0, min(len(l[r1]), len(l[r2]))), randint(0, min(len(l[r1]), len(l[r2]))) if c1 > c2: c1, c2 = c2, c1 if c1 == c2: c1 = max(c1 - 1, 0); c2 = min(len(l[r1]), len(l[r2])) for c in range(c1, c2): l[r1][c], l[r2][c] = l[r2][c], l[r1][c] else: r1, r2 = randint(firstRow, lastRow), randint(firstRow, lastRow) c1, c2 = randint(firstCol[r1], lastCol[r1]), randint(firstCol[r2], lastCol[r2]) l[r1][c1], l[r2][c2] = l[r2][c2], l[r1][c1] if randint(0,5) > 0: doMutate(l) result = list(list(thing) for thing in layout) doMutate(result) return result def optimizeLayout(score, layout): # return layout # TODO: does this make things better overall? If not, uncomment the above line. layout = [[x for x in l] for l in layout] success = True current = score(layout) while success: success = False for i in range(20): row1 = randint(firstRow, lastRow) col1 = randint(firstCol[row1], lastCol[row1]) row2 = randint(firstRow, lastRow) col2 = randint(firstCol[row2], lastCol[row2]) layout[row1][col1], layout[row2][col2] = layout[row2][col2], layout[row1][col1] nextScore = score(layout) if nextScore < current: current = nextScore success = True else: layout[row1][col1], layout[row2][col2] = layout[row2][col2], layout[row1][col1] return layout results = list(Layouts.layouts.values()) cycles = 40 steps = 15 iterations = 16 population = 1200 children = population / 20 from multiprocessing import Pool pool = Pool(processes=8) import random for cycle in range(cycles): print print "~~~~~~~~~~~~~~~~~" print "Cycle %d of %d..." % (cycle + 1, cycles) print "~~~~~~~~~~~~~~~~~" print for step in range(steps): print "============================" print "Step %d of %d..." % (step + 1, steps) print "============================" print minTemp = (step * 0.8 / steps) * (1. - cycle * 1./cycles) + cycle * 1./cycles maxTemp = ((step + 1) * 0.8 / steps + 0.2) * (1. - cycle * 1./cycles) + cycle * 1./cycles seed, = evolve([random.choice(results)], model, mutateLayout, optimizeLayout, minTemp, maxTemp, processPool=pool, results=1, children=children, population=population, iterations=iterations) print print '============================' print print Model.displayLayout(seed) print print '============================' print results.append(seed) print '~~~~~~~~' print 'Results:' print '~~~~~~~~' print for layout in results: print '============================' print print Model.displayLayout(layout) print print '============================' print print print '~~~~~~~~~~~~~~~~~~~~~' print 'Final optimization...' print '~~~~~~~~~~~~~~~~~~~~~' print final = dict() for seed in dict((Model.displayLayout(l), l) for l in results).values(): layout, = evolve([seed], model, mutateLayout, optimizeLayout, 1., 1., processPool=pool, results=1, children=1000, population=15000, iterations=11) print print Model.displayLayout(layout) print print "========================================" print final[Model.displayLayout(layout)] = layout print print '~~~~~~~~~~~~~~~~' print 'Final results...' print '~~~~~~~~~~~~~~~~' for s, l in sorted((model(l, 1.), l) for l in final.values()): print print '# score = %.4f' % s print "'''" print Model.displayLayout(l) print "''',"