def compute_fitness(G, W, k, P):
    fitness = []
    for p in P:
        parts = create_partitions(G, W, k, p)
        wp = [weight_part(part, W) for part in parts]
        fitness.append((p, max(wp) - min(wp)))
    return fitness
def driver(G, W, k, MAX_GEN):
    n = len(G)
    P = []
    for i in range(2*n):
        temp = range(n)
        random.shuffle(temp)
        P.append(tuple(temp))
    for i in range(MAX_GEN):
        fitness = compute_fitness(G, W, k, P)
        fitness.sort(key=lambda tup: tup[1])
        P = [fitness[j][0] for j in range(n)]
        P = crossover(P, k, n)
    fitness = compute_fitness(G, W, k, P)
    fitness.sort(key=lambda tup: tup[1])
    p = fitness[0][0]
    return create_partitions(G, W, k, p)