Package: hello-genetic-algorithm
hello-genetic-algorithmA basic implementation of genetic algorithm. It fits for small scale experiments like college labs or GA beginners.Use this command to installpip install hello-genetic-algorithmAlgorithm ParametersEssential parameters (must set up by user)Individual classFitness functionOptional parameters (with default value if not set)Mutation ratioCrossoverConstraintsSelection ratioExecution parameters (config stop criteria or logging level)Max iterationMax generationEnvironment CapacityLogging levelIntroduction by exampleFormulate the ProblemAssume we have 12 goods to be packed into a travel suitcase. The suitcase can hold at list 250 kg goods. We have measured the weights for each of the goods and define importance so that we should packed more important goods as much as possible in the limit of weight constraint.Define the chromosome as a 0-1 vector to represent each box. The problem is to find out a vector that maximize sum of boxImportance where sum of boxWeights are less than or equal to 250. eq.$$ \max \sum_{i}{I_i} \quad where \quad i \in {0, \dots, 11}  $$
$$ s.t. \sum_{i}{W_i} <= 250 $$Formulation to parametersThis formulation can be mapping toaBinaryIndividualclass to represent whether to select a goodsa predefinedWeightedSumFitness:a user-definedconstraints: total weights of goods should be less or equal to 250.Algorithm StepsInitialize: input parameters and create algorithm instanceCalculate fitness: calculate fitness value for every individualSelect: keep only the individuals fulfill the constrantsReproduce: generate new individuals by mutation and crossover operatorExit criteria: check if stop criteria is fulfilled. If yes, stop the progress, otherwise repeat from step 2.Example Codefromhelloga.environmentimportEnvironmentfromhelloga.individualimportBinaryIndividualfromhelloga.crossoverimportSinglePointCrossOverfromhelloga.selectorimportLeadingSelectorfromhelloga.fitnessimportWeightedSumFitness# Define fitness importence and contraint weightsbox_importance=[6,5,8,7,6,9,4,5,4,9,2,1]box_weights=[20,30,60,90,50,70,30,30,70,20,20,60]# Define constraintsdeftotal_size_lt250(individual,size=np.array([])):deftotal_size(individual,size=np.array([])):chr_arr=np.array(individual.chromosome)siz_arr=np.array(size)total=np.dot(chr_arr,siz_arr.T)returntotaltotal=total_size(individual,size)returntotal<=250# Initialize by random individuals.# Each element in the vector represents whether to select the i-th goods or notindividuals=[BinaryIndividual([1,1,1,0,0,0,0,0,0,0,0,1],0,0),BinaryIndividual([1,0,0,0,1,0,0,0,0,0,0,1],0,0),BinaryIndividual([0,0,0,0,0,1,1,0,0,1,0,0],0,0),BinaryIndividual([0,0,1,0,0,0,0,0,1,0,0,1],0,0),BinaryIndividual([0,1,0,0,1,0,0,0,0,0,0,1],0,0),]# Define selectorsel=LeadingSelector(ratio=0.5,constraints=[lambdax:total_size_lt250(x,box_weights)])# Define fitness functionfit=WeightedSumFitness(weights=box_importance)# Define selectorxo=SinglePointCrossOver()# Create environmentenv=Environment(individuals,selector=sel,crossover=xo,fitness_func=fit,MAX_GENERATION=50,CAPACITY=100,MAX_ITERATION=100,log_level='info')# Run genetic algorithmenv.evolute()# Print population and generation after the algorithm stoppedprint(env.species.population(),env.species.generations())# Print best 3 solutions to the problemprint('The best 3 solutions are: ')forsolinenv.getSolution(3):print(sol)