Parcourir la source

Merge tag 'v1.0.16' into develop

- Add of Zdt documentation
Jérôme BUISINE il y a 3 ans
Parent
commit
f40bedc9f3

+ 5 - 4
README.md

@@ -86,10 +86,11 @@ Main idea about this Python package is that it does not which doesn't implement
 Fully documentation of package with examples is [available](https://jbuisine.github.io/macop). 
 
 You can also see examples of use:
--  in the [knapsackExample.py](https://github.com/jbuisine/macop/blob/master/examples/knapsackExample.py) for mono-objective knapsack instance.
--  in the [knapsackMultiExample.py](https://github.com/jbuisine/macop/blob/master/examples/knapsackMultiExample.py) for multi-objective knapsack instance.
--  in the [qapExample.py](https://github.com/jbuisine/macop/blob/master/examples/qapExample.py) for mono-objective QAP instance.
--  in the [ubqpExample.py](https://github.com/jbuisine/macop/blob/master/examples/ubqpExample.py) for mono-objective UBQP problem instance.
+-  in the [knapsackExample.py](https://github.com/jbuisine/macop/blob/master/examples/knapsackExample.py) for mono-objective knapsack instance;
+-  in the [knapsackMultiExample.py](https://github.com/jbuisine/macop/blob/master/examples/knapsackMultiExample.py) for multi-objective knapsack instance;
+-  in the [qapExample.py](https://github.com/jbuisine/macop/blob/master/examples/qapExample.py) for mono-objective QAP instance;
+-  in the [ubqpExample.py](https://github.com/jbuisine/macop/blob/master/examples/ubqpExample.py) for mono-objective UBQP problem instance;
+-  in the [ZdtExample.py](https://github.com/jbuisine/macop/blob/master/examples/ZdtExample.py) for continuous optimisation problem over Zdt function.
 
 ## Add as dependency
 

BIN
docs/source/_static/examples/zdt/rosenbrock_function.jpg


+ 2 - 2
docs/source/conf.py

@@ -25,9 +25,9 @@ copyright = '2021, Jérôme BUISINE'
 author = 'Jérôme BUISINE'
 
 # The short X.Y version
-version = '1.0.15'
+version = '1.0.16'
 # The full version, including alpha/beta/rc tags
-release = 'v1.0.15'
+release = 'v1.0.16'
 
 
 # -- General configuration ---------------------------------------------------

+ 15 - 5
docs/source/examples.rst

@@ -1,9 +1,9 @@
-Some examples
+Example uses
 =====================================
 
 You will find here some examples of using Macop with implementations of problems well known from the literature.
 
-Implemented problem examples
+Discrete problem
 ----------------------------
 
 .. toctree::
@@ -12,16 +12,26 @@ Implemented problem examples
    qap_example
    ubqp_example
 
+Continuous problem
+----------------------------
+
+.. toctree::
+   :maxdepth: 1
+
+   zdt_example
+
 
 Available code examples
 -----------------------
 
-- mono-objective knapsack: knapsackExample.py_
-- multi-objective knapsack: knapsackMultiExample.py_
+- mono-objective knapsack problem: knapsackExample.py_
+- multi-objective knapsack problem: knapsackMultiExample.py_
 - QAP problem: qapExample.py_
 - UBQP problem: ubqpExample.py_
+- Continuous Zdt optimisation problem: ZdtExample.py_
 
 .. _knapsackExample.py: https://github.com/jbuisine/macop/blob/master/examples/knapsackExample.py
 .. _knapsackMultiExample.py: https://github.com/jbuisine/macop/blob/master/examples/knapsackMultiExample.py
 .. _qapExample.py: https://github.com/jbuisine/macop/blob/master/examples/qapExample.py
-.. _ubqpExample.py: https://github.com/jbuisine/macop/blob/master/examples/ubqpExample.py
+.. _ubqpExample.py: https://github.com/jbuisine/macop/blob/master/examples/ubqpExample.py
+.. _ZdtExample.py: https://github.com/jbuisine/macop/blob/master/examples/ZdtExample.py

+ 1 - 1
docs/source/qap_example.rst

@@ -29,7 +29,7 @@ is assigned to location 2, facility 3 is assigned to location 3, and facility 2
 which means that facility 4 is assigned to location 1, facility 1 is assigned to location 2, facility 3 is assigned to location 3, and facility 2 is assigned to location 3. 
 In the figure, the line between a pair of facilities indicates that there is required flow between the facilities, and the thickness of the line increases with the value of the flow. 
 
-.. image:: _static//examples/qap/factories_qap.png
+.. image:: _static/examples/qap/factories_qap.png
    :width: 50 %
    :align: center
    :alt: Example of QAP facilities to locations problem

+ 201 - 0
docs/source/zdt_example.rst

@@ -0,0 +1,201 @@
+===============================
+Zdt optimisation problem
+===============================
+
+In applied mathematics, test functions, known as artificial landscapes, are useful to evaluate characteristics of continuous optimization algorithms, such as:
+
+- Convergence rate.
+- Precision.
+- Robustness.
+- General performance.
+
+.. note:: 
+   The full code for what will be proposed in this example is available: ZdtExample.py_.
+
+
+Rosenbrock's function
+======================
+
+In mathematical optimization, the Rosenbrock function is a non-convex function, introduced by Howard H. Rosenbrock in 1960, which is used as a performance test problem for optimization algorithms.
+
+Mathematical definition
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The function is defined by: :math:`f(x, y) = (a − x)^2 + b(y − x^2)^2`
+
+It has a global minimum at :math:`(x, y) = (a, a^2)`, where :math:`f(x, y) = 0`. Usually these parameters are set such that :math:`a = 1` and :math:`b = 100`. Only in the trivial case where :math:`a = 0` the function is symmetric and the minimum is at the origin. 
+
+Below is a 3D representation of the function with the same parameters :math:`a = 1` and :math:`b = 100`.
+
+.. image:: _static/examples/zdt/rosenbrock_function.jpg
+   :width: 50 %
+   :align: center
+   :alt: 3D representation of Rosenbrock's function
+
+The search space is defined by: :math:`-\infty \leq x_i \leq \infty, 1 \leq i \leq n`
+
+Optimal solution is defined by: :math:`f(1, ..., 1)=0` when :math:`n > 3`
+
+Specific instance used
+~~~~~~~~~~~~~~~~~~~~~~
+
+Using :math:`a = 1` and :math:`b = 100`, the function can be re-written:
+
+- :math:`f(x)=\sum_{i=1}^{n-1}{[(x_{i + 1} − x_i^2)^2 + (1 − x_i)^2]}`
+
+
+For the current implementation example, the search space will be reduced to :math:`-10 \leq x_i \leq 10` and the instance size will be set to :math:`n = 10`.
+
+Macop implementation
+========================
+
+Let's see how it is possible with the use of the **Macop** package to implement and deal with this Rosenbrock's function instance problem.
+
+Solution structure definition
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Firstly, we are going to use a type of solution that will allow us to define the structure of our solutions.
+
+The available macop.solutions.continuous.ContinuousSolution_ type of solution within the Macop package represents exactly what one would wish for. 
+I.e. a solution that stores a float array with respect to the size of the problem.
+
+Let's see an example of its use:
+
+.. code:: python
+
+    from macop.solutions.continuous import ContinuousSolution
+    
+    problem_interval = -10, 10
+    solution = ContinuousSolution.random(10, interval=problem_interval)
+    print(solution)
+
+The ``problem_interval`` variable is required in order to generate our continuous solution with respect to the search space.
+The resulting solution obtained should be something like:
+
+.. code:: bash
+
+    Continuous solution [-3.31048093 -8.69195762 ... -2.84790964 -1.08397853]
+
+
+Zdt Evaluator
+~~~~~~~~~~~~~
+
+Now that we have the structure of our solutions, and the means to generate them, we will seek to evaluate them.
+
+To do this, we need to create a new evaluator specific to our problem and the relative evaluation function:
+
+- :math:`f(x)=\sum_{i=1}^{n-1}{[(x_{i + 1} − x_i^2)^2 + (1 − x_i)^2]}`
+
+So we are going to create a class that will inherit from the abstract class macop.evaluators.base.Evaluator_:
+
+
+.. code:: python
+
+    from macop.evaluators.base import Evaluator
+
+    class ZdtEvaluator(Evaluator):
+    """Generic Zdt evaluator class which enables to compute custom Zdt function for continuous problem
+
+    - stores into its `_data` dictionary attritute required measures when computing a continuous solution
+    - `_data['f']` stores lambda Zdt function 
+    - `compute` method enables to compute and associate a score to a given continuous solution
+    """
+
+    def compute(self, solution):
+        """Apply the computation of fitness from solution
+        Args:
+            solution: {:class:`~macop.solutions.base.Solution`} -- Solution instance
+    
+        Returns:
+            {float}: fitness score of solution
+        """
+        return self._data['f'](solution)
+
+The cost function for the zdt continuous problem is now well defined but we still need to define the lambda function.
+
+.. code:: python
+
+    from macop.evaluators.continuous.mono import ZdtEvaluator
+
+    # Rosenbrock function definition
+    Rosenbrock_function = lambda s: sum([ 100 * math.pow(s.data[i + 1] - (math.pow(s.data[i], 2)), 2) + math.pow((1 - s.data[i]), 2) for i in range(len(s.data) - 1) ])
+
+    evaluator = ZdtEvaluator(data={'f': Rosenbrock_function})
+
+.. tip::
+    The class proposed here, is available in the Macop package macop.evaluators.continuous.mono.ZdtEvaluator_.
+
+Running algorithm
+~~~~~~~~~~~~~~~~~
+
+Now that the necessary tools are available, we will be able to deal with our problem and look for solutions in the search space of our Zdt Rosenbrock instance.
+
+Here we will use local search algorithms already implemented in **Macop**.
+
+If you are uncomfortable with some of the elements in the code that will follow, you can refer to the more complete **Macop** documentation_ that focuses more on the concepts and tools of the package.
+
+.. code:: python
+
+    # main imports
+    import numpy as np
+
+    # module imports
+    from macop.solutions.continuous import ContinuousSolution
+    from macop.evaluators.continuous.mono import ZdtEvaluator
+
+    from macop.operators.continuous.mutators import PolynomialMutation
+
+    from macop.policies.classicals import RandomPolicy
+
+    from macop.algorithms.mono import IteratedLocalSearch as ILS
+    from macop.algorithms.mono import HillClimberFirstImprovment
+
+    # usefull instance data
+    n = 10
+    problem_interval = -10, 10
+    qap_instance_file = 'zdt_instance.txt'
+
+    # default validator (check the consistency of our data, i.e. x_i element in search space)
+    def validator(solution):
+        mini, maxi = problem_interval
+
+        for x in solution.data:
+            if x < mini or x > maxi:
+                return False
+
+        return True
+
+    # define init random solution with search space bounds
+    def init():
+        return ContinuousSolution.random(n, interval=problem_interval, validator)
+
+    # only one operator here
+    operators = [PolynomialMutation()]
+
+    # random policy even if list of solution has only one element
+    policy = RandomPolicy(operators)
+
+    # Rosenbrock function definition
+    Rosenbrock_function = lambda s: sum([ 100 * math.pow(s.data[i + 1] - (math.pow(s.data[i], 2)), 2) + math.pow((1 - s.data[i]), 2) for i in range(len(s.data) - 1) ])
+
+    evaluator = ZdtEvaluator(data={'f': Rosenbrock_function})
+
+    # passing global evaluation param from ILS
+    hcfi = HillClimberFirstImprovment(init, evaluator, operators, policy, validator, maximise=False, verbose=True)
+    algo = ILS(init, evaluator, operators, policy, validator, localSearch=hcfi, maximise=False, verbose=True)
+
+    # run the algorithm
+    bestSol = algo.run(10000, ls_evaluations=100)
+
+    print('Solution for zdt Rosenbrock instance score is {}'.format(evaluator.compute(bestSol)))
+
+
+Continuous Rosenbrock's function problem is now possible with **Macop**. As a reminder, the complete code is available in the ZdtExample.py_ file.
+
+.. _ZdtExample.py: https://github.com/jbuisine/macop/blob/master/examples/ZdtExample.py
+.. _documentation: https://jbuisine.github.io/macop/_build/html/documentations
+
+
+.. _macop.solutions.continuous.ContinuousSolution: macop/macop.solutions.continuous.html#macop.solutions.continuous.ContinuousSolution
+.. _macop.evaluators.base.Evaluator: macop/macop.evaluators.base.html#macop.evaluators.base.Evaluator
+.. _macop.evaluators.continuous.mono.ZdtEvaluator: macop/macop.evaluators.continuous.mono.html#macop.evaluators.continuous.mono.ZdtEvaluator

+ 1 - 1
setup.py

@@ -82,7 +82,7 @@ class TestCommand(distutils.command.check.check):
 
 setup(
     name='macop',
-    version='1.0.15',
+    version='1.0.16',
     description='Minimalist And Customisable Optimisation Package',
     long_description=open('README.md').read(),
     long_description_content_type='text/markdown',