Project-Platypus / Platypus

A Free and Open Source Python Library for Multiobjective Optimization
GNU General Public License v3.0
569 stars 153 forks source link

Is it possible to use custom initial population? #62

Closed Alaya-in-Matrix closed 1 year ago

Alaya-in-Matrix commented 6 years ago

I have some good guess about the final PF, is it possible to add them into the initial population or archives?

eigeneko commented 6 years ago

You can modify the initialize() method, and then change the self.population. I think it's easy to implement.

Alaya-in-Matrix commented 6 years ago

I am not very familiar with Python, can I create a new class that inherits the algorithm class(like NSGAIII) and override the initialize()?

dhadka commented 6 years ago

Try using InjectedPopulation. For example:

algorithm = NSGAII(problem, generator = InjectedPopulation(init_pop))

I added this today, so please pull the latest changes from master.

Edit: This seeds the initial population and archive (if there is one) with a list of solutions, which can be the PF from a previous run.

Alaya-in-Matrix commented 6 years ago

Thanks!

ecchapin commented 6 years ago

Hi,

Following on this previous comment, I am also interested in giving it a custom initial population. Could you provide an example of how you write the code for init_pop. For example, I have 14 binary decision variables. How would I give platypus a couple of initial solutions with init_pop?

Thanks so much, Emily

kimbrerfesten commented 6 years ago

Would also love an example of how to do this. It would also support restarting the run.

dieaquino commented 5 years ago

Here's the example, this worked to me:

problem = Problem(14,2)
problem.types[:] = [Integer(4, 32),        
                    Integer(4, 32),        
                    Integer(1, 4),         
                    Integer(1, 5),         
                    Integer(0, 3),         
                    Integer(4, 32),        
                    Integer(4, 32),        
                    Integer(1, 4),         
                    Integer(1, 5),         
                    Integer(0, 3),         
                    Integer(4, 32),        
                    Integer(4, 32),
                    Integer(1, 4),
                    Integer(1, 5)]
problem.function = my_function
problem.directions[:] = Problem.MAXIMIZE

v_population_size = 5
init_pop = [Solution(problem) for i in range(v_population_size)]
pop_indiv = [[x.rand() for x in problem.types] for i in range(v_population_size)]

for i in range(v_population_size):
    init_pop[i].variables = pop_indiv[i]

algorithm = NSGAII(problem, population_size=v_population_size, generator=InjectedPopulation(init_pop))
algorithm.run(10)   
ashuein commented 4 years ago

Here's the example, this worked to me:

problem = Problem(14,2)
problem.types[:] = [Integer(4, 32),        
                    Integer(4, 32),        
                    Integer(1, 4),         
                    Integer(1, 5),         
                    Integer(0, 3),         
                    Integer(4, 32),        
                    Integer(4, 32),        
                    Integer(1, 4),         
                    Integer(1, 5),         
                    Integer(0, 3),         
                    Integer(4, 32),        
                    Integer(4, 32),
                    Integer(1, 4),
                    Integer(1, 5)]
problem.function = my_function
problem.directions[:] = Problem.MAXIMIZE

v_population_size = 5
init_pop = [Solution(problem) for i in range(v_population_size)]
pop_indiv = [[x.rand() for x in problem.types] for i in range(v_population_size)]

for i in range(v_population_size):
    init_pop[i].variables = pop_indiv[i]

algorithm = NSGAII(problem, population_size=v_population_size, generator=InjectedPopulation(init_pop))
algorithm.run(10)   

can you elaborate a little bit on what your code is actually doing?

joergfelder commented 4 years ago

Thanks for the example code. I am currently running an optimization where each evaluation takes really long (a 3D EM problem) so that I store the variables and results in a csv file as a precaution. This turns out to be a good idea, as the computer was shut down due to a power failure last week. No I am looking into restarting the optimization. I am ok with the code above. However, in the meantime I have more results that my population size is large. So ideally, I would like to inject only the best solutions up to now. However, since I am optimizing for five 5 different target functions I am not quite sure how to select the "best"solutions. Can I use the nondominated function for this?

joergfelder commented 4 years ago

My current implementation is as follows. I read the results from previous runs from a csv file:

file = open( str(CSVFileName), 'r')
csvreader = csv.reader(file)

for row in csvreader:
     if len(row) != 0:
         Variable_1 = np.append(Variable_1, float(row[0]))
         Variable_2 = np.append(Variable_2, float(row[1]))
       ...
        Result_1 = np.append(Variable_1, float(row[X]))
        Result_2 = np.append(Variable_2, float(row[X+1]))

file.close()

init_pop = [Solution(problem) for i in range(len(Result_1))]
for i in range(len(Result_1)):
    init_pop[i].variables = [ Variable_1, Variable_2, ...]
    init_pop[i].objectives = [ Result_1, Result_2 ...
    init_pop[i].constraints = [ Constraint_1, Constraint_2, ... ] 
    init_pop[i].constraint_violation = 0.0
    init_pop[i].feasible = True
    init_pop[i].evaluated = True

nondominated_solutions = nondominated(init_pop)
NumberOfIterations = len(Result_1)

i_num_evals = 500
algorithm = NSGAII(problem, population_size=len(nondominated_solutions), generator=InjectedPopulation(nond_sols))
i_num_evals = i_num_evals - NumberOfIterations + len(nondominated_solutions)
algorithm.run(i_num_evals)

However, now algorithm.results returns a number of evaluated solutions - but an even one with zero values in the objectives that have not been evaluated. Could someone give me an idea of what is going wrong?

github-actions[bot] commented 1 year ago

This issue is stale and will be closed soon. If you feel this issue is still relevant, please comment to keep it active. Please also consider working on a fix and submitting a PR.