def GA_Version_1(version_path, Runs, generations, parent_pop_init, mating_pop,
                 mutationRate, mutationFunc, passes, instance):
    minFitnessValsOfAllRuns = []
    averageFitnessValsOfAllRuns = []
    for r in range(0, Runs):
        img_path = version_path + "GA instance " + str(instance) + "/Images/"
        initial_population_path = version_path + "GA instance " + str(
            instance) + "/initial_population" + " for Run " + str(r +
                                                                  1) + ".json"
        final_population_path = version_path + "GA instance " + str(
            instance) + "/final_population" + " for Run " + str(r +
                                                                1) + ".json"
        data_path = version_path + "GA instance " + str(instance) + "/"

        random_seed = 100 * (r + 1)
        np.random.seed(random_seed)

        LB = 0
        UB = 1

        initial_image = cv2.imread("binaryhand.png", 0)

        initialize_population(random_seed,
                              initial_image,
                              parent_pop_init,
                              bonus=False)

        with open("CellularAutomata.json", 'r') as f:
            population = json.loads(f.read())

        start_image = np.asarray(population[0])
        final_image = np.asarray(population[0])
        goal_image = np.asarray(population[1])

        save_image(img_path, initial_image, "initial_image", r)
        save_image(img_path, start_image, "start_image", r)
        save_image(img_path, goal_image, "goal_image", r)

        goal_image_binary = grayToBinary(goal_image)
        save_image(img_path, goal_image_binary, "goal_image_binary", r)

        population_used = copy.deepcopy(population[2:])
        save_data(initial_population_path, population_used)

        s = 0
        minFitnessValsPerRun = []
        averageFitnessValsPerRun = []

        diversity_initial = calculateDiversity(population_used)
        #print("Initial diversity= "+str(diversity_initial)+" for Run: "+str(r+1))
        for epoch in range(0, generations):
            parent_pop_size = len(population_used)
            parentPopfitnessVals = evaluatePopulationFitness(
                population_used, parent_pop_size, passes, final_image,
                goal_image_binary)
            [minfitness,
             bestSolution] = solutionTaggerSorter(population_used,
                                                  parentPopfitnessVals,
                                                  parent_pop_size, 1, False)
            minfitness = minfitness[0]
            averagefitness = stat.mean(parentPopfitnessVals)
            matingPool = population_used
            muArgs = {
                "matingPool": matingPool,
                "mutationRate": mutationRate,
                "LB": LB,
                "UB": UB
            }

            mutationStrategy, args = mutationStrategySelector(
                mutationFunc, muArgs)

            lamb = len(matingPool)
            offsprings = mutationFunction(mutationStrategy, args)
            offspringFitnessVals = evaluatePopulationFitness(
                offsprings, lamb, passes, final_image, goal_image_binary)
            newGenPop = crowding(population_used, offsprings,
                                 parentPopfitnessVals, offspringFitnessVals,
                                 parent_pop_size)

            if epoch == 0:
                initFitness = minfitness

            population_used = newGenPop
            averageFitnessValsPerRun.append(averagefitness)
            minFitnessValsPerRun.append(minfitness)
            diversity_current = calculateDiversity(newGenPop)


#            print("diversity of current generation= "+str(diversity_current)+" for Run: "+str(r+1))
#            print("epoch="+str(epoch)+" for Run: "+str(r+1))
#            print("minfitness="+str(minfitness)+" for Run: "+str(r+1))
#            print("\n")
#        print("initminfitness="+str(initFitness)+" for Run: "+str(r+1))
#        print("finalminfitness="+str(minfitness)+" for Run: "+str(r+1))
#        print("\n")
        print(" Run: " + str(r + 1))
        save_values(data_path + "data" + " for Run " + str(r + 1) + ".json", [
            diversity_initial, diversity_current, initFitness, minfitness,
            bestSolution
        ], [
            "Initial diversity", "final diversity", "Initial minimum fitness",
            "final minimum fitness", "Best Solution"
        ])
        save_image(img_path, getFinalImage(start_image, bestSolution, passes),
                   "final_image_binary", r)
        save_data(final_population_path, population_used)

        minFitnessValsOfAllRuns.append(minFitnessValsPerRun)
        averageFitnessValsOfAllRuns.append(averageFitnessValsPerRun)

    stats = progressOfEvolution(Runs, generations, minFitnessValsOfAllRuns,
                                averageFitnessValsOfAllRuns)
    return stats
def GA_Version_1(Runs, generations, parent_pop_init, mating_pop, mutationRate,
                 crossoverRate, mutationFunc, crossoverFunc, passes):
    print("GA version 1 begins here")
    minFitnessValsOfAllRuns = []
    averageFitnessValsOfAllRuns = []
    for r in range(0, Runs):

        random_seed = 100 * (r + 1)
        np.random.seed(random_seed)

        LB = 0
        UB = 1

        initial_image = cv2.imread("binaryhand.png", 0)

        initialize_population(initial_image, parent_pop_init, bonus=False)

        with open("CellularAutomata.json", 'r') as f:
            population = json.loads(f.read())

        start_image = np.asarray(population[0])
        final_image = np.asarray(population[0])
        goal_image = np.asarray(population[1])
        visualize_image(initial_image)
        visualize_image(start_image)
        visualize_image(goal_image)

        goal_image_binary = grayToBinary(goal_image)

        population_used = copy.deepcopy(population[2:])

        s = 0
        minFitnessValsPerRun = []
        averageFitnessValsPerRun = []

        diversity_initial = calculateDiversity(population_used)
        print("Initial diversity= " + str(diversity_initial) + " for Run: " +
              str(r + 1))
        for epoch in range(0, generations):
            parent_pop_size = len(population_used)
            parentPopfitnessVals = evaluatePopulationFitness(
                population_used, parent_pop_size, passes, final_image,
                goal_image_binary)
            [minfitness,
             bestSolution] = solutionTaggerSorter(population_used,
                                                  parentPopfitnessVals,
                                                  parent_pop_size, 1, False)
            minfitness = minfitness[0]
            averagefitness = stat.mean(parentPopfitnessVals)
            matingPool = fitnessProportionateSelectionWithoutScaling(
                population_used, parentPopfitnessVals, s, parent_pop_size,
                mating_pop)

            muArgs = {
                "matingPool": matingPool,
                "mutationRate": mutationRate,
                "LB": LB,
                "UB": UB
            }
            crArgs = {
                "matingPool": matingPool,
                "mating_pop": mating_pop,
                "LB": LB,
                "UB": UB,
                "crossoverRate": crossoverRate
            }

            mutationStrategy, args = mutationStrategySelector(
                mutationFunc, muArgs)
            crossoverStrategy, args1 = crossoverStrategySelector(
                crossoverFunc, crArgs)

            crossoverFunction(crossoverStrategy, args1)
            lamb = len(matingPool)
            offsprings = mutationFunction(mutationStrategy, args)
            offspringFitnessVals = evaluatePopulationFitness(
                offsprings, lamb, passes, final_image, goal_image_binary)
            newGenPop = crowding(population_used, offsprings,
                                 parentPopfitnessVals, offspringFitnessVals,
                                 parent_pop_size)

            if epoch == 0:
                initFitness = minfitness

            population_used = newGenPop
            averageFitnessValsPerRun.append(averagefitness)
            minFitnessValsPerRun.append(minfitness)
            diversity_current = calculateDiversity(newGenPop)
            print("diversity of current generation= " +
                  str(diversity_current) + " for Run: " + str(r + 1))
            print("epoch=" + str(epoch) + " for Run: " + str(r + 1))
            print("minfitness=" + str(minfitness) + " for Run: " + str(r + 1))
        print("initminfitness=" + str(initFitness) + " for Run: " + str(r + 1))
        print("finalminfitness=" + str(minfitness) + " for Run: " + str(r + 1))

        visualize_image(getFinalImage(start_image, bestSolution, passes))

        minFitnessValsOfAllRuns.append(minFitnessValsPerRun)
        averageFitnessValsOfAllRuns.append(averageFitnessValsPerRun)

    stats = progressOfEvolution(Runs, generations, minFitnessValsOfAllRuns,
                                averageFitnessValsOfAllRuns)
    print("GA version 1 ends here")
    return stats
    initialize_population(initial_image, 1, bonus=True)

    with open("CellularAutomata.json", 'r') as f:
        population = json.loads(f.read())

    start_image = np.asarray(population[0])
    goal_image = np.asarray(population[1])

    start_image_binary = grayToBinary(start_image)
    plt.imshow(start_image_binary, cmap="gray")
    plt.show()
    goal_image_binary = grayToBinary(goal_image)

    name = imgs[i][:-4]

    final_image = getFinalImage(start_image, ruleTable, 1)

    psnr_GA[name] = psnr(goal_image, final_image, data_range=255)
    msssim_GA[name] = msssim(goal_image, final_image, MAX=255)
    fitness_GA[name] = evaluatePopulationFitness(ruleTable, 1, 1, start_image,
                                                 goal_image_binary)
    print(psnr_GA)
    print(msssim_GA)
    print(fitness_GA)
    print('myimage')
    save_image(img_path, start_image, "start_" + name)
    save_image(img_path, goal_image, "goal_" + name)
    save_image(img_path, final_image, "final_" + name)

#with open('',)