进化算法生成MIDI和弦时遇数组真值歧义错误求解决
问题原因与解决方案
错误原因
你遇到的ValueError是因为get_fitness函数返回的是一个numpy数组而非标量值。由于每个solution[i]是一个和弦(包含多个音符的数组),(average_notes[i] - solution[i]) ** 2会生成对应和弦中每个音符误差的数组,直接将这些数组累加到total_score后,最终返回的total_score是一个数组。当你在if条件中比较两个数组的大小时,会得到一个布尔数组,Python无法直接判断其真假,因此抛出错误。
修复步骤
1. 修正适应度函数,返回标量值
修改get_fitness函数,对每个和弦的误差数组求和,将其转换为标量后再累加到总分中:
import numpy as np def get_fitness(solution, average_notes): total_score = 0 for i in range(len(average_notes)): if average_notes[i] == -1: continue # 对当前和弦的所有音符误差求和,得到标量误差值 chord_error = np.sum((average_notes[i] - solution[i]) ** 2) total_score += chord_error return total_score
2. 修正选择逻辑(可选但重要)
你的选择函数当前逻辑是保留适应度更高的个体,但由于你的适应度是误差平方和,值越小代表个体越优,因此需要反转判断条件,保留适应度更低的个体:
def selection(population, average_notes): bracket = np.random.permutation(population) new_population = [] for i in range(0, len(bracket), 2): fitness_a = get_fitness(bracket[i], average_notes) fitness_b = get_fitness(bracket[i + 1], average_notes) # 保留误差更小(适应度更优)的个体 if fitness_a < fitness_b: new_population.append(bracket[i]) else: new_population.append(bracket[i + 1]) return new_population
说明
- 修正后的
get_fitness会返回一个单一的标量值,代表整个解决方案的总误差,这样在if条件中比较两个标量就不会再触发歧义错误。 - 选择逻辑的修正确保进化过程中保留更优的和弦生成方案,符合进化算法的核心逻辑。
内容的提问来源于stack exchange,提问作者Mostafa Khaled
相关产品推荐
相关产品推荐

