diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5466067ab2e3eea943fb63174ab2da7056338bc..96feadf83e7a405968380ac25da9ba5a57283f6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,7 +38,8 @@ add_executable(pdptw src/mains/main.cpp
                 src/lns/operators/sorting_strategy.cpp
                 src/lns/operators/destruction/random_destroy.cpp
                 src/lns/operators/reconstruction/enumerate.cpp
-                src/lns/operators/reconstruction/list_heuristic_insertion.hpp
+                src/lns/operators/reconstruction/list_heuristic_insertion.cpp
+                src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp
                 src/lns/operators/selector/operator_selection.cpp
                 src/utils.cpp
                 )
diff --git a/src/lns/operators/reconstruction/enumerate.cpp b/src/lns/operators/reconstruction/enumerate.cpp
index 24fabb6eb39e9bd05a5b5d78d9dc4b2d57a8419e..5a060def9c8faf37be68fe748dc790e39447cbde 100644
--- a/src/lns/operators/reconstruction/enumerate.cpp
+++ b/src/lns/operators/reconstruction/enumerate.cpp
@@ -2,17 +2,6 @@
 
 namespace enumeration
 {
-
-    template<std::derived_from<AtomicRecreation> ModificationType>
-    void addToListIfValidTemplate(Solution const &solution, ModificationType const &modification, ModificationContainer &list)
-    {
-        if (solution.checkModification(modification))
-        {
-            std::cout << " => Insert Modification" << "\n";
-            list.push_front(std::make_unique<ModificationType>(modification));
-        }
-    }
-
     /**
      * Enumerate InsertPair modifications.
      * Does some checks to cut some loops. (TO DO)
@@ -20,19 +9,28 @@ namespace enumeration
      * @param pair
      * @param ModificationContainer
      */
-    void enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list)
+    void enumerateAllInsertPair(Solution const &solution, Pair const &pair, std::function<void(InsertPair &&)> const &consumeModification)
     {
         int routeIndex = 0;
         // Insert into existing routes
         for (Route const &route: solution.getRoutes())
         {
-            for (int p = 0; p <= route.getSize(); p++)
+            int routeSize = route.getSize();
+            for (int p = 0; p <= routeSize; ++p)
             {
-                for (int d = p; d <= route.getSize(); d++)
+                for (int d = p; d <= routeSize; ++d)
                 {
                     Index index = std::make_tuple(routeIndex, p, d);
-                    // add to list if valid modification
-                    enumeration::addToListIfValidTemplate(solution, InsertPair(index, pair), list);
+
+                    consumeModification(InsertPair(index,pair));
+
+                    // std::unique_ptr<InsertPair> modification = std::make_unique<InsertPair>(index, pair);
+                    // // add to list if valid modification
+                    // if (solution.checkModification(*modification))
+                    // {
+                    //     std::cout << " => Insert Modification\n";
+                    //     list.push_front(std::move(modification));
+                    // }
                 }
             }
             ++routeIndex;
diff --git a/src/lns/operators/reconstruction/enumerate.h b/src/lns/operators/reconstruction/enumerate.h
index 22cd2e29dca75f2ba6a0942c3fbd29eaf7252d0c..47ba175ba4d22be88ecea7490e549ddaf7bb1017 100644
--- a/src/lns/operators/reconstruction/enumerate.h
+++ b/src/lns/operators/reconstruction/enumerate.h
@@ -24,7 +24,7 @@ namespace enumeration
      * @param Pair
      * @param list
      */
-    void enumerateAllInsertPair(Solution const &solution, Pair const &Pair, ModificationContainer &list);
+    void enumerateAllInsertPair(Solution const &solution, Pair const &pair, std::function<void(InsertPair &&)> const &consumeModification);
 
 
 }// namespace enumeration
diff --git a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..47896e8c53b2db1b75a65a724f4be1d9fdf82fb1
--- /dev/null
+++ b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp
@@ -0,0 +1,53 @@
+#include "list_heuristic_cost_oriented.h"
+
+void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
+                                                    EnumerationType enumeration) const
+{
+    std::vector<int> sortedPairs;
+    // selection strategy
+    switch (strategy)
+    {
+        case SortingStrategyType::SHUFFLE: {
+            std::cout << " \n(Shuffle)\n";
+            // copy
+            sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
+            break;
+        }
+        default:
+            spdlog::error("Error, invalid strategy selected.");
+            throw std::invalid_argument("Invalid sorting strategy selected.");
+            break;
+    }
+
+    for (int pairID: sortedPairs)
+    {
+        Pair const &pair = solution.getData().getPair(pairID);
+
+        AtomicRecreationPtr bestRecreation;
+        double bestRecreationCost = std::numeric_limits<double>::max();
+
+        // Enumeration strategy
+        switch (enumeration)
+        {
+            case EnumerationType::ALL_INSERT_PAIR: {
+                std::cout << " \n(All insert pair) \n";
+                enumeration::enumerateAllInsertPair(
+                        solution,
+                        pair,
+                        keepBestSolution<InsertPair>(solution, bestRecreation, bestRecreationCost, blinkRate));
+
+                break;
+            }
+            default:
+                spdlog::error("Error, invalid enumeration selected.");
+                throw std::invalid_argument("Invalid enumeration strategy selected.");
+                break;
+        }
+
+        if (bestRecreation)
+        {
+            std::cout << "\n --- Apply recreation --- \n";
+            solution.applyRecreateSolution(*bestRecreation);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h
new file mode 100644
index 0000000000000000000000000000000000000000..24c633f9f92e0a0272349470b72ff2f00276e089
--- /dev/null
+++ b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "input/data.h"
+#include "input/pdptw_data.h"
+#include "lns/operators/abstract_operator.h"
+#include "lns/operators/sorting_strategy.h"
+#include "utils.h"
+
+/**
+ * List heuristic operator but evaluates costs before trying to know if the modification is feasible
+ */
+class ListHeuristicCostOriented : public ReconstructionOperator
+{
+public:
+    using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>;
+    void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
+                             EnumerationType enumeration) const override;
+};
+
+/**
+ * Create a function that will consume all the enumerated modifications
+ * @tparam ModificationType The type of modification enumerated
+ * @param bestModificationPtr the pointer to the actual best modification found yet
+ * @param bestCost the cost of the best modification
+ * @param blinkRate blinking rate
+ */
+template<std::derived_from<AtomicRecreation> ModificationType>
+std::function<void(ModificationType &&)> keepBestSolution(Solution const &solution,
+                                                          std::unique_ptr<AtomicRecreation> &bestModificationPtr,
+                                                          double &bestCost, double blinkRate)
+{
+    return [&](ModificationType &&modification) {
+        double cost = modification.evaluate(solution);
+        // first test the cost
+        // if the modification is better, then blink,
+        // then check the modification
+        // then store the best cost and the modification to the pointer
+        if (cost < bestCost && util::getRandom() >= blinkRate && solution.checkModification(modification))
+        {
+            std::cout << " => Better Modification, update pointer"
+                      << "\n";
+            bestModificationPtr = std::make_unique<ModificationType>(modification);
+            bestCost = cost;
+        }
+    };
+}
diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp b/src/lns/operators/reconstruction/list_heuristic_insertion.cpp
similarity index 75%
rename from src/lns/operators/reconstruction/list_heuristic_insertion.hpp
rename to src/lns/operators/reconstruction/list_heuristic_insertion.cpp
index fa241231917fc9494d1265b7501fa0d7b67d520d..bbe4dedecc7b2af810ed6a6318bcde342ea448fe 100644
--- a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp
+++ b/src/lns/operators/reconstruction/list_heuristic_insertion.cpp
@@ -1,10 +1,7 @@
-#pragma once
 
 #include "list_heuristic_insertion.h"
 #include "lns/operators/sorting_strategy.h"
 #include "enumerate.h"
-// This is a header, but it does define templates, so we can't put them in .cpp file
-// for forward declaration you can use the .h file, but if you need to use the class, you must include this one instead
 
 
 #include <concepts>
@@ -20,11 +17,13 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
         case SortingStrategyType::SHUFFLE: 
         {
             std::cout << " \n(Shuffle)\n";
+            // copy
             sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
             break;
         }
         default:
-            spdlog::error("Error, strategy selected.");
+            spdlog::error("Error, invalid strategy selected.");
+            throw std::invalid_argument("Invalid sorting strategy selected.");
             break;
     }
 
@@ -32,7 +31,7 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
     for (int pairID: sortedPairs)
     {
         Pair const &pair = solution.getData().getPair(pairID);
-        recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate, enumeration);
+        recreation = ListHeuristicInsertion::selectRecreation(solution, pair, blinkRate, enumeration);
         if (recreation)
         {
             std::cout << "\n --- Apply recreation --- \n";
@@ -41,27 +40,26 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
     }
 }
 
-std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::choosingStrategy(Solution &solution, Pair const &pair,
+std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::selectRecreation(Solution &solution, Pair const &pair,
                                                                            double blinkRate, EnumerationType enumeration)
 {
     AtomicRecreationPtr bestInsertion;
     double bestKnownInsertionCost = std::numeric_limits<double>::max();
 
     enumeration::ModificationContainer modifications;
-    //Generator().populate(solution, pair, modifications);
-    //
 
     // Enumeration strategy
     switch (enumeration) {
         case EnumerationType::ALL_INSERT_PAIR: 
         {
             std::cout << " \n(All insert pair) \n";
-            //enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list)
-            enumeration::enumerateAllInsertPair(solution, pair, modifications);
+            enumeration::enumerateAllInsertPair(solution, pair, addToListIfValidTemplate<InsertPair>(solution, modifications));
+            
             break;
         }
         default:
-            spdlog::error("Error, enumeration selected.");
+            spdlog::error("Error, invalid enumeration selected.");
+            throw std::invalid_argument("Invalid enumeration strategy selected.");
             break;
     }
 
diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.h b/src/lns/operators/reconstruction/list_heuristic_insertion.h
index 895a47cdc6d2490781726f0b93af93dbd63580c9..395f88e29ea1a1b7dd1611b2ff68369d3ed29ff2 100644
--- a/src/lns/operators/reconstruction/list_heuristic_insertion.h
+++ b/src/lns/operators/reconstruction/list_heuristic_insertion.h
@@ -24,13 +24,36 @@ private:
 public:
     explicit ListHeuristicInsertion();
 
-    void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const override;
+    void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
+                             EnumerationType enumeration) const override;
 
 private:
     /**
      * @param blinkRate probability to ignore the request insertion
      * @return the best insertion found
      */
-    static std::unique_ptr<AtomicRecreation> choosingStrategy(Solution &solution, Pair const &pair,
-                                                              double blinkRate, EnumerationType enumeration);
+    static std::unique_ptr<AtomicRecreation> selectRecreation(Solution &solution, Pair const &pair, double blinkRate,
+                                                              EnumerationType enumeration);
 };
+
+/**
+ * Used in enumerate.cpp functions to evaluate modification
+ * Do not evaluate cost (see list_heuristic_cost_oriented that evaluate cost before feasability)
+ * @tparam ModificationType the type of modification to be checked
+ * @param solution the solution to check the modification validity
+ * @param list the modification will be added to this list if valid
+ * @return a function that takes a ModificationType and add it to list iff it is valid
+ */
+template<std::derived_from<AtomicRecreation> ModificationType>
+std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const &solution,
+                                                                  enumeration::ModificationContainer &list)
+{
+    return [&](ModificationType &&modification) {
+        if (solution.checkModification(modification))
+        {
+            std::cout << " => Insert Modification"
+                      << "\n";
+            list.push_front(std::make_unique<ModificationType>(modification));
+        }
+    };
+}
\ No newline at end of file
diff --git a/src/mains/main.cpp b/src/mains/main.cpp
index 654c5c9c6997d93a002bf07e59cbe1b28190a8f7..c3ed313e0f985dd797044b2a8f55842e32e779d2 100644
--- a/src/mains/main.cpp
+++ b/src/mains/main.cpp
@@ -14,6 +14,7 @@
 #include "input/data.h"
 #include "lns/constraints/capacity/capacity_constraint.h"
 #include "lns/constraints/time_window/time_window_constraint.h"
+#include "lns/operators/reconstruction/list_heuristic_cost_oriented.h"
 #include "lns/solution/solution.h"
 #include "lns/modification/pair/insert_pair.h"
 #include "lns/modification/route/insert_route.h"
@@ -21,7 +22,6 @@
 #include "lns/modification/route/remove_route.h"
 
 #include "lns/operators/reconstruction/list_heuristic_insertion.h"
-#include "lns/operators/reconstruction/list_heuristic_insertion.hpp"
 #include "lns/operators/sorting_strategy.h"
 
 #include "lns/operators/reconstruction/enumerate.h"
@@ -76,8 +76,11 @@ int main(int argc, char const *argv[])
 
     std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR  -> reconstruction (NO COST UPDATE)\n";
 
-    ListHeuristicInsertion heuristicInsertion;
-    heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
+    //ListHeuristicInsertion heuristicInsertion;
+    //heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
+
+    ListHeuristicCostOriented heuristic;
+    heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
 
     solution.print();