diff --git a/Mesh/mwis.hpp b/Mesh/mwis.hpp
index 4d90fe76c6eb780cbac52adb2e7e4559ac66ecd0..fe8ee1f887de9395f86ee368dd200dd175737827 100644
--- a/Mesh/mwis.hpp
+++ b/Mesh/mwis.hpp
@@ -111,7 +111,7 @@ class lagrangian_bound {
   typedef boost::iterator_property_map<
     std::vector<bool>::iterator, index_map> selected_map_type;
   typedef boost::iterator_property_map<
-    std::vector<std::vector<size_t>>::iterator, index_map> clique_map_type;
+    std::vector< std::vector<size_t> >::iterator, index_map> clique_map_type;
   typedef boost::iterator_property_map<
     typename std::vector<weight>::iterator, index_map> weight_map_type;
 
@@ -119,11 +119,11 @@ class lagrangian_bound {
   WeightMap _weight;
   size_t _max_size;
 
-  std::vector<std::vector<vertex>> _clique_contents;
+  std::vector< std::vector<vertex> > _clique_contents;
 
   std::vector<weight> _lambda, _gradient;
 
-  std::vector<std::vector<size_t>> _clique_storage;
+  std::vector< std::vector<size_t> > _clique_storage;
   std::vector<bool> _selected_storage;
   std::vector<weight> _effective_weight_storage;
 
@@ -767,7 +767,7 @@ class evaluator {
   typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex;
   typedef typename boost::property_traits<WeightMap>::value_type weight;
 
-  std::vector<std::vector<vertex>> _cliques;
+  std::vector< std::vector<vertex> > _cliques;
   size_t _limit;
 public:
   typedef weight result_type;
@@ -795,16 +795,28 @@ public:
 template<typename Graph, typename WeightMap>
 struct lns_state {
   typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex;
+  typedef typename boost::property_map<
+    Graph, boost::vertex_index_t>::type index_map;
+  typedef boost::iterator_property_map<
+    std::vector<bool>::iterator, index_map> solution_map_type;
 
   const Graph &graph;
   WeightMap weight_map;
 
-  std::vector<vertex> solution;
+  std::vector<bool> solution_storage;
+  solution_map_type solution;
 
   lns_state(const Graph &graph, WeightMap weight_map,
-            const std::vector<vertex> &solution):
-    graph(graph), weight_map(weight_map), solution(solution)
-    {}
+            const std::vector<vertex> &initial_solution):
+    graph(graph), weight_map(weight_map),
+    solution_storage(num_vertices(graph), false) {
+    index_map ids = boost::get(boost::vertex_index, graph);
+    solution = make_iterator_property_map(solution_storage.begin(), ids);
+
+    for (std::size_t i = 0; i < initial_solution.size(); i++) {
+      put(solution, initial_solution[i], true);
+    }
+  }
 };
 
 template<typename Graph>
@@ -855,7 +867,7 @@ public:
  * visited edge into a set.
  */
 template<typename Graph, typename Tag>
-class set_recorder : public boost::base_visitor<set_recorder<Graph, Tag>> {
+class set_recorder : public boost::base_visitor< set_recorder<Graph, Tag> > {
   typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex;
   typedef typename boost::graph_traits<Graph>::edge_descriptor edge;
 
@@ -930,104 +942,94 @@ class lns_search {
   typedef typename boost::graph_traits<Graph>::out_edge_iterator out_edge_iterator;
   typedef typename boost::property_traits<WeightMap>::value_type weight;
 
-  std::vector<std::vector<vertex>> _cliques;
+  typedef typename boost::property_map<
+    Graph, boost::vertex_index_t>::type index_map;
+  typedef boost::iterator_property_map<
+    std::vector< std::vector<size_t> >::iterator, index_map> clique_map_type;
+
+  const Graph &_graph;
+
+  std::vector< std::vector<vertex> > _clique_contents;
+
+  std::vector< std::vector<std::size_t> > _clique_storage;
+  clique_map_type _cliques;
 public:
   typedef lns_assignment<Graph> result_type;
   typedef lns_state<Graph, WeightMap> first_argument_type;
   typedef lns_fragment<Graph> second_argument_type;
 
   template<typename Iterator>
-  lns_search(Iterator begin, Iterator end): _cliques(begin, end) {}
-
-  lns_assignment<Graph> operator()(const lns_state<Graph, WeightMap> &l_state,
-                                   const lns_fragment<Graph> &fragment) const {
-    state<Graph, WeightMap> search_state(l_state.graph, l_state.weight_map,
-                                         _cliques.begin(), _cliques.end());
-
-    std::vector<vertex> selected_vertex;
-    std::set<vertex> removed;
-    std::set<size_t> assigned;
-
-    weight new_weight(0);
-
-    for (std::size_t i = 0; i < l_state.solution.size(); i++) {
-      vertex v = l_state.solution[i];
-
-      if (fragment.vertices.find(v) != fragment.vertices.end())
-        continue;
-
-      selected_vertex.push_back(v);
+  lns_search(const Graph &graph, Iterator begin, Iterator end):
+    _graph(graph), _clique_contents(begin, end) {
+    size_t vertex_count = num_vertices(graph);
+    _clique_storage.resize(vertex_count);
 
-      new_weight += get(l_state.weight_map, v);
+    index_map ids = boost::get(boost::vertex_index, graph);
+    _cliques = make_iterator_property_map(_clique_storage.begin(),ids);
 
-      std::pair<out_edge_iterator, out_edge_iterator> edges =
-        out_edges(v, l_state.graph);
-      for (out_edge_iterator eit = edges.first; eit != edges.second; eit++) {
-        const vertex &other = target(*eit, l_state.graph);
-        removed.insert(other);
+    size_t i = 0;
+    for (Iterator it = begin; it != end; it++, i++) {
+      for (typename std::vector<vertex>::const_iterator v_it = it->begin();
+           v_it != it->end(); v_it++) {
+        get(_cliques, *v_it).push_back(i);
       }
-
-      const std::vector<std::size_t> &clique = get(search_state.clique_map, v);
-      for (size_t i = 0; i < clique.size(); i++)
-        assigned.insert(clique[i]);
     }
+  }
 
-    std::pair<vertex_iterator, vertex_iterator> vs = boost::vertices(l_state.graph);
-    for (vertex_iterator it = vs.first; it != vs.second; it++) {
-      vertex v = *it;
-      if (fragment.vertices.find(v) == fragment.vertices.end())
-        removed.insert(v);
-    }
+  lns_assignment<Graph> operator()(const lns_state<Graph, WeightMap> &l_state,
+                                   const lns_fragment<Graph> &fragment) const {
 
-    std::map<size_t, size_t> size_delta;
-    for (typename std::set<vertex>::const_iterator it = removed.begin();
-         it != removed.end(); it++) {
-      vertex v = *it;
+    std::set<std::size_t> clique_ids;
 
-      const std::vector<vertex> &cliques = get(search_state.clique_map, v);
-      for (std::size_t i = 0; i < cliques.size(); i++) {
-        std::size_t clique = cliques[i];
+    weight best_value(0);
+    std::vector<vertex> best_solution;
 
-        size_delta[clique]++;
-        if (size_delta[clique] == search_state.clique_sizes[clique]) {
-          assigned.insert(clique);
-        }
+    for (typename std::set<vertex>::const_iterator it =
+           fragment.vertices.begin();
+         it != fragment.vertices.end(); it++) {
+      const std::vector<size_t> cs = get(_cliques, *it);
+      std::copy(cs.begin(), cs.end(),
+                std::inserter(clique_ids, clique_ids.begin()));
+
+      if (get(l_state.solution, *it)) {
+        best_value += get(l_state.weight_map, *it);
+        best_solution.push_back(*it);
       }
     }
 
-    std::vector<size_t> assigned_v(assigned.begin(), assigned.end());
-    std::vector<vertex> removed_v(removed.begin(), removed.end());
-
-    state_change<Graph, WeightMap> delta(
-      assigned_v, size_delta,
-      selected_vertex, removed_v,
-      weight(0), new_weight);
+    std::vector< std::vector<vertex> > selectable_cliques;
+    for (std::set<std::size_t>::const_iterator it = clique_ids.begin();
+         it != clique_ids.end(); it++) {
+      std::vector<vertex> data = _clique_contents[*it];
+      data.erase(
+        std::remove_if(data.begin(), data.end(),
+                       std::not1(make_set_membership_test(fragment.vertices))),
+        data.end());
+
+      if (data.size() != 0)
+        selectable_cliques.push_back(data);
+    }
 
-    delta.apply(search_state);
+    state<Graph, WeightMap> search_state(
+      l_state.graph, l_state.weight_map,
+      selectable_cliques.begin(),
+      selectable_cliques.end());
 
     lagrangian_bound<Graph, WeightMap>
       bound(l_state.graph, l_state.weight_map,
-            _cliques.begin(), _cliques.end());
+            selectable_cliques.begin(),
+            selectable_cliques.end());
 
     visit_state<Graph, WeightMap> visitor;
-    visitor.best_solution = l_state.solution;
-    visitor.best_value = weight(0);
-    for (std::size_t i = 0; i < visitor.best_solution.size(); i++)
-      visitor.best_value += get(l_state.weight_map, visitor.best_solution[i]);
+    visitor.best_solution = best_solution;
+    visitor.best_value = best_value;
 
     successor<Graph, WeightMap, lagrangian_bound<Graph, WeightMap> > successor(
       bound, visitor.best_value);
 
     search::depth_first_search(search_state, visitor, successor);
 
-    std::vector<vertex> newly_selected;
-    for (std::size_t i = 0; i < visitor.best_solution.size(); i++) {
-      vertex v = visitor.best_solution[i];
-      if (fragment.vertices.find(v) != fragment.vertices.end())
-        newly_selected.push_back(v);
-    }
-
-    return lns_assignment<Graph>(newly_selected);
+    return lns_assignment<Graph>(visitor.best_solution);
   }
 };
 
@@ -1081,7 +1083,7 @@ void find_cliques(const Graph &graph, OutputIterator out) {
   typedef typename boost::graph_traits<Graph>::edge_iterator edge_iterator;
   typedef typename boost::graph_traits<Graph>::out_edge_iterator out_edge_iterator;
 
-  std::set<std::pair<vertex, vertex>> visited_edges;
+  std::set< std::pair<vertex, vertex> > visited_edges;
 
   std::pair<edge_iterator, edge_iterator> es = edges(graph);
   for (edge_iterator eit = es.first; eit != es.second; eit++) {
@@ -1139,7 +1141,7 @@ void maximum_weight_independent_set(const Graph &graph, WeightMap weight_map,
   typedef typename boost::graph_traits<Graph>::vertex_iterator vertex_iterator;
   typedef typename boost::property_traits<WeightMap>::value_type weight;
 
-  std::vector<std::vector<vertex>> cliques;
+  std::vector< std::vector<vertex> > cliques;
   mwis::find_cliques(graph, std::back_inserter(cliques));
 
   mwis::lagrangian_bound<Graph, WeightMap> bound(