我正在实施一种算法来解决 8 皇后问题:https ://en.wikipedia.org/wiki/Eight_queens_puzzle
我在尝试遍历种群并通过交叉创建新种群时遇到了问题。问题出在 numpy.random 的选择函数内部。
我的意图是分配population
给newPopulation
(第 50 行),为空newPopulation
(第 53 行),然后下一次迭代将新的 100 个孩子附加到newPopulation
.
它抱怨输入到choice() 的列表的大小不同,即使我在循环之前打印每个右侧的len() 并且它显示它们都是100?
完全错误:
Traceback (most recent call last):
File "test.py", line 44, in <module>
choice1 = choice(population, p=normalFitness)
File "mtrand.pyx", line 1141, in mtrand.RandomState.choice
ValueError: 'a' and 'p' must have same size
这是我的程序:
1 import queensState as qs
2 import numpy as np
3 import random
4 from numpy.random import choice
5
6 def cross(state1,state2):
7 return qs.State([state1.state[0],state1.state[1],state1.state[2],state1.state[3],state2.state[4], state2.state[5],state2.state[6],state2.state[7]])
8
9 #create the initial population
10 population = []
11 newPopulation = []
12 normalFitness = []
13 fitness=np.zeros((100,),dtype=int)
14
15 #step through each state and give
16 #random values to each index in the array
17 for i in range(100):
18 x = []
19 for h in range(8):
20 d = random.randint(1,8)
21 x.append(d)
22 newState = qs.State(x)
23 #append the current state to the population with
24 #the fitness(hash) and the state array
25 population.append(newState)
26
27
28 for i in range(100):
29 totalFitness = 0
30 for n in range(100): #calculate total fitness
31 totalFitness+=population[n].fitness
32
33 fitness[i]=totalFitness
34
35 #initialize the normalized fitness array
36 for x in range(100):
37 normalFitness.append(population[x].fitness/totalFitness)
38
39 print("poplen: ",len(population)," fitlen: ",len(normalFitness)) #this prints "poplen: 100 fitlen: 100"
40 for x in range(100): #this loop is solely for testing
41 print("Pop: ",population[x].state," normalfit: ", normalFitness[x])
42
43 for x in range(100):
44 choice1 = choice(population, p=normalFitness)
45 choice2 = choice(population, p=normalFitness)
46 child = cross(choice1,choice2)
47 newPopulation.append(child)
48 #print("State1: ", choice1.state, " State2: ",choice2.state, "Cross: ", child.state)
49
50 population = newPopulation
51 for x in range(100):
52 print(population[x].state)
53 normalFitness=[]
54 print(len(normalFitness))
55
56 print(fitness)
我认为这可能是因为我将 normalFitness 列表分配给了一个空列表,而不是使用 del。如果我将第 53 行更改为:del normalFitness[:]
它具有相同的行为。
如果需要,这是 QueensState 代码:
1 import numpy as np
2
3 class State:
4 state = np.zeros(8)
5 fitness=0
6 normalizedFitness=0
7
8 def __init__(self, state):
9 self.state = state
10 self.fitness = hash(self)
11
12 #the hash is used to find the fitness
13 #the fitness is defined by the number of non attacking queens
14 def __hash__(self):
15 count = 0
16 attackingQueens = [False,False,False,False,False,False,False,False]
17 for i in range(0,7):
18 x1 = i+1
19 y1 = self.state[i]
20 for j in range(i+1,8):
21 x2 = j+1
22 y2 = self.state[j]
23 if y1==y2 or abs((x1-x2))==abs((y1-y2)):
24 attackingQueens[i]=True
25 attackingQueens[j]=True
26 for attacking in attackingQueens:
27 if not attacking:
28 count+=1
29 self.fitness=count
30 return count
任何想法都非常感谢!
谢谢你。