How do I return this information (sum of number_connected_components) to main()

81 views
Skip to first unread message

Andreia Gualberto

unread,
Mar 26, 2020, 2:08:04 PM3/26/20
to deap-users
I am making a genetic  algorithm using eaSimple and I would like to return the value of the sum of the number of related components (number_connected_components), but I do not know how to return this value. The only information I can get is the statistical values AVG, MIN, MAX using tools.Statistics. 
How do I return this information (sum of number_connected_components) to main()

def modFit(ind, yes):
    overall total

    CommMatrix = yes ['CommMatrix']
    A = np.multiply(np.array(ind), CommMatrix)
    G = nx.from_numpy_matrix(A)
    F4 = 1.0/nx.number_connected_components(G)
    total+=nx.number_connected_components(G)
    w1, w2, w3, w4 = yes['weights']
    FOther, = fit2(ind, yes)
    
    return FOther+w4*F4,
  

....

main( ) :
       pop, log = algorithms.eaSimple(pop, toolbox, cxpb=yes['GAParams']['cxProb'],
                               mutpb=yes['GAParams']['mutProb'], ngen=yes['GAParams']['ngen'],
                               stats=mstats, halloffame=hof, verbose=True)



Derek Tishler

unread,
Mar 26, 2020, 8:47:11 PM3/26/20
to deap-users
One method is to copy and paste algorithms.eaSimple from the github source to your script to be able to modify it. Then your evaluate function can return more than just a fitness tuple, and using zip you can unpack that into multiple items with something like:

In eval func
def eval(ind):
   
#do work, then return a tuple containing Fitness_Tuple, and then whatever else you want to return
   
return (fitness, ), sum(number_connected_components)

And in your main > eaSimple
fitnesses, sum_comonents_by_ind = zip(*evaluate(invalid_individuals))



Note...individuals are objects, you can add this value to your individual for easier handling, based on eaSimple:
From eaSimple source we start with existing:
fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
   
for ind, fit in zip(invalid_ind, fitnesses):
        ind
.fitness.values = fit

With above edit to unpack values and adding those values to each ind this becomes:

fitnesses, sum_comonents_by_ind = zip*(toolbox.map(toolbox.evaluate, invalid_ind))
for ind, fit, scbi in zip(invalid_ind, fitnesses, sum_comonents_by_ind):
    ind
.fitness.values = fit
    ind
.sum_number_connected_components =scbi

Andreia Gualberto

unread,
Mar 27, 2020, 2:39:15 PM3/27/20
to deap-users
I changed the eaSimple as recommended (replaces the fitness). I made an error in the 'map', according to searches, I converted to list() and so the error was solved. After that, the execution happens only until the first generation individuals, returning in values (0.5004301075268818, 3) the fitness and sum correctly. And another 'type' error appeared:

  File "C:\Users\andreia\AppData\Local\Programs\Python\Python36\lib\site-packages\deap\algorithms.py", line 175, in eaSimple
    fitnesses, sum_comonents_by_ind = zip*(list(toolbox.map(toolbox.evaluate, invalid_ind)))
TypeError: can't multiply sequence by non-int of type 'type'

Also, I'm still wondering how to receive these values in main(). I have to use the value of hof[0] to plot a graph. I can only see the reception of the 'pop' population and the 'log'...

something like : 
number_component = hof[0].sum_comonents_by_ind ?

Derek Tishler

unread,
Mar 27, 2020, 9:48:51 PM3/27/20
to deap-users
Sorry It is zip(* vs the second above written zip*(. The second time I wrote it was a typo.

And yes, if you assigned sum_number_connected_components to each individual then you can read it from the Hof items or the Pop items if they are returned from eaSimple back to Main. Hof items are just individuals from the pop. But note that the toolbox.map is used twice to evaluate the 0th gen and each after that in the loop, so be sure to change both spots of code.
Reply all
Reply to author
Forward
0 new messages