Parcourir la source

Add of example into documentation

Jérôme BUISINE il y a 3 ans
Parent
commit
02f1bb1631

+ 1 - 1
README.md

@@ -23,7 +23,7 @@
 
 ## How to use ?
 
-You can see an example of use in the `mainExample.py` python file.
+You can see an example of use in the `knapsackExample.py` python file.
 
 Fully documentation of package with examples is also [available](https://jbuisine.github.io/macop). 
 

BIN
docs/build/doctrees/description.doctree


BIN
docs/build/doctrees/environment.pickle


BIN
docs/build/doctrees/examples.doctree


BIN
docs/build/doctrees/macop/macop.algorithms.Algorithm.doctree


BIN
docs/build/doctrees/macop/macop.operators.policies.UCBPolicy.doctree


+ 16 - 1
docs/build/html/_modules/macop/algorithms/Algorithm.html

@@ -156,7 +156,7 @@
 
 <span class="c1"># main imports</span>
 <span class="kn">import</span> <span class="nn">logging</span>
-<span class="kn">from</span> <span class="nn">..utils.color</span> <span class="kn">import</span> <span class="n">macop_text</span><span class="p">,</span> <span class="n">macop_line</span>
+<span class="kn">from</span> <span class="nn">..utils.color</span> <span class="kn">import</span> <span class="n">macop_text</span><span class="p">,</span> <span class="n">macop_line</span><span class="p">,</span> <span class="n">macop_progress</span>
 
 
 <span class="c1"># Generic algorithm class</span>
@@ -279,6 +279,18 @@
 
         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">numberOfEvaluations</span></div>
 
+<div class="viewcode-block" id="Algorithm.getGlobalMaxEvaluation"><a class="viewcode-back" href="../../../macop/macop.algorithms.Algorithm.html#macop.algorithms.Algorithm.Algorithm.getGlobalMaxEvaluation">[docs]</a>    <span class="k">def</span> <span class="nf">getGlobalMaxEvaluation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;Get the global max number of evaluation (if inner algorithm)</span>
+
+<span class="sd">        Returns:</span>
+<span class="sd">            {int} -- current global max number of evaluation</span>
+<span class="sd">        &quot;&quot;&quot;</span>
+
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">maxEvaluations</span>
+
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">maxEvaluations</span></div>
+
 <div class="viewcode-block" id="Algorithm.stop"><a class="viewcode-back" href="../../../macop/macop.algorithms.Algorithm.html#macop.algorithms.Algorithm.Algorithm.stop">[docs]</a>    <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;</span>
 <span class="sd">        Global stopping criteria (check for inner algorithm too)</span>
@@ -375,6 +387,9 @@
         <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">checkpoint</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">checkpoint</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
 
+        <span class="n">macop_progress</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">getGlobalEvaluation</span><span class="p">(),</span>
+                       <span class="bp">self</span><span class="o">.</span><span class="n">getGlobalMaxEvaluation</span><span class="p">())</span>
+
         <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;-- </span><span class="si">%s</span><span class="s2"> evaluation </span><span class="si">%s</span><span class="s2"> of </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s%%</span><span class="s2">) - BEST SCORE </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                      <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">numberOfEvaluations</span><span class="p">,</span>
                       <span class="bp">self</span><span class="o">.</span><span class="n">maxEvaluations</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{0:.2f}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>

+ 0 - 1
docs/build/html/_modules/macop/checkpoints/BasicCheckpoint.html

@@ -248,7 +248,6 @@
                 <span class="n">macop_text</span><span class="p">(</span>
                     <span class="s1">&#39;No backup found... Start running algorithm from evaluation 0.&#39;</span>
                 <span class="p">))</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">macop_line</span><span class="p">())</span>
             <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
                 <span class="s2">&quot;Can&#39;t load backup... Backup filepath not valid in Checkpoint&quot;</span><span class="p">)</span>
 

+ 5 - 1
docs/build/html/_modules/macop/evaluators/EvaluatorExample.html

@@ -154,6 +154,10 @@
 <span></span><span class="sd">&quot;&quot;&quot;Python evaluator function example</span>
 <span class="sd">&quot;&quot;&quot;</span>
 
+<span class="kn">import</span> <span class="nn">random</span>
+
+<span class="n">elements_score</span> <span class="o">=</span> <span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">30</span><span class="p">)]</span>
+
 
 <span class="c1"># evaluator example</span>
 <div class="viewcode-block" id="evaluatorExample"><a class="viewcode-back" href="../../../macop/macop.evaluators.EvaluatorExample.html#macop.evaluators.EvaluatorExample.evaluatorExample">[docs]</a><span class="k">def</span> <span class="nf">evaluatorExample</span><span class="p">(</span><span class="n">_solution</span><span class="p">):</span>
@@ -168,7 +172,7 @@
 <span class="sd">    &quot;&quot;&quot;</span>
     <span class="n">fitness</span> <span class="o">=</span> <span class="mi">0</span>
     <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">elem</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">_solution</span><span class="o">.</span><span class="n">data</span><span class="p">):</span>
-        <span class="n">fitness</span> <span class="o">=</span> <span class="n">fitness</span> <span class="o">+</span> <span class="p">(</span><span class="n">elem</span> <span class="o">*</span> <span class="n">index</span><span class="p">)</span>
+        <span class="n">fitness</span> <span class="o">+=</span> <span class="n">elements_score</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">*</span> <span class="n">elem</span>
 
     <span class="k">return</span> <span class="n">fitness</span></div>
 </pre></div>

+ 1 - 1
docs/build/html/_modules/macop/operators/policies/UCBPolicy.html

@@ -171,7 +171,7 @@
 <span class="sd">        rewards: {[float]} -- list of summed rewards obtained for each operator</span>
 <span class="sd">        occurences: {[int]} -- number of use (selected) of each operator</span>
 <span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_operators</span><span class="p">,</span> <span class="n">_C</span><span class="o">=</span><span class="mf">10.</span><span class="p">):</span>
+    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_operators</span><span class="p">,</span> <span class="n">_C</span><span class="o">=</span><span class="mf">1000.</span><span class="p">):</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">operators</span> <span class="o">=</span> <span class="n">_operators</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">rewards</span> <span class="o">=</span> <span class="p">[</span><span class="mf">0.</span> <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">operators</span><span class="p">]</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">occurences</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span> <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">operators</span><span class="p">]</span>

+ 0 - 50
docs/build/html/_sources/description.rst.txt

@@ -19,53 +19,3 @@ Just install package using `pip` Python package manager:
 .. code:: bash
    
    pip install macop
-
-
-How to use ?
-------------
-
-Load all `macop` implemented features:
-
-.. code:: python
-    
-   from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
-   from macop.solutions.BinarySolution import BinarySolution
-   from macop.evaluators.EvaluatorExample import evaluatorExample
-
-   from macop.operators.mutators.SimpleMutation import SimpleMutation
-   from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
-   from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
-   from macop.operators.crossovers.RandomSplitCrossover import RandomSplitCrossover
-
-   from macop.operators.policies.RandomPolicy import RandomPolicy
-
-   from macop.checkpoints.BasicCheckpoint import BasicCheckpoint
-
-   # logging configuration
-   logging.basicConfig(format='%(asctime)s %(message)s', filename='example.log', level=logging.DEBUG)
-
-   # default validator
-   def validator(solution):
-      return True
-
-   # define init random solution
-   def init():
-      return BinarySolution([], 30).random(validator)
-
-   filepath = "checkpoints.csv"
-
-   def main():
-
-      operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
-      policy = RandomPolicy(operators)
-
-      algo = ILS(init, evaluatorExample, operators, policy, validator, True)
-      algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath=filepath)
-
-      bestSol = algo.run(425)
-
-      print("Found ", bestSol)
-
-
-   if __name__ == "__main__":
-      main()

+ 246 - 4
docs/build/html/_sources/examples.rst.txt

@@ -1,13 +1,255 @@
 Some examples
 =====================================
 
-Mono-objective example
+1. Mono-objective
 -----------------------
 
-Available soon...
+In this tutorial, it will introduce the way of running your algorithm quickly.
+First of all we need to define the kind of solution best represent the problem. In this tutorial, we use the well known knapsack problem using 30 objects.
 
+1.1 Problem definition
+~~~~~~~~~~~~~~~~~~~~~~
 
-Multi-objective example
-------------------------
+Hence, we define our problem :
+- value of each component of knapsack
+- weight associated to each of these components (objects)
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    import random
+
+    """
+    Problem definition
+    """
+    random.seed(42)
+
+    elements_score = [ random.randint(1, 20) for _ in range(30) ]
+    elements_weight = [ random.randint(5, 25) for _ in range(30) ]
+
+We can now define the solution representation. In knapsack problem we want to fill our knapsack in an optimization way selecting or not each component (object).
+The best way to represent this problem is to use the `BinarySolution` from `macop` which stores solution as a binary array.
+
+Using the solution representation, we need to define multiple things to fit our algorithm :
+- 1. function which validates or not a solution (based on constraints)
+- 2. function which evaluates the solution (in order to obtain fitness)
+- 3. initialization solution function
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    import random
+    from macop.solutions.BinarySolution import BinarySolution
+
+    """
+    Problem definition
+    """
+    random.seed(42)
+
+    elements_score = [ random.randint(1, 20) for _ in range(30) ]
+    elements_weight = [ random.randint(2, 5) for _ in range(30) ]
+
+    # 1. validator function (we accept only bag with maximum weight 80kg)
+    def validator(_solution):
+
+        weight_sum = 0
+        for index, elem in enumerate(_solution.data):
+            weight_sum += elements_weight[index] * elem
+
+        if weight_sum <= 80:
+            return True
+        else:
+            False
+
+    # 2. function which computes fitness of solution
+    def evaluator(_solution):
+
+        fitness = 0
+        for index, elem in enumerate(_solution.data):
+            fitness += (elements_score[index] * elem)
+
+        return fitness
+
+    # 3. function which here initializes solution ramdomly and check validity of solution
+    def init():
+        return BinarySolution([], 30).random(validator)
+
+1.2 Operators and Policy
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+In our algorithm we need to use some operators in order to improve current best solution found at current `n` evaluations.
+
+In `macop` you have some available operators. In this example, we use 3 of them.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    from macop.operators.mutators.SimpleMutation import SimpleMutation
+    from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
+    from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    # list of operators instance to use
+    operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
+
+As we defined multiple operators, we have to tell how we want to select them into the algorithm. This is why **Policy** classes have been implemented.
+`Policy` class implementation enables to select the next operator to use and once new solution is generated, computes its score (in `apply` method). This class requires all the operators use to be instanciate.
+
+Why computing score into **Policy** `apply` method ? Because it's a way to get some important statistics from solution improvment using specific operator.
+**UCBPolicy** as example, based on Upper Confidence Bound (UCB_), computes reward each time a new solution is generated from an operator in order to better select next operator later. We use in this example the `UCBPolicy` implementation.
+
+.. _UCB: https://banditalgs.com/2016/09/18/the-upper-confidence-bound-algorithm/
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    from macop.operators.mutators.SimpleMutation import SimpleMutation
+    from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
+    from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
+
+    from macop.operators.policies.UCBPolicy import UCBPolicy
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    # list of operators instance to use
+    operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
+
+    # `policy` instance is created using specific value for Upper Confidence Bound
+    policy = UCBPolicy(operators, C=100.)
+
+1.3 Before running algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before running algorithm we can define a logger to keep track of the all algorithm run.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    import logging
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+We can now instanciate our algorithm. We use the Iterated Local Search in this example. It is mainly used to avoid local optima using multiple local search.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    import logging
+
+    from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+    algo = ILS(init, evaluator, operators, policy, validator, _maximise=True)
+
+The algorithm is now well defined and is ready to run ! But one thing can be done, and it's very interesting to avoir restart from scratch the algorithm run.
+The use of checkpoint is available in `macop`. A `BasicCheckpoint` class let the algorithm save at `every` evaluations the best solution found.
+
+We need to specify the use of checkpoint if we prefer to restart from.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+    
+    import logging
+
+    from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
+    from macop.checkpoints.BasicCheckpoint import BasicCheckpoint
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+    algo = ILS(init, evaluator, operators, policy, validator, _maximise=True)
+
+    # we specify the checkpoint class directly, the frequency and the path we want to save algorithm evolution
+    algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath='data/checkpoint.csv')
+
+
+In this way, now we can run and obtained the best solution found in `n` evaluations
+
+.. code:: python
+
+    bestSol = algo.run(10000)
+    print('Solution score is {}'.format(evaluator(bestSol)))
+
+2. Multi-objective example
+--------------------------
 
 Available soon...

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 48
docs/build/html/description.html


Fichier diff supprimé car celui-ci est trop grand
+ 231 - 6
docs/build/html/examples.html


+ 4 - 0
docs/build/html/genindex.html

@@ -324,6 +324,10 @@
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%; vertical-align: top;"><ul>
       <li><a href="macop/macop.algorithms.Algorithm.html#macop.algorithms.Algorithm.Algorithm.getGlobalEvaluation">getGlobalEvaluation() (macop.algorithms.Algorithm.Algorithm method)</a>
+</li>
+  </ul></td>
+  <td style="width: 33%; vertical-align: top;"><ul>
+      <li><a href="macop/macop.algorithms.Algorithm.html#macop.algorithms.Algorithm.Algorithm.getGlobalMaxEvaluation">getGlobalMaxEvaluation() (macop.algorithms.Algorithm.Algorithm method)</a>
 </li>
   </ul></td>
 </tr></table>

+ 11 - 0
docs/build/html/macop/macop.algorithms.Algorithm.html

@@ -300,6 +300,17 @@
 </dl>
 </dd></dl>
 
+<dl class="method">
+<dt id="macop.algorithms.Algorithm.Algorithm.getGlobalMaxEvaluation">
+<code class="sig-name descname">getGlobalMaxEvaluation</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/macop/algorithms/Algorithm.html#Algorithm.getGlobalMaxEvaluation"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#macop.algorithms.Algorithm.Algorithm.getGlobalMaxEvaluation" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the global max number of evaluation (if inner algorithm)</p>
+<dl class="field-list simple">
+<dt class="field-odd">Returns</dt>
+<dd class="field-odd"><p>{int} – current global max number of evaluation</p>
+</dd>
+</dl>
+</dd></dl>
+
 <dl class="method">
 <dt id="macop.algorithms.Algorithm.Algorithm.increaseEvaluation">
 <code class="sig-name descname">increaseEvaluation</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/macop/algorithms/Algorithm.html#Algorithm.increaseEvaluation"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#macop.algorithms.Algorithm.Algorithm.increaseEvaluation" title="Permalink to this definition">¶</a></dt>

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
docs/build/html/macop/macop.operators.policies.UCBPolicy.html


BIN
docs/build/html/objects.inv


Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
docs/build/html/searchindex.js


+ 0 - 50
docs/source/description.rst

@@ -19,53 +19,3 @@ Just install package using `pip` Python package manager:
 .. code:: bash
    
    pip install macop
-
-
-How to use ?
-------------
-
-Load all `macop` implemented features:
-
-.. code:: python
-    
-   from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
-   from macop.solutions.BinarySolution import BinarySolution
-   from macop.evaluators.EvaluatorExample import evaluatorExample
-
-   from macop.operators.mutators.SimpleMutation import SimpleMutation
-   from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
-   from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
-   from macop.operators.crossovers.RandomSplitCrossover import RandomSplitCrossover
-
-   from macop.operators.policies.RandomPolicy import RandomPolicy
-
-   from macop.checkpoints.BasicCheckpoint import BasicCheckpoint
-
-   # logging configuration
-   logging.basicConfig(format='%(asctime)s %(message)s', filename='example.log', level=logging.DEBUG)
-
-   # default validator
-   def validator(solution):
-      return True
-
-   # define init random solution
-   def init():
-      return BinarySolution([], 30).random(validator)
-
-   filepath = "checkpoints.csv"
-
-   def main():
-
-      operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
-      policy = RandomPolicy(operators)
-
-      algo = ILS(init, evaluatorExample, operators, policy, validator, True)
-      algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath=filepath)
-
-      bestSol = algo.run(425)
-
-      print("Found ", bestSol)
-
-
-   if __name__ == "__main__":
-      main()

+ 246 - 4
docs/source/examples.rst

@@ -1,13 +1,255 @@
 Some examples
 =====================================
 
-Mono-objective example
+1. Mono-objective
 -----------------------
 
-Available soon...
+In this tutorial, it will introduce the way of running your algorithm quickly.
+First of all we need to define the kind of solution best represent the problem. In this tutorial, we use the well known knapsack problem using 30 objects.
 
+1.1 Problem definition
+~~~~~~~~~~~~~~~~~~~~~~
 
-Multi-objective example
-------------------------
+Hence, we define our problem :
+- value of each component of knapsack
+- weight associated to each of these components (objects)
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    import random
+
+    """
+    Problem definition
+    """
+    random.seed(42)
+
+    elements_score = [ random.randint(1, 20) for _ in range(30) ]
+    elements_weight = [ random.randint(5, 25) for _ in range(30) ]
+
+We can now define the solution representation. In knapsack problem we want to fill our knapsack in an optimization way selecting or not each component (object).
+The best way to represent this problem is to use the `BinarySolution` from `macop` which stores solution as a binary array.
+
+Using the solution representation, we need to define multiple things to fit our algorithm :
+- 1. function which validates or not a solution (based on constraints)
+- 2. function which evaluates the solution (in order to obtain fitness)
+- 3. initialization solution function
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    import random
+    from macop.solutions.BinarySolution import BinarySolution
+
+    """
+    Problem definition
+    """
+    random.seed(42)
+
+    elements_score = [ random.randint(1, 20) for _ in range(30) ]
+    elements_weight = [ random.randint(2, 5) for _ in range(30) ]
+
+    # 1. validator function (we accept only bag with maximum weight 80kg)
+    def validator(_solution):
+
+        weight_sum = 0
+        for index, elem in enumerate(_solution.data):
+            weight_sum += elements_weight[index] * elem
+
+        if weight_sum <= 80:
+            return True
+        else:
+            False
+
+    # 2. function which computes fitness of solution
+    def evaluator(_solution):
+
+        fitness = 0
+        for index, elem in enumerate(_solution.data):
+            fitness += (elements_score[index] * elem)
+
+        return fitness
+
+    # 3. function which here initializes solution ramdomly and check validity of solution
+    def init():
+        return BinarySolution([], 30).random(validator)
+
+1.2 Operators and Policy
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+In our algorithm we need to use some operators in order to improve current best solution found at current `n` evaluations.
+
+In `macop` you have some available operators. In this example, we use 3 of them.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    from macop.operators.mutators.SimpleMutation import SimpleMutation
+    from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
+    from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    # list of operators instance to use
+    operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
+
+As we defined multiple operators, we have to tell how we want to select them into the algorithm. This is why **Policy** classes have been implemented.
+`Policy` class implementation enables to select the next operator to use and once new solution is generated, computes its score (in `apply` method). This class requires all the operators use to be instanciate.
+
+Why computing score into **Policy** `apply` method ? Because it's a way to get some important statistics from solution improvment using specific operator.
+**UCBPolicy** as example, based on Upper Confidence Bound (UCB_), computes reward each time a new solution is generated from an operator in order to better select next operator later. We use in this example the `UCBPolicy` implementation.
+
+.. _UCB: https://banditalgs.com/2016/09/18/the-upper-confidence-bound-algorithm/
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    from macop.operators.mutators.SimpleMutation import SimpleMutation
+    from macop.operators.mutators.SimpleBinaryMutation import SimpleBinaryMutation
+    from macop.operators.crossovers.SimpleCrossover import SimpleCrossover
+
+    from macop.operators.policies.UCBPolicy import UCBPolicy
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    # list of operators instance to use
+    operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
+
+    # `policy` instance is created using specific value for Upper Confidence Bound
+    policy = UCBPolicy(operators, C=100.)
+
+1.3 Before running algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before running algorithm we can define a logger to keep track of the all algorithm run.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    import logging
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+We can now instanciate our algorithm. We use the Iterated Local Search in this example. It is mainly used to avoid local optima using multiple local search.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+
+    import logging
+
+    from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+    algo = ILS(init, evaluator, operators, policy, validator, _maximise=True)
+
+The algorithm is now well defined and is ready to run ! But one thing can be done, and it's very interesting to avoir restart from scratch the algorithm run.
+The use of checkpoint is available in `macop`. A `BasicCheckpoint` class let the algorithm save at `every` evaluations the best solution found.
+
+We need to specify the use of checkpoint if we prefer to restart from.
+
+.. code:: python
+    
+    """
+    imports part
+    """
+    ...
+    
+    import logging
+
+    from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
+    from macop.checkpoints.BasicCheckpoint import BasicCheckpoint
+
+    """
+    Problem definition
+    """
+    ...
+
+    """
+    Algorithm parameters
+    """
+    ...
+
+    if not os.path.exists('data'):
+    os.makedirs('data')
+
+    # logging configuration
+    logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
+
+    algo = ILS(init, evaluator, operators, policy, validator, _maximise=True)
+
+    # we specify the checkpoint class directly, the frequency and the path we want to save algorithm evolution
+    algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath='data/checkpoint.csv')
+
+
+In this way, now we can run and obtained the best solution found in `n` evaluations
+
+.. code:: python
+
+    bestSol = algo.run(10000)
+    print('Solution score is {}'.format(evaluator(bestSol)))
+
+2. Multi-objective example
+--------------------------
 
 Available soon...

+ 33 - 4
mainExample.py

@@ -1,6 +1,7 @@
 # main imports
 import logging
 import os
+import random
 
 # module imports
 from macop.algorithms.IteratedLocalSearch import IteratedLocalSearch as ILS
@@ -23,14 +24,39 @@ if not os.path.exists('data'):
 # logging configuration
 logging.basicConfig(format='%(asctime)s %(message)s', filename='data/example.log', level=logging.DEBUG)
 
+random.seed(42)
+
+elements_score = [ random.randint(1, 20) for _ in range(30) ]
+elements_weight = [ random.randint(2, 5) for _ in range(30) ]
+
+def knapsackWeight(_solution):
+
+    weight_sum = 0
+    for index, elem in enumerate(_solution.data):
+        weight_sum += elements_weight[index] * elem
+
+    return weight_sum
+
 # default validator
-def validator(solution):
-    return True
+def validator(_solution):
+
+    if knapsackWeight(_solution) <= 80:
+        return True
+    else:
+        False
 
 # define init random solution
 def init():
     return BinarySolution([], 30).random(validator)
 
+def evaluator(_solution):
+
+    fitness = 0
+    for index, elem in enumerate(_solution.data):
+        fitness += (elements_score[index] * elem)
+
+    return fitness
+
 filepath = "data/checkpoints.csv"
 
 def main():
@@ -38,10 +64,13 @@ def main():
     operators = [SimpleBinaryMutation(), SimpleMutation(), SimpleCrossover(), RandomSplitCrossover()]
     policy = UCBPolicy(operators)
 
-    algo = ILS(init, evaluatorExample, operators, policy, validator, True)
+    algo = ILS(init, evaluator, operators, policy, validator, _maximise=True)
     algo.addCheckpoint(_class=BasicCheckpoint, _every=5, _filepath=filepath)
 
-    bestSol = algo.run(425)
+    bestSol = algo.run(10000)
+
+    print('Solution score is {}'.format(evaluator(bestSol)))
+    print('Solution weigth is {}'.format(knapsackWeight(bestSol)))
 
 if __name__ == "__main__":
     main()

+ 16 - 1
macop/algorithms/Algorithm.py

@@ -3,7 +3,7 @@
 
 # main imports
 import logging
-from ..utils.color import macop_text, macop_line
+from ..utils.color import macop_text, macop_line, macop_progress
 
 
 # Generic algorithm class
@@ -126,6 +126,18 @@ class Algorithm():
 
         return self.numberOfEvaluations
 
+    def getGlobalMaxEvaluation(self):
+        """Get the global max number of evaluation (if inner algorithm)
+
+        Returns:
+            {int} -- current global max number of evaluation
+        """
+
+        if self.parent is not None:
+            return self.parent.maxEvaluations
+
+        return self.maxEvaluations
+
     def stop(self):
         """
         Global stopping criteria (check for inner algorithm too)
@@ -222,6 +234,9 @@ class Algorithm():
         if self.checkpoint is not None:
             self.checkpoint.run()
 
+        macop_progress(self.getGlobalEvaluation(),
+                       self.getGlobalMaxEvaluation())
+
         logging.info("-- %s evaluation %s of %s (%s%%) - BEST SCORE %s" %
                      (type(self).__name__, self.numberOfEvaluations,
                       self.maxEvaluations, "{0:.2f}".format(

+ 0 - 1
macop/checkpoints/BasicCheckpoint.py

@@ -95,7 +95,6 @@ class BasicCheckpoint(Checkpoint):
                 macop_text(
                     'No backup found... Start running algorithm from evaluation 0.'
                 ))
-            print(macop_line())
             logging.info(
                 "Can't load backup... Backup filepath not valid in Checkpoint")
 

+ 5 - 1
macop/evaluators/EvaluatorExample.py

@@ -1,6 +1,10 @@
 """Python evaluator function example
 """
 
+import random
+
+elements_score = [random.randint(1, 20) for _ in range(30)]
+
 
 # evaluator example
 def evaluatorExample(_solution):
@@ -15,6 +19,6 @@ def evaluatorExample(_solution):
     """
     fitness = 0
     for index, elem in enumerate(_solution.data):
-        fitness = fitness + (elem * index)
+        fitness += elements_score[index] * elem
 
     return fitness

+ 1 - 1
macop/operators/policies/UCBPolicy.py

@@ -18,7 +18,7 @@ class UCBPolicy(Policy):
         rewards: {[float]} -- list of summed rewards obtained for each operator
         occurences: {[int]} -- number of use (selected) of each operator
     """
-    def __init__(self, _operators, _C=10.):
+    def __init__(self, _operators, _C=1000.):
         self.operators = _operators
         self.rewards = [0. for o in self.operators]
         self.occurences = [0 for o in self.operators]

+ 30 - 0
macop/utils/color.py

@@ -1,3 +1,6 @@
+import sys
+
+
 class Colors:
     ENDC = '\033[m'
     GREEN = '\033[32m'
@@ -25,3 +28,30 @@ def macop_line():
             line += Colors.GREY + '----' + Colors.ENDC
 
     return line
+
+
+def macop_progress(evaluations, max):
+
+    barWidth = 156
+
+    progress = evaluations / float(max)
+
+    output_str = Colors.GREEN + '[' + Colors.ENDC
+    pos = int(barWidth * progress)
+    for i in range(barWidth):
+        if i < pos:
+            output_str = output_str + Colors.GREY + '=' + Colors.ENDC
+        elif i == pos:
+            output_str = output_str + Colors.GREEN + '>' + Colors.ENDC
+        else:
+            output_str = output_str + Colors.GREY + ' ' + Colors.ENDC
+
+    output_str = output_str + Colors.GREEN + '] ' + Colors.ENDC + str(
+        int(progress * 100.0)) + "%\r"
+    print(output_str)
+    sys.stdout.write("\033[F")
+
+    # go to line
+    if progress >= 1.:
+        print()
+        print(macop_line())