I’m working on a genetic algorithm for an optimization task where I need to compare different parameters across three functions, including:
- Crossover: One-point (OT), two-point (DT)
- Mutation rates: 0.001 (M1), 0.05 (M2), 0.01 (M3)
- Parent selection: Inbreeding (ID), Outbreeding (AD), Panmixia (PM), Selective breeding (SE)
- Children selection for new population: Normal selection (ZV), Displacement selection (VV), Elite selection(EV)
- Stopping criteria: Fixed iterations (KI), Distance between individuals (VCH), Distance between average fitness values (VF)
The idea is to:
- Compare performance with different combinations of these parameters (using tables).
- Plot graphs showing the minimum function value vs. population number, testing mutation rates, crossover types, parent selection, and population formation.
Issue: I’m struggling to get the algorithm working. The log error from my latest run shows:
{
"name": "error",
"message": "unpack requires a buffer of 4 bytes",
"stack": "---------------------------------------------------------------------------
error Traceback (most recent call last)
Cell In[36], line 2
1 # Run the genetic algorithm
----> 2 best_solution, best_fitness = genetic_algorithm(
3 iterations=100,
4 pop_count=50,
5 num_children=50,
6 crossover_point_count=1,
7 mutation_chance=0.1,
8 inversion_chance=0.05,
9 function_constraints=[(-100, 100), (-100, 100)],
10 fit_f=easom,
11 parent_selection=inbreeding,
12 children_selection=normal_selection,
13 )
14 print(f\"Best solution: {best_solution}, with fitness: {best_fitness}\")
Cell In[35], line 55, in genetic_algorithm(iterations, pop_count, num_children, crossover_point_count, mutation_chance, inversion_chance, function_constraints, fit_f, parent_selection, children_selection)
50 children[i] = apply_mutation_and_inversion(
51 children[i], mutation_chance, inversion_chance
52 )
54 # convert children to float to calculate fitness
---> 55 children = [[binary_to_float(gene) for gene in child] for child in children]
57 # check constraints for children
58 for i in range(len(children)):
Cell In[35], line 55, in <listcomp>(.0)
50 children[i] = apply_mutation_and_inversion(
51 children[i], mutation_chance, inversion_chance
52 )
54 # convert children to float to calculate fitness
---> 55 children = [[binary_to_float(gene) for gene in child] for child in children]
57 # check constraints for children
58 for i in range(len(children)):
Cell In[35], line 55, in <listcomp>(.0)
50 children[i] = apply_mutation_and_inversion(
51 children[i], mutation_chance, inversion_chance
52 )
54 # convert children to float to calculate fitness
---> 55 children = [[binary_to_float(gene) for gene in child] for child in children]
57 # check constraints for children
58 for i in range(len(children)):
Cell In[20], line 26, in binary_to_float(binary_list)
24 # pack these bytes together into binary data, then unpack as a float
25 binary_data = struct.pack(\"B\" * len(byte_values), *byte_values)
---> 26 float_num = struct.unpack(\"f\", binary_data)[0]
28 return float_num
error: unpack requires a buffer of 4 bytes"
}
The error occurs when converting binary data back to float in my binary_to_float function. It seems like the buffer size is incorrect during unpacking. Here’s the problematic part of the code:
def binary_to_float(binary_list):
# convert binary string into bytes
byte_values = [int("".join(str(bit) for bit in binary_list[i:i + 8]), 2) for i in range(0, len(binary_list), 8)]
# pack these bytes together into binary data, then unpack as a float
binary_data = struct.pack("B" * len(byte_values), *byte_values)
float_num = struct.unpack("f", binary_data)[0] # ERROR: This line raises the unpacking error
return float_num
I’ve already implemented the following steps:
- Fitness functions for the three target functions.
- Binary conversion for float numbers to binary strings and vice versa.
- Crossover, mutation, and inversion operations.
- Parent selection methods, returning two parents based on the selection criteria.
- Children selection methods, including elite selection, but I’m getting errors (e.g., TypeError: unsupported operand type).
I think there are a few things wrong in my implementation, but I can’t pinpoint the exact issue. The code is too large to post here, but I’ve uploaded it here on GitHub.
- What’s causing the "unpack requires a buffer of 4 bytes" error in the
binary_to_floatfunction? - How to correctly put together the genetic algorithm to handle these parameters and move forward with testing?
I’d appreciate any guidance on what could be wrong or suggestions for improving my approach!
float_num = struct.unpack("f", binary_data)[0]but the traceback you posted only shows information about calling the functiongenetic_algorithmbinary_listwhen the functionbinary_to_float(binary_list)bumps into that error. With that information you can reduce your question to like 10% of what it is now as it is no longer dependent on any other code. And maybe you'll even notice what is wrong. I think you can help yourself here more than you've done so far.