0

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:

  1. Compare performance with different combinations of these parameters (using tables).
  2. 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:

  1. Fitness functions for the three target functions.
  2. Binary conversion for float numbers to binary strings and vice versa.
  3. Crossover, mutation, and inversion operations.
  4. Parent selection methods, returning two parents based on the selection criteria.
  5. 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.

  1. What’s causing the "unpack requires a buffer of 4 bytes" error in the binary_to_float function?
  2. 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!

3
  • You haven't posted the full traceback. Please post the full traceback, since the error is in the line float_num = struct.unpack("f", binary_data)[0] but the traceback you posted only shows information about calling the function genetic_algorithm Commented Oct 7, 2024 at 15:47
  • @Cincinnatus Thank you, I've added the full traceback. Commented Oct 7, 2024 at 15:59
  • This should be easy to debug. Get the exact value of binary_list when the function binary_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. Commented Oct 8, 2024 at 8:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.