diff --git a/README.md b/README.md
index d894bc1d9b395db0e7e8580b9d248ba349948973..a305b5fe4b400c77275ce0365fd75a9f9376a87d 100644
--- a/README.md
+++ b/README.md
@@ -18,11 +18,11 @@ If you use the code from this repository, please cite
     publisher = {},
 }
 ```
-For questions, please contact elina.ronnberg@liu.se
+For questions, please contact lukas.eveborn@liu.se
 
 ### Electric Vehicle Routing Problem with Time  Windows and Piecewise Linear Charging Function
 The instances that we use were introduced by M. Schneider, A. Stenger and D. Goeke *The Electric Vehicle-Routing Problem with Time Windows and Recharging Stations*, and can be found at https://data.mendeley.com/datasets/h3mrm5dhxw/1
-These instances are based on the benchmark indtances for the VRP of M.M. Solomon *Algorithms for the Vehicle Routing and Scheduling Problems with Time Window Constraints*.
+These instances are based on the benchmark instances for the VRP of M.M. Solomon *Algorithms for the Vehicle Routing and Scheduling Problems with Time Window Constraints*.
 
 ## Code 
 The code that was used in the paper is found in this repository.
diff --git a/src/evrp_data_subproblem.h b/src/evrp_data_subproblem.h
index 9ed16b564d5ca9b6d80c9c0f7e25ba7393b8632e..1614aa11bb3686aa8dfe3dfb356938b9fd8899b0 100644
--- a/src/evrp_data_subproblem.h
+++ b/src/evrp_data_subproblem.h
@@ -34,7 +34,9 @@ struct Node
     double min_time_arc;
     double min_fuel_arc;
 
-    double min_time_incoming;
+    double min_time_incoming_ng; 
+    double min_time_outgoing_ng;
+
 };
 
 struct Arc
diff --git a/src/labelling_algorithm.cpp b/src/labelling_algorithm.cpp
index 9e68e2ff1a428cc32cd30393311eb122b05fb2ad..8e5a38014f222385a2123a95686085ac5da097be 100644
--- a/src/labelling_algorithm.cpp
+++ b/src/labelling_algorithm.cpp
@@ -671,16 +671,6 @@ void LabellingAlgorithm::assign_min_arc()
         least_arc_costs.push_back(make_tuple(nodes.uniqueNodeIndex, cost / nodeInfo[nodes.uniqueNodeIndex].demand));
         least_arc_time.push_back(make_tuple(nodes.uniqueNodeIndex, cost / (time + (refuel / charging_rates[0]))));
 
-        // Incoming arcs to compute multiplicity of visits in ng-completion
-        time = 1000;
-        for (auto incoming : nodes.incomingNodes)
-        {
-            if (nodeInfo[incoming].nodeType != 'f')
-            {
-                time = min(time, arcInfo[incoming][nodes.uniqueNodeIndex].time + nodeInfo[incoming].serviceTime);
-            }
-        }
-        nodeInfo[nodes.uniqueNodeIndex].min_time_incoming = time;
     }
     sort(least_arc_costs.begin(), least_arc_costs.end(), compare_cost); // sort the queues cost/demand and cost/(time+refueltime) in increasing order (most negative value first)
     sort(least_arc_time.begin(), least_arc_time.end(), compare_cost);
@@ -1049,6 +1039,28 @@ void LabellingAlgorithm::get_ng_sets(int size)
         closest.push_back(node.uniqueNodeIndex); // insert node itself into ints ng-set
         ng_set[node.uniqueNodeIndex] = closest;
     }
+
+
+    //find the node k closest to node i, such that i is not in the ng-set of k
+    for(auto node: nodeInfo){
+        double closest_incoming=1000000;
+        double closest_outgoing=1000000;
+        for(auto next: nodeInfo){ //check all  arcs
+            if(next.nodeType=='f'){
+                continue;
+            }
+            else{
+                int neighbour=next.uniqueNodeIndex;
+                if(find(ng_set[neighbour].begin(),ng_set[neighbour].end(),node.uniqueNodeIndex)==ng_set[neighbour].end()){
+                    closest_incoming=min(closest_incoming,arcInfo[node.uniqueNodeIndex][neighbour].time+nodeInfo[neighbour].serviceTime);
+                    closest_outgoing=min(closest_outgoing,arcInfo[node.uniqueNodeIndex][neighbour].time+nodeInfo[node.uniqueNodeIndex].serviceTime);
+                }
+            }
+        }
+        node.min_time_incoming_ng=closest_incoming;
+        node.min_time_outgoing_ng=closest_outgoing;
+    }
+
 }
 
 /**
@@ -1155,13 +1167,7 @@ double LabellingAlgorithm::get_capacity_bound(Label* label, bool ng)
     
     double cost=nodeInfo[labelNode].min_cost_arc;
     double resource_left=maxResource.capacity-label->capacity;
-
     double earliest_start_time=label->tMin+nodeInfo[labelNode].serviceTime;
-       
-    vector<tuple<int,int,int>> visited_in_completion; //node identifier, multiple of visits, maximum visits
-    visited_in_completion.reserve(20);
-
-
     int i=0;    
     while(i<least_arc_costs.size()){
         int currNode=get<0>(least_arc_costs[i]);
@@ -1170,67 +1176,21 @@ double LabellingAlgorithm::get_capacity_bound(Label* label, bool ng)
             continue;
         }
         if(label->visitedForDominance[currNode]==0 || ng){    //node has not been visited before
-            if(ng){ 
-                //add nodes to completion calculate the number of times it can be visited
-                int completion_size=visited_in_completion.size();
-                if(completion_size<2){  //special case when adding the first two nodes
-                    if(earliest_start_time+arcInfo[labelNode][currNode].time>nodeInfo[currNode].dueDate){
-                        i++;    //find first customer node that is reachable
-                        continue;
-                    }
-                    if(completion_size==0 && label->visitedForDominance[currNode]==1){  //if first node in completion, and label remembers first node
-                        int k=i+1;                                                     //find best node that is not remembered and can be reached
-                        while(k<least_arc_costs.size()){
-                            if(label->visitedForDominance[get<0>(least_arc_costs[k])]==0 && earliest_start_time+arcInfo[labelNode][get<0>(least_arc_costs[k])].time<=nodeInfo[get<0>(least_arc_costs[k])].dueDate){
-                                currNode=get<0>(least_arc_costs[k]); //k is reachable, not remebered by the label, and not a charging node
-                                i=i-1;  //the recent i was not added in the completion, but is valid
-                                break;
-                            }
-                            else{
-                                k++;
-                            }
-                        }
-                    }
-
-                    double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);
-                    int multiplicity=ceil((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_arc+nodeInfo[currNode].min_time_incoming));
-                    visited_in_completion.emplace_back(make_tuple(currNode,1,multiplicity));
-                    i++;
-                    
-                }
-                else{
-                    tuple<int,int,int> node=visited_in_completion[completion_size-2];
-                    if(get<1>(node)<get<2>(node)){  //check if any node can still be revisited. Reachability must not be tested here
-                        visited_in_completion.emplace_back(make_tuple(get<0>(node), get<1>(node)+1,get<2>(node)));
-                        currNode=get<0>(node);
-                    }
-                    else if(earliest_start_time+arcInfo[labelNode][currNode].time>nodeInfo[currNode].dueDate){  //verify reachability of new node
-                        i++;
-                        continue;
-                    }
-                    else{
-                        double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);  //add new node
-                        int multiplicity=ceil((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_arc+nodeInfo[currNode].min_time_incoming));
-                        visited_in_completion.emplace_back(make_tuple(currNode,1,multiplicity));
-                        i++;
-                    }
-                }
-            }    
-
             if(nodeInfo[currNode].min_cost_arc>=0){
-                if(ng){
-                    if(visited_in_completion.size()!=1){    //the first added node may have positive cost
-                        break;
-                    }
-                }
-                else{
-                    break;
-                }
+                break;
             }
             
+            double multiplicity=1;
+            if(ng){ //must check if it can be reached!
+                double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);
+                if(start_time>nodeInfo[currNode].dueDate){
+                    i++;
+                    continue;
+                }
+                multiplicity=floor((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_outgoing_ng+nodeInfo[currNode].min_time_incoming_ng))+1;
+            }
             float value;
-            value=min((double)1,resource_left/nodeInfo[currNode].demand);
-        
+            value=min((double)multiplicity,resource_left/nodeInfo[currNode].demand);
             resource_left=resource_left-(nodeInfo[currNode].demand*value);
             cost=cost+(nodeInfo[currNode].min_cost_arc*value);
             
@@ -1239,18 +1199,14 @@ double LabellingAlgorithm::get_capacity_bound(Label* label, bool ng)
             }
         }
                       
-        if(!ng){
-            i++;
-        }
-    }
-    if(ng){
-        return(min(cost,nodeInfo[labelNode].min_cost_arc));
-    }
-    else{
-        return(cost);
+        i++;
     }
+    
+    return(cost);
 }
 
+
+
 /**
  * \fn time_bound_special
  * \brief adapted knapsack time bounds with battery constraints
@@ -1269,13 +1225,11 @@ double LabellingAlgorithm::get_time_bound(Label* label, bool ng)
     }
     
     double resource_left=maxResource.tMin-label->tMin-nodeInfo[labelNode].min_time_arc-added_time;   //reduce time availability 
-
     double earliest_start_time=label->tMin+nodeInfo[labelNode].serviceTime;
     
     double added_charging;
     double required_charging;
-    vector<tuple <int,int,int>> visited_in_completion;  //node identifier, multiplicity of visits, maximum visits
-    visited_in_completion.reserve(15);
+    
     int i=0; 
     while(i<least_arc_time.size()){   
 
@@ -1286,89 +1240,33 @@ double LabellingAlgorithm::get_time_bound(Label* label, bool ng)
             continue;
         }
         else if(label->visitedForDominance[currNode]==0 || ng){ 
-            if(ng){ 
-                // add nodes to completion and calculate the number of times it can be visited
-                int completion_size=visited_in_completion.size();
-                
-                if(completion_size<2){  //special case for first two nodes int the completion
-                    if(label->tMin+nodeInfo[labelNode].serviceTime+arcInfo[labelNode][currNode].time>nodeInfo[currNode].dueDate){
-                        i++;    //find first customer node in list that is reachable
-                        continue;
-                    }
-                    if(completion_size==0 && label->visitedForDominance[currNode]==1){ //first node in completion may not be rememebered byt the label
-                        int k=i+1;  
-                        while(k<least_arc_time.size()){
-                            if(label->visitedForDominance[get<0>(least_arc_time[k])]==0 && label->tMin+nodeInfo[labelNode].serviceTime+arcInfo[labelNode][get<0>(least_arc_time[k])].time<=nodeInfo[get<0>(least_arc_time[k])].dueDate && nodeInfo[get<0>(least_arc_time[k])].nodeType!='f'){
-                                currNode=get<0>(least_arc_time[k]);
-                                i=i-1;  //i is valid, and has not been added to completion
-                                break;
-                            }
-                            else{
-                                k++;
-                            }
-                        }
-                    }
-                    double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);
-                    int multiplicity=ceil((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_arc+nodeInfo[currNode].min_time_incoming));
-                    visited_in_completion.emplace_back(make_tuple(currNode,1,multiplicity));
-                    i++;   
-                }
-                else{
-                    tuple<int,int,int>node=visited_in_completion[completion_size-2];
-                    
-                    if(get<1>(node)<get<2>(node)){ //check second to last node can still be revisited. Reachability must not be tested
-                        visited_in_completion.emplace_back(make_tuple(get<0>(node), get<1>(node)+1,get<2>(node)));
-                        currNode=get<0>(node);
-                        
-                    }
-                    else if(label->tMin+nodeInfo[labelNode].serviceTime+arcInfo[labelNode][currNode].time>nodeInfo[currNode].dueDate){
-                        i++;    //else find next node that is reachable
-                        continue;
-                    }
-                    else{   //add node to completion of the path
-                        double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);
-                        int multiplicity=ceil((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_arc+nodeInfo[currNode].min_time_incoming));
-                        visited_in_completion.emplace_back(make_tuple(currNode,1,multiplicity));
-                        i++;
-                    }
-                }
-            }
-        
-             if(nodeInfo[currNode].min_cost_arc>=0){
-                if(ng){
-                    if(visited_in_completion.size()!=1){    //the first added node may have positive cost
-                        break;
-                    }
-                }
-                else{
-                    break;
+            
+            if(nodeInfo[currNode].min_cost_arc>=0){
+                break;
+            }  
+           
+            double multiplicity=1;
+            if(ng){
+                double start_time=max(earliest_start_time+arcInfo[labelNode][currNode].time,nodeInfo[currNode].readyTime);
+                if(start_time>nodeInfo[currNode].dueDate){
+                    i++;
+                    continue;
                 }
+                multiplicity=floor((nodeInfo[currNode].dueDate-start_time)/(nodeInfo[currNode].min_time_outgoing_ng+nodeInfo[currNode].min_time_incoming_ng))+1;
             }
-
             float value;
-            
             added_charging=max((double)0,nodeInfo[currNode].min_fuel_arc-energy)/charging_rates[0]; //charging time at fastest rate
             energy=max((double)0.0,energy-nodeInfo[currNode].min_fuel_arc);     //update the energy resource
-            value=min((double)1,resource_left/(nodeInfo[currNode].min_time_arc+added_charging));
+            value=min((double)multiplicity,resource_left/(nodeInfo[currNode].min_time_arc+added_charging));
 
             resource_left=resource_left-(nodeInfo[currNode].min_time_arc+added_charging)*value;
-
             cost=cost+(nodeInfo[currNode].min_cost_arc*value);
 
             if(resource_left<=0){
                 break;
-            }
-                
+            }   
         }
-        if(!ng){
-                i++;
-            }
-    }
-
-    if(ng){
-        return(min(cost,nodeInfo[labelNode].min_cost_arc));
-    }
-    else{
-        return(cost);
+        i++;
     }
+    return(cost);
 }