1

我正在实施一种算法来解决 8 皇后问题:https ://en.wikipedia.org/wiki/Eight_queens_puzzle

我在尝试遍历种群并通过交叉创建新种群时遇到了问题。问题出在 numpy.random 的选择函数内部。

我的意图是分配populationnewPopulation(第 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

任何想法都非常感谢!

谢谢你。

4

0 回答 0