# Evolving a population#

Solving an optimization problem using an optimization algorithm is, in pygmo, described as evolving a population. In the scientific literature, an interesting discussion has developed over the past decades on whether evolution is or not a form of optimization. In pygmo we take the opposite standpoint and we regard optimization, of all types, as a form of evolution. Regardless on whether you will be using an SQP, an interior point optimizer or an evolutionary startegy solver, in pygmo you will always have to call a method called `evolve()` to improve over your initial solutions, i.e. your population.

The simplest way to evolve a population is to use directly the `algorithm` method `evolve()`

```>>> import pygmo as pg
>>> # The problem
>>> prob = pg.problem(pg.rosenbrock(dim = 10))
>>> # The initial population
>>> pop = pg.population(prob, size = 20)
>>> # The algorithm (a self-adaptive form of Differential Evolution (sade - jDE variant)
>>> algo = pg.algorithm(pg.sade(gen = 1000))
>>> # The actual optimization process
>>> pop = algo.evolve(pop)
>>> # Getting the best individual in the population
>>> best_fitness = pop.get_f()[pop.best_idx()]
>>> print(best_fitness)
[1.31392565e-07]
```

Clearly, as `sade` is a stochastic optimization algorithm, should we repeat the evolution starting from the same population, we would obtain different results. If we want to monitor multiple runs from different initial populations and see how the final best fitness is achieved as the number of fitness evaluations increase. Most pygmo UDAs allow to do this as they maintain an internal log that can be accessed after the UDA has been extracted (see `extract()`). This allows, for example to obtain plots such as those on the right, where multiple trials are monitored:

```>>> # We set the verbosity to 100 (i.e. each 100 gen there will be a log line)
>>> algo.set_verbosity(100)
>>> # We perform an evolution
>>> pop = pg.population(prob, size = 20)
>>> pop = algo.evolve(pop)
Gen:        Fevals:          Best:             F:            CR:            dx:            df:
1             20         135745       0.264146       0.541101        61.4904    2.55547e+06
101           2020        36.7951       0.252116       0.380181        7.01344        179.332
201           4020        4.06502       0.254534       0.740681        6.00596        59.3928
301           6020        2.96096       0.147331       0.790883       0.402499        7.95054
401           8020        2.43639       0.452624       0.922214        5.28217        6.80877
501          10020        1.65288       0.981585       0.975004        1.34442       0.897989
601          12020        1.16901        0.97663       0.783304        1.70733        1.36504
701          14020       0.750577       0.398881       0.922214        2.11136        1.78254
801          16020       0.438464        0.36723       0.960114        1.65512        1.18982
901          18020        0.18011        0.25882       0.932028        2.34781         1.4481
1001          20020      0.0792334       0.412775       0.887402        1.07089       0.211411
1101          22020     0.00875321       0.852287       0.472265        1.17808       0.170671
1201          24020    0.000820125       0.529034       0.633499       0.207262      0.0122566
1301          26020    2.13261e-05       0.176605       0.896106       0.060826    0.000706859
1401          28020    6.06571e-07       0.105885        0.81249     0.00852982    4.93967e-05
Exit condition -- generations = 1500