def highPeakBestTriple(init_pop):
    best_steerers = []
    for t in range(len(limit_matrices)):
        global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
        best_prob = 1.0
        best_s1 = -1
        best_s2 = -1
        best_s3 = -1
        for s1 in range(len(limit_matrices)):
            for s2 in range(len(limit_matrices)):
                for s3 in range(len(limit_matrices)):
                    dist = np.array(init_pop * limit_matrices[s1] *
                                    limit_matrices[s2] * limit_matrices[s3] *
                                    limit_matrices[t])[0]
                    if dist[global_peak_index] < best_prob:
                        best_prob = dist[global_peak_index]
                        best_s1 = s1
                        best_s2 = s2
                        best_s3 = s3

        print landscapes[t].name + ":", landscapes[
            best_s1].name + " ---> " + landscapes[
                best_s2].name + " ---> " + landscapes[
                    best_s3].name + ", ", best_prob
        best_steerers.append((landscapes[best_s1], landscapes[best_s2],
                              landscapes[best_s3], best_prob))

    return best_steerers
def lowestPeakBestTriple(init_pop):
    best_steerers = []
    for t in range(len(limit_matrices)):
        lowest_peak_index = convertGenotypeToInt(
            landscapes[t].getLowestFitnessPeak())

        best_s1 = -1
        best_s2 = -1
        best_s3 = -1
        best_prob = 0.0
        for s1 in range(len(limit_matrices)):
            for s2 in range(len(limit_matrices)):
                for s3 in range(len(limit_matrices)):
                    dist = np.array(init_pop * limit_matrices[s1] *
                                    limit_matrices[s2] * limit_matrices[s3] *
                                    limit_matrices[t])[0]
                    if dist[lowest_peak_index] > best_prob:
                        best_prob = dist[lowest_peak_index]
                        best_s1 = s1
                        best_s2 = s2
                        best_s3 = s3
        best_steerers.append((landscapes[best_s1], landscapes[best_s2],
                              landscapes[best_s3], best_prob))
        print landscapes[t].name + ":  ", landscapes[
            best_s1].name + " ---> " + landscapes[
                best_s2].name + " ---> " + landscapes[
                    best_s3].name + ", ", best_prob

    return best_steerers
def doubleSteererPercentages(init_pop, allowSAM=True):

    steering_stats = []

    overall_better = 0
    overall_worse = 0
    overall_same = 0

    for t in range(len(limit_matrices)):
        if t != 10 or allowSAM:

            better = 0
            worse = 0
            same = 0

            peak_genotype = landscapes[t].getGlobalPeak()
            peak_genotype_index = convertGenotypeToInt(peak_genotype)
            peak_fitness = landscapes[t].getFitness(peak_genotype)

            for k1 in range(len(limit_matrices)):
                for k2 in range(len(limit_matrices)):
                    steered_pop = (init_pop * limit_matrices[k1] *
                                   limit_matrices[k2] *
                                   limit_matrices[t]).tolist()[0]
                    straight_pop = (init_pop * limit_matrices[t]).tolist()[0]

                    #Floating point arithematic is nasty, check for what is essential equality
                    if np.abs(steered_pop[peak_genotype_index] -
                              straight_pop[peak_genotype_index]) < 10**-15:
                        same += 1
                    elif steered_pop[peak_genotype_index] > straight_pop[
                            peak_genotype_index]:
                        worse += 1
                    elif steered_pop[peak_genotype_index] < straight_pop[
                            peak_genotype_index]:
                        better += 1

            steering_stats.append((better, worse, same))

            pc_better = 100 * float(better) / (better + worse + same)
            pc_worse = 100 * float(worse) / (better + worse + same)
            print landscapes[t].name + ", better:", str(better) + " (" + str(
                pc_better) + "%)", ", worse:", str(worse) + " (" + str(
                    pc_worse) + "%)"

            overall_better += better
            overall_worse += worse
            overall_same += same
            pc_ov_better = 100 * float(overall_better) / (
                overall_better + overall_worse + overall_same)
            pc_ov_worse = 100 * float(overall_worse) / (
                overall_better + overall_worse + overall_same)

    print "Overall, better:", str(overall_better) + " (" + str(
        pc_ov_better) + "%)", ", worse:", str(overall_worse) + " (" + str(
            pc_ov_worse) + "%)"
    return steering_stats
def probLowestPeak(init_pop):
    lowest_pgs_probs = []
    for t in range(len(limit_matrices)):
        dist = np.array(init_pop * limit_matrices[t])[0]
        lpg = landscapes[t].getLowestFitnessPeak()
        lowest_pgs_probs.append(dist[convertGenotypeToInt(lpg)])
        print landscapes[t].name + ":", lowest_pgs_probs[t]

    return lowest_pgs_probs
def probHighestPeak(init_pop):
    highest_pgs_probs = []
    for t in range(len(limit_matrices)):
        dist = np.array(init_pop * limit_matrices[t])[0]
        global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
        highest_pgs_probs.append(dist[global_peak_index])
        print landscapes[t].name + ":", highest_pgs_probs[t]

    return highest_pgs_probs
def probHighestPeak(init_pop):
	highest_pgs_probs = []
	for t in range(len(limit_matrices)):
		dist = np.array(init_pop * limit_matrices[t])[0]
		global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
		highest_pgs_probs.append(dist[global_peak_index])
		print landscapes[t].name+":", highest_pgs_probs[t]

	return highest_pgs_probs
def probLowestPeak(init_pop):
	lowest_pgs_probs = []
	for t in range(len(limit_matrices)):
		dist = np.array(init_pop * limit_matrices[t])[0]
		lpg = landscapes[t].getLowestFitnessPeak()
		lowest_pgs_probs.append(dist[convertGenotypeToInt(lpg)])		
		print landscapes[t].name+":", lowest_pgs_probs[t]

	return lowest_pgs_probs
def tripleSteererPercentages(init_pop, allowSAM = True):

	steering_stats = []

	overall_better = 0
	overall_worse = 0
	overall_same = 0

	for t in range(len(limit_matrices)):
		if t!=10 or allowSAM:

			better = 0
			worse = 0
			same = 0

			peak_genotype = landscapes[t].getGlobalPeak()
			peak_genotype_index = convertGenotypeToInt(peak_genotype)
			peak_fitness = landscapes[t].getFitness(peak_genotype)

			for k1 in range(len(limit_matrices)):
				for k2 in range(len(limit_matrices)): 
					for k3 in range(len(limit_matrices)):

						steered_pop = (init_pop * limit_matrices[k1] * limit_matrices[k2] * limit_matrices[k3] * limit_matrices[t]).tolist()[0]
						straight_pop = (init_pop * limit_matrices[t]).tolist()[0]

						#Floating point arithematic is nasty, check for what is essential equality
						if np.abs(steered_pop[peak_genotype_index] - straight_pop[peak_genotype_index]) < 10**-15:
							same+=1
						elif steered_pop[peak_genotype_index] > straight_pop[peak_genotype_index]:
							worse+=1
						elif steered_pop[peak_genotype_index] < straight_pop[peak_genotype_index]:
							better+=1

			steering_stats.append((better,worse,same))


			pc_better = 100*float(better) / (better+worse+same)
			pc_worse  = 100*float(worse) / (better+worse+same)
			print landscapes[t].name+", better:", str(better)+" ("+str(pc_better)+"%)", ", worse:", str(worse)+" ("+str(pc_worse)+"%)"

			overall_better+=better
			overall_worse+=worse
			overall_same+=same
			pc_ov_better = 100*float(overall_better) / (overall_better+overall_worse+overall_same)
			pc_ov_worse = 100*float(overall_worse) / (overall_better+overall_worse+overall_same)



	print "Overall, better:", str(overall_better)+" ("+str(pc_ov_better)+"%)", ", worse:", str(overall_worse)+" ("+str(pc_ov_worse)+"%)"
	return steering_stats
def highPeakBestSingle(init_pop):
	best_steerers = []
	for t in range(len(limit_matrices)):
		global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
		best_prob = 1.0
		best_steerer = -1
		for s in range(len(limit_matrices)):
			dist = np.array(init_pop * limit_matrices[s] * limit_matrices[t])[0]
			if dist[global_peak_index] < best_prob:
				best_prob = dist[global_peak_index]
				best_steerer = s
		best_steerers.append((landscapes[s], best_prob))

		print landscapes[t].name+":", landscapes[best_steerer].name, best_prob
	return best_steerers
def highPeakBestSingle(init_pop):
    best_steerers = []
    for t in range(len(limit_matrices)):
        global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
        best_prob = 1.0
        best_steerer = -1
        for s in range(len(limit_matrices)):
            dist = np.array(init_pop * limit_matrices[s] *
                            limit_matrices[t])[0]
            if dist[global_peak_index] < best_prob:
                best_prob = dist[global_peak_index]
                best_steerer = s
        best_steerers.append((landscapes[s], best_prob))

        print landscapes[t].name + ":", landscapes[
            best_steerer].name, best_prob
    return best_steerers
def highPeakBestDouble(init_pop):
	best_steerers = []
	for t in range(len(limit_matrices)):
		global_peak_index = convertGenotypeToInt(landscapes[t].getGlobalPeak())
		best_prob = 1.0
		best_s1 = -1
		best_s2 = -1
		for s1 in range(len(limit_matrices)):
			for s2 in range(len(limit_matrices)):
				dist = np.array(init_pop * limit_matrices[s1] * limit_matrices[s2] * limit_matrices[t])[0]
				if dist[global_peak_index] < best_prob:
					best_prob = dist[global_peak_index]
					best_s1 = s1
					best_s2 = s2

		print landscapes[t].name+":", landscapes[best_s1].name+" ---> "+landscapes[best_s2].name+", ", best_prob
		best_steerers.append((landscapes[best_s2], landscapes[best_s2], best_prob))
	return best_steerers
def lowestPeakBestDouble(init_pop):
	best_steerers = [] 
	for t in range(len(limit_matrices)):
		lowest_peak_index = convertGenotypeToInt(landscapes[t].getLowestFitnessPeak())

		best_s1 = -1
		best_s2 = -1
		best_prob = 0.0
		for s1 in range(len(limit_matrices)):
			for s2 in range(len(limit_matrices)):
				dist = np.array(init_pop * limit_matrices[s1] * limit_matrices[s2] * limit_matrices[t])[0]
				if dist[lowest_peak_index] > best_prob:
					best_prob = dist[lowest_peak_index]
					best_s1 = s1
					best_s2 = s2
		best_steerers.append((landscapes[best_s1], landscapes[best_s2], best_prob))
		print landscapes[t].name+":  ", landscapes[best_s1].name+" ---> "+landscapes[best_s2].name+", ", best_prob

	return best_steerers
def lowestPeakBestSingle(init_pop):
	best_steerers = [] 
	for t in range(len(limit_matrices)):
		lowest_peak_index = convertGenotypeToInt(landscapes[t].getLowestFitnessPeak())

		best_steerer = -1
		best_prob = 0.0

		#For each possible steerer
		for s in range(len(limit_matrices)):
			dist = np.array(init_pop * limit_matrices[s] * limit_matrices[t])[0]
			if dist[lowest_peak_index] > best_prob:
				best_prob = dist[lowest_peak_index]
				best_steerer = s
		best_steerers.append((landscapes[best_steerer], best_prob))

		print landscapes[t].name+":", best_steerers[t][0].name, best_steerers[t][1]

	return best_steerers
def lowestPeakBestSingle(init_pop):
    best_steerers = []
    for t in range(len(limit_matrices)):
        lowest_peak_index = convertGenotypeToInt(
            landscapes[t].getLowestFitnessPeak())

        best_steerer = -1
        best_prob = 0.0

        #For each possible steerer
        for s in range(len(limit_matrices)):
            dist = np.array(init_pop * limit_matrices[s] *
                            limit_matrices[t])[0]
            if dist[lowest_peak_index] > best_prob:
                best_prob = dist[lowest_peak_index]
                best_steerer = s
        best_steerers.append((landscapes[best_steerer], best_prob))

        print landscapes[t].name + ":", best_steerers[t][
            0].name, best_steerers[t][1]

    return best_steerers