给我一段基于遗传算法的编曲代码
时间: 2023-12-13 17:05:27 浏览: 26
以下是一个基于遗传算法的简单编曲代码示例:
```python
import numpy as np
import scipy.signal as sig
import pyaudio
# Define the target melody
target_melody = np.array([60, 62, 64, 65, 67, 69, 71, 72])
# Define the population size and number of generations
pop_size = 50
num_gen = 100
# Define the range of possible note values (midi numbers)
note_range = (48, 84)
# Define the fitness function
def fitness(melody):
# Calculate the mean squared error between the target melody and the given melody
mse = np.mean((target_melody - melody)**2)
# Return the fitness as the negative of the mse
return -mse
# Define the mutation function
def mutation(individual):
# Randomly select a note index to mutate
mutate_idx = np.random.randint(len(individual))
# Randomly select a new note value within the note range
new_note = np.random.randint(note_range[0], note_range[1]+1)
# Mutate the selected note
individual[mutate_idx] = new_note
return individual
# Define the crossover function
def crossover(parent1, parent2):
# Randomly select a crossover point
crossover_idx = np.random.randint(len(parent1))
# Create the child by combining the first part of parent1 with the second part of parent2
child = np.concatenate((parent1[:crossover_idx], parent2[crossover_idx:]))
return child
# Initialize the population with random melodies
population = [np.random.randint(note_range[0], note_range[1]+1, size=len(target_melody)) for _ in range(pop_size)]
# Iterate through the generations
for g in range(num_gen):
# Evaluate the fitness of each individual
fitnesses = [fitness(melody) for melody in population]
# Select the best individuals to be parents for the next generation
parents_idx = np.argsort(fitnesses)[-2:]
parents = [population[idx] for idx in parents_idx]
# Create the next generation by crossover and mutation
next_gen = [crossover(parents[0], parents[1]) for _ in range(pop_size-2)]
next_gen = [mutation(individual) if np.random.rand() < 0.1 else individual for individual in next_gen]
next_gen.extend(parents)
population = next_gen
# Play the best melody of the current generation
best_idx = np.argsort(fitnesses)[-1]
best_melody = population[best_idx]
freqs = 2**(best_melody/12)*440
dur = 0.5*np.ones(len(best_melody))
sig_data = np.zeros(int(np.sum(dur)*44100))
idx = 0
for f, d in zip(freqs, dur):
t = np.arange(0, d, 1/44100)
note_data = np.sin(2*np.pi*f*t)
sig_data[idx:idx+len(note_data)] = note_data
idx += len(note_data)
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True)
stream.write(sig_data.astype(np.float32).tobytes())
stream.stop_stream()
stream.close()
p.terminate()
```
该代码使用遗传算法生成适合目标旋律的旋律。每代中,基于音符的MIDI编号,计算每个个体的适应性,选择最好的两个个体作为下一代的父代,使用交叉和变异操作生成下一代。同时,播放当前代中最好的旋律。