anyoptimization / pymoo

NSGA2, NSGA3, R-NSGA3, MOEAD, Genetic Algorithms (GA), Differential Evolution (DE), CMAES, PSO
https://pymoo.org
Apache License 2.0
2.28k stars 392 forks source link

Any methods to get first feasible solution in less generation? #384

Closed jacktang closed 1 year ago

jacktang commented 1 year ago

Hi,

In my problem, I used nsga2 as the solver and adopted random sampling strategy, the code looked like below:

        algorithm = NSGA2(
            pop_size=100,
            n_offsprings=50,
            sampling=FloatRandomSampling(),
            ...
            eliminate_duplicates=True
        )

I found that the first feasible solution came up around 400 generations. When the constraints changed, it would need more generations, and sometime it had no solution at all (but I know there was always one feasible solution existed).

So I tried add the feasible solution into the init population(https://github.com/anyoptimization/pymoo/issues/362), but the final result is worse than random sampling. So here are my questions:

  1. How can I get the "high quality" feasible solution as random sampling but takes less generations/time? Any papers or resources to recommend?
  2. Is there any indicators to tell me there is no solution in 100 generations? If yes, I want to add the feasible solution using callback to make sure the problem always be solved.

Appreciate your time!

blankjul commented 1 year ago

Constrained problems can be really challenging. And also every domain problem is different.

Often you can redefine your problem to be easier to solve. Can you implement a repair operator? https://pymoo.org/operators/repair.html If you can every single solution evaluated, is feasible. The repair can also be another embedded optimization run by the way.

Otherwise, can you redefine your problem to be easier to be solved? What type of constraints do you have?

jacktang commented 1 year ago

@blankjul Sorry for the later reply.

My problem is about controlling flow rate in cascaded liquid tanks and I simplify the problem below. As below figure shown, there are three tanks, each of them has the constraint of water level, and two controllers to control the flow rate, and flow rate changes every 30 minutes(this is X). There are two objectives in the operation:

  1. try to keep the liquid to the upper water limit
  2. try to keep the peak flow rate at red point (between tank-B and tank-C) to minimal

And the constraints includes:

  1. tank water level limits (between min water level and max water level)
  2. controller flow rate limits (between min flow rate and max flow rate)

And the array of X are flow rates in 4 hours (X size is 8) . $Q{in}$ is the input flow rate of tank, and $Q{out}$ is the output flow rate of tank. There is always one feasible solution exits, which is $Q{in} = Q{out}$, which means $X=[Q{in-A}, Q{in-B}, Q_{in-C}]$.

I've read the repair operator document, and thank you for your suggestions. But I don't know how to apply to above problem.

image

jacktang commented 1 year ago

Well, I got how to use repair operator now. Thanks!

jacktang commented 1 year ago

Hello @blankjul,

From my experiences, the repair operator is computing sensitive and takes long time. It makes sense that it should enable repair in parallel while the problem runs on multi-thread/process.

blankjul commented 1 year ago

The repair operator receives the whole population. Are you then using a for loop in there to repair each individual at a time? In your implementation, you can parallelize this to speed it up as well (e.g. you can use joblib).