python 2d array condition - python

i'm working on 8 queen(Genetic Algorithm) program with python 3.4
i use a matrix for keep queens position. but i have an error in sort() function,i dont underestand this error.
please help me ...
my code:
from random import randrange
__author__ = 'Moein'
class NQueen:
NUM_COLS = 8
POPULATIONS = 100
current = [[]]
def __init__(self):
self.current = [[0 for col in range(self.NUM_COLS + 1)] for row in range(self.POPULATIONS)]
# generate first Generation
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
self.current[i][j] = randrange(self.NUM_COLS)
count = 0
condition = True
while condition:
self.crossover()
self.mutation()
self.fitness()
self.sort()
count += 1
print(self.current)
# print(self.current[0])
if self.current[0][self.NUM_COLS] == 0:
condition = False
print(self.current[0])
pass
def fitness(self):
count = 0
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
for x in range(j + 1, self.NUM_COLS):
if self.current[i][j] == self.current[i][x]:
count += 1
if abs(j - x) == abs(self.current[i][j] - self.current[i][x]):
count += 1
self.current[i][self.NUM_COLS] = count
count = 0
pass
def sort(self):
for i in range(0, self.POPULATIONS - 1):
for j in range(i + 1, self.POPULATIONS):
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
for x in range(0, self.NUM_COLS + 1):
temp = self.current[i][x]
self.current[i][x] = self.current
self.current[j][x] = temp
pass
def crossover(self):
_new = [[0 for x in range(self.NUM_COLS + 1)] for x in range(self.POPULATIONS)]
for i in range(0, int(self.POPULATIONS / 2)):
for j in range(0, int(self.NUM_COLS / 2)):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
for j in range(int(self.NUM_COLS / 2), self.NUM_COLS):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
self.current = _new
pass
def mutation(self):
for i in range(0, self.POPULATIONS):
self.current[i][randrange(self.NUM_COLS)] = randrange(self.NUM_COLS)
pass
nQueen = NQueen()
print(nQueen.current[0])
and my error:
Traceback (most recent call last):
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 81, in <module>
nQueen = NQueen()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 27, in __init__
self.sort()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 54, in sort
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
TypeError: unorderable types: list() > int()

self.current[i][x] = self.current
I guess that its this line causing the problem, since
self.current
is a list, so you are setting
self.current[i][x]
to be a list instead of an int. So at this point:
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
when you try to compare those values it might happen, that you compare
an int with a list, which causes the error.
TypeError: unorderable types: list() > int()
Cheers
EDIT:
I just tried it out.
Replacing
self.current
with an int for example 2 prevents the Exception from occurring.

Related

Implement the merge sort algorithm to sort a list of numbers in ascending order

I was trying to implement merge sort in python, here's what I got:
def merge_sort(num_list):
if len(num_list) < 2:
return num_list
else:
mid = len(num_list) // 2
left_list = merge_sort(num_list[: mid])
right_list = merge_sort(num_list[mid: ])
merge(left_list,right_list)
def merge(left_list,right_list):
sorted_list = []
i = j = 0
while (i < len(left_list) and j < len(right_list)):
if left_list[i] <= right_list[j]:
sorted_list.append(left_list[i])
i += 1
else:
sorted_list.append(right_list[j])
j += 1
while(i < len(left_list)):
sorted_list.append(left_list[i])
i += 1
while j < len(right_list):
sorted_list.append(right_list[j])
j += 1
return sorted_list
And I received this error message:
Traceback (most recent call last):
line 34, in <module>
sorted_list = merge_sort(num_list)
line 9, in merge_sort
left_list=merge_sort(num_list[:mid])
line 12, in merge_sort
merge(left_list,right_list)
line 18, in merge
while i<len(left_list) and j<len(right_list):
TypeError: object of type 'NoneType' has no len()
Could somebody help me understand what went wrong in the code and how do I fix that?
You're not returning the merged list in your merge_sort method in your else condition. The following change will make your function work correctly (note the return at the end):
def merge_sort(num_list):
if len(num_list) < 2:
return num_list
mid = len(num_list) // 2
left_list = merge_sort(num_list[: mid])
right_list = merge_sort(num_list[mid: ])
return merge(left_list,right_list)
You forgot to return the merged list at the end of your merge_sort() method. It should be:
def merge_sort(num_list):
if len(num_list) < 2:
return num_list
else:
mid = len(num_list) // 2
left_list = merge_sort(num_list[: mid])
right_list = merge_sort(num_list[mid: ])
return merge(left_list,right_list)
Python returns None when functions exit without a return statement, so when it gets to here:
left_list = merge_sort(num_list[: mid])
right_list = merge_sort(num_list[mid: ])
if merge_sort() doesn't return anything, then it will assign None to those variables. Thus, when it gets to the while loop on line 18 in merge(), left_list and/or right_list are None, which gives you that TypeError when you try to take the length of them.

Index out of Range while counting inversions

I am trying to count the number of inversions in a .txt file given as an argument in a command line input. When ever it gets to line that actually checks if there is an inversion I get a index out of range error. I have tried writing down the place and value in i and j for each loop but I can't figure out how to stop it from going out of range. Here is the error
File "./counting_inversions.py", line 31, in sortAndCountSplit
if (l[i] <= r[j]):
IndexError: list index out of range
Does any one else know a solution?
import argparse
def readFile():
arg_parser = argparse.ArgumentParser(description='Print the given input file.')
arg_parser.add_argument('filename', help='path to a file')
args = arg_parser.parse_args()
with open(args.filename, 'r') as in_file:
n = int(in_file.readline())
vals = [int(val) for val in in_file.readlines()]
return([n, vals])
def sortAndCount(invList):
if (len(invList) == 1):
return (invList, 0)
else:
midpoint = int(len(invList) / 2)
left, lc = sortAndCount(invList[:midpoint])
right, rc = sortAndCount(invList[midpoint:])
arr, sc = sortAndCountSplit(left, right)
return (arr, (lc + rc + sc))
def sortAndCountSplit(l, r):
s = []
i = j = inversions = 0
for k in range((len(l) + len(r))):
if ((i < len(l)) and (l[i] <= r[j]) or j >= len(r)):
s.append(l[i])
i += 1
else:
s.append(r[j])
j += 1
inversions += len(l) - i
return (s, inversions)
def main():
file = readFile()
print(sortAndCount(file[1]))
main()

'return' outside function (making text gradient)

line 18
i'm making a text gradient and cant seem to get this right. here's my code.
what the h*** is wrong with the indention here?
import math
gradient = ('FF24E9', 'F026EC', 'E128F0', 'D22AF3', 'C32CF7', 'A530FE', '8F3EFE', '7A4CFE', '655AFE', '5068FE', '3B76FE')
def gradientmadness(text):
leng = len(text)
output = ''
if leng < 11:
for i in range(0, leng):
output += '<c=#%s>' % gradient[i]
for i in range(0, leng):
output += text[i] + '</c>'
else :
output += '<c=#'
output += '><c=#'.join(gradient)
output += '>'
size = int(math.ceil(leng / 11.0))
for i in range(1, 11 + 1):
output += text[(i - 1) * size: i * size] + '</c>'
return output
gradientmadness.command = "gradient1"
Here is your code with correct formatting :
import math
gradient = ('FF24E9', 'F026EC', 'E128F0', 'D22AF3', 'C32CF7', 'A530FE', '8F3EFE', '7A4CFE', '655AFE', '5068FE', '3B76FE')
def gradientmadness(text):
leng = len(text)
output = ''
if leng < 11:
for i in range(0, leng):
output += '<c=#%s>' % gradient[i]
for i in range(0, leng):
output += text[i] + '</c>'
else :
output += '<c=#'
output += '><c=#'.join(gradient)
output += '>'
size = int(math.ceil(leng / 11.0))
for i in range(1, 11 + 1):
output += text[(i - 1) * size: i * size] + '</c>'
return output
gradientmadness.command = "gradient1"

Why is the code (Python) giving error?

import numpy as np
import matplotlib.pyplot as plt
class Prisoners_Dilemma:
def __init__(self,n,p):
self.n = n
self.p = p
def decision_array(self):
self.dict_dict = {}
for i in range(1,self.n + 1):
self.dict_dict[i] = []
list_list = []
for j in range(1,self.n):
#np.random.seed(j)
self.r = np.random.uniform(0,1)
if self.r > self.p:
q = 0
else:
q = 1
list_list.append(q)
self.dict_dict[i] = list_list
return self.dict_dict
def payoff(self):
self.dict_dict_2 = {}
for i in range(1,self.n + 1):
self.dict_dict_2[i] = []
list_list_2 = []
list_list_3=[]
for j in range(1, i):
list_list_2.append(self.dict_dict[j][i-2])
for j in range(i + 1, self.n + 1):
list_list_2.append(self.dict_dict[j][i-1])
list_list_2_np = np.array(list_list_2)
against_i = np.sum(list_list_2_np)
for_i = np.sum(self.dict_dict[i])
if against_i == 0 and for_i == 0:
payoff_i = 2
elif against_i == 0 and for_i != 0:
payoff_i = 5
elif against_i != 0 and for_i == 0:
payoff_i = -5
else:
payoff_i = -2
list_list_3.append(payoff_i)
self.dict_dict_2[i]=list_list_3
return self.dict_dict_2
def gameplay(self, N, initial_count):
self.counter = initial_count
for i in range(N):
for j in range(1, self.n + 1):
z = self.dict_dict_2[j]
x = np.array(z)
self.counter += np.sum(z)
return self.counter
y = Prisoners_Dilemma(15,0.015)
print (y.gameplay(20,100))
In the above code, the compiler gives the error that instance has no attribute as dict_dict_2 even though its prefixed with self. Moreover, it is perfectly fine with dict_dict. For the sake of completeness I have included the whole code but the problem lies only in payoff and gameplay methods?
dict_dict_2 is only created in payoff(), therefore you must call it before attempting to call gameplay().
The issue is that you are only creating self.dict_dict_2 variable in the payoff function, but in your logic where you are calling gameplay() function , you are not calling the payoff() function before accessing dict_dict_2 , from the looks of it you are not calling that function anywhere at all.
Not sure what dict_dict_2 holds, but the above is the reason why you are getting the issue, maybe you can move the initialization part of dict_dict_2 to __init__() function , though that would not fix the complete issue, since you would still be trying to access dict_dict_1[j] which can error out if j is not a key in dict_dict_2 .

Genetic algorithm suspends in python?

I have implemented a simple genetic algorithm in python - here is the most of the code:
import random
ings = (('w1', 200, 25, 80),
('su1', 50, 55, 150),
('su2', 400, 100, 203),
('sy1', 10, 150, 355),
('sy2', 123, 88, 101),
('sy3', 225, 5, 30),
('sy4', 1, 44, 99),
('sy5', 500, 220, 300))
mutationRate = 0.2
crossoverRate = 0.9
iterations = 100
file = open('D:\\logfile2.txt', 'a')
class Ingredient:
def __init__(self, n, p, mi, ma):
self.name = n
self.price = p
self.min = mi
self.max = ma
self.perc = random.randrange(self.min, self.max)
class Drink:
def __init__(self):
self.ing = [Ingredient(*x) for x in ings]
self.normalize()
self.fitness = self.evaluate()
def normalize(self):
sum = 0
for x in self.ing:
sum += x.perc
if sum < 1000:
offset = 1000 - sum
while not offset == 0:
index = random.randrange(len(self.ing))
val = self.ing[index].max - self.ing[index].perc
threshold = random.randrange(val) if val > 0 else 0
threshold = threshold if threshold < offset else offset
self.ing[index].perc += threshold
offset -= threshold
if sum > 1000:
offset = sum - 1000
while not offset == 0:
index = random.randrange(len(self.ing))
val = self.ing[index].perc - self.ing[index].min
threshold = random.randrange(val) if val > 0 else 0
threshold = threshold if threshold < offset else offset
self.ing[index].perc -= threshold
offset -= threshold
def evaluate(self):
fitness = 0
for x in self.ing:
fitness += x.perc * x.price
return 300000 - fitness
class GeneticAlgorithm:
def __init__(self):
self.drinkList = [Drink() for x in range(8)]
self.pool = []
def mutate(self, index):
ing1, ing2 = random.randrange(8), random.randrange(8)
while ing1 == ing2:
ing2 = random.randrange(8)
ptr = self.drinkList[index].ing
ing1thr = ptr[ing1].max - ptr[ing1].perc
ing2thr = ptr[ing2].perc - ptr[ing2].min
if ing1thr & ing2thr:
change = random.randrange(ing1thr if ing1thr < ing2thr else ing2thr)
ptr[ing1].perc += change
ptr[ing2].perc -= change
def crossover(self, index1, index2):
ing1, ing2 = random.randrange(8), random.randrange(8)
while ing1 == ing2:
ing2 = random.randrange(8)
ptr1 = self.drinkList[index1].ing[:]
ptr2 = self.drinkList[index2].ing[:]
resultIndex1 = random.randrange(len(self.drinkList))
while True:
resultIndex2 = random.randrange(len(self.drinkList))
if not resultIndex1 == resultIndex2:
break
bias = 1 if ptr1[ing1].perc > ptr2[ing1].perc else -1
if bias == 1:
maxChange = min(ptr1[ing1].perc - ptr1[ing1].min,
ptr1[ing2].max - ptr1[ing2].perc,
ptr2[ing1].max - ptr2[ing1].perc,
ptr2[ing2].perc - ptr2[ing2].min)
if maxChange:
change = random.randrange(maxChange)
ptr1[ing1].perc -= change
ptr1[ing2].perc += change
ptr2[ing1].perc += change
ptr2[ing2].perc -= change
self.drinkList[resultIndex1].ing = ptr1[:]
self.drinkList[resultIndex2].ing = ptr2[:]
if bias == -1:
maxChange = min(ptr1[ing1].max - ptr1[ing1].perc,
ptr1[ing2].perc - ptr1[ing2].min,
ptr2[ing1].perc - ptr2[ing1].min,
ptr2[ing2].max - ptr2[ing2].perc)
if maxChange:
change = random.randrange(maxChange)
ptr1[ing1].perc += change
ptr1[ing2].perc -= change
ptr2[ing1].perc -= change
ptr2[ing2].perc += change
self.drinkList[resultIndex1].ing = ptr1[:]
self.drinkList[resultIndex2].ing = ptr2[:]
def roulette(self):
sum = 0
lst = []
for x in self.drinkList:
sum += x.fitness
lst.append(sum)
return lst
def selectOne(self):
selection = random.randrange(self.pool[-1])
index = 0
while selection >= self.pool[index]:
index += 1
return index
def selectCouple(self):
selection1 = random.randrange(self.pool[-1])
index1, index2 = 0, 0
while selection1 >= self.pool[index1]:
index1 += 1
while True:
selection2 = random.randrange(self.pool[-1])
while selection2 >= self.pool[index2]:
index2 += 1
if not index1 == index2: break
return (index1, index2)
def save(self, text):
file.write(text)
for x in self.drinkList:
for y in x.ing:
file.write('min: ' + str(y.min) +
' max: ' + str(y.max) +
' value: ' + str(y.perc) + '\n')
file.write('\n\n')
file.write('\nPopulation fitness: ' +
str(self.calculatePopulationFitness()) +
'\n\n----------------------------------------------\n\n')
def run(self):
file.write("Genetic algorithm\n\nAttributes values:\n" +
"Mutation rate: " + str(mutationRate) +
"\nCrossover rate: " + str(crossoverRate) +
"\nIterations: " + str(iterations) +
"\nIngredients:\n\n" + str(ings))
self.save('\n\n--First population--\n\n')
for cnt in range(iterations):
self.updateFitness()
self.pool = self.roulette()
if random.random() < mutationRate:
index = self.selectOne()
self.showFitness('Mutation in iteration ' + str(cnt))
self.mutate(index)
self.updateFitness()
self.showFitness('Results: ')
if random.random() < crossoverRate:
index1, index2 = self.selectCouple()
self.showFitness('Crossover in iteration ' + str(cnt))
self.crossover(index1, index2)
self.updateFitness()
self.showFitness('Results: ')
self.save('--Final population--\n\n')
def calculatePopulationFitness(self):
sum = 0
for x in self.drinkList:
sum += x.fitness
return sum
def updateFitness(self):
for x in self.drinkList:
x.fitness = x.evaluate()
def showFitness(self, text):
lst = [x.fitness for x in self.drinkList]
all = sum(lst)
file.write(text + '\n' + str(lst) + '||' + str(all) + '\n')
To run it I create an instance of GeneticAlgorithm and launch it through run() method.
The problem is, for low level of iterations the program works more or less fine, but if I set iteration to 50 for example, it seems to fall in infinite loop or suspend at random iteration (the logfile is not updated anymore and the program does not stop - happenes at random iteration). What can be the cause of this?
PS: Can you suggest any changes to the coding style? I'm quite new to python and i don't know all the conventions yet.
I don't completely understand your algorithm but it looks like your code hangs in this loop here:
while True:
selection2 = random.randrange(self.pool[-1])
while selection2 >= self.pool[index2]:
index2 += 1
if not index1 == index2: break
It gets to a point where you never get a value where index1 != index2. This could either indicate you have a mistake somewhere in your code, or that there isn't a situation that meets this condition. You could try putting a cap on the number of iterations of this, for example:
iters = 0
while iters < 5000:
selection2 = random.randrange(self.pool[-1])
while selection2 >= self.pool[index2]:
index2 += 1
iters += 1
if index1 != index2: break
if iters == 5000:
# Deal with not being able to identify a Couple
I know the question is more than a year old. Still I wanted a GA code in python to start with and found the problem.
while True:
selection2 = random.randrange(self.pool[-1])
while selection2 >= self.pool[index2]:
index2 += 1
if not index1 == index2: break
The problem is in this loop. once index2 is found to be equal it is not reset back to zero before trying to find a new value.
while True:
index2 = 0
selection2 = random.randrange(self.pool[-1])
while selection2 >= self.pool[index2]:
index2 += 1
if not index1 == index2: break

Categories