├── README.md ├── VRP.cpp ├── dataone.txt └── datatwo.txt /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Project Objective 3 | 4 | The focus of this project is to implement a hybrid Greedy Randomized Adaptive Search (GRASP) algorithm that solves a single depot vehicle routing problem. 5 | 6 | ## Introduction 7 | 8 | ### Vehicle Routing Problem 9 | 10 | The simplest vehicle routing problem can be stated as: Given a single depot and a fixed number vehicles, each customer has a specific demand that is to be delivered from the depot. The capacity of the vehicles is known. The distances among the customer locations as well as from the depot to each customer location is known. The vehicle starts from the depot and returns to depot after meeting the customer demands. The problem is to satisfy the demand of all customers such that the total distance travelled is minimized. 11 | 12 | 13 | ### Vehicle Routing Problem - Variants: 14 | 15 | 1. Vehicle Routing Problem with Pickup and Delivery (VRPPD): 16 | A number of goods need to be moved from certain pickup locations to other delivery locations. The goal is to find optimal routes for a fleet of vehicles to visit the pickup and drop-off locations. 17 | 2. Vehicle Routing Problem with LIFO : 18 | Similar to the VRPPD, except an additional restriction is placed on the loading of the vehicles: at any delivery location, the item being delivered must be the item most recently picked up. This scheme reduces the loading and unloading times at delivery locations because there is no need to temporarily unload items other than the ones that should be dropped off. 19 | 3. Vehicle Routing Problem with Time Windows (VRPTW): 20 | The delivery locations have time windows within which the deliveries (or visits) must be made. 21 | 4. Capacitated Vehicle Routing Problem (with or without Time Windows): 22 | CVRP or CVRPTW. The vehicles have limited carrying capacity of the goods that must be delivered. 23 | 24 | ### Greedy Randomized Adaptive Search Procedure 25 | 26 | GRASP, a randomized adaptive search method is a constructive search methodology. GRASP constructs a solution in an iterative fashion by evaluating insertion priority of the candidate solution elements. 27 | 28 | #### Solution Construction 29 | 30 | GRASP begins every iteration with an empty solution set, adding elements iteratively. To explain, any iteration starts with an empty solution and evaluates all candidate elements according to a performance function (g) for their influence on the quality of the current list of partial solution. The candidate elements are then sorted in decreasing order to make a restricted candidate list. From this set, a random element is chosen and added to the partial solution. Steps involved: 31 | 32 | 1. Candidate evaluation 33 | Every candidate is evaluated using a candidate evaluation function (g). The change in the quality of partial solution by the addition of respective candidate element is what is taken into account. 34 | 2. Restricted candidate list construction 35 | R.C.L. construction can be carried out in two ways: cardinality based construction and value based construction. The former method includes the k (fixed by the user) best candidates in the R.C.L., where k is the parameter. If k =1, the construction is purely greedy, and as k increases the randomness increases. In value based method a parameter a€ [0, 1] is employed for the R.C.L. construction. A threshold value which equals gmin + a (gmax-gmin) is calculated. All elements which is below or above the threshold value is included in the list (for a minimization and maximization problem respectively). 36 | 3. Random element chooser 37 | An element from the list is chosen randomly. 38 | 39 | #### Solution Improvement 40 | 41 | ##### Intra-Route Improvement – Two Opt Heuristic 42 | 43 | A 2 opt neighborhood operator removes two non adjacent edges and reconnects the remaining two paths, yielding to a new solution. For this to work a feasible round trip must be given, which means every node is visited exactly once. 44 | 45 | ##### Inter-Route Improvement – Cross-Exchange 46 | 47 | Here, the basic idea is to move nodes (or paths) from one route to a different route. Unlike single route neighborhood operators (intra-route improvement), multi-route neighborhood operators must check capacity constraints, because by moving customers or customer segments between different routes, the aggregated demand of the route can change and hence may become infeasible. 48 | 49 | #### Basic Algorithm 50 | 51 | ``` 52 | Data: set V containing customers and depot 53 | Data: cost matrix D 54 | Result: set of routes R 55 | while termination criteria not met, do 56 | s <- empty solution; 57 | calculate seed customers; 58 | create partial solution s based on seed customers; 59 | while solution s is not complete, do 60 | evaluate all candidate elements ci € C with g(ci,s); 61 | build rcl out of the best candidates; 62 | choose random ci € rcl; 63 | add ci to s; 64 | remove ci from C; 65 | end 66 | improve s until it is locally optimal; 67 | if f(s)< f(sbest) then 68 | sbest = s; 69 | end 70 | end 71 | ``` 72 | 73 | ## Test Problem under Study 74 | 75 | A single depot VRP with 600 customers. The constraints include:- 76 | * Customers can be served only between 5.00 A.M. and 8.00 A.M. 77 | * Each truck can only travel a maximum of 65 k.m. or 35 stops (customers). 78 | * Customer demands are specific. 79 | * Each truck can take 1000 k.g. at full load. 80 | 81 | Objective 82 | * Find the number of trucks. 83 | * Vehicle route for each truck 84 | * Total distance traveled and the associated cost. 85 | 86 | ### Input Data 87 | 88 | The input data consists of a 601 X 601 distance matrix (dataone.txt) and a 600 X 1 demand matrix (datatwo.txt). 89 | 90 | ### Functions 91 | 92 | *int seeder(int array[])* 93 | Calculates and returns the seed customers. 94 | 95 | *int calculatelength(route)* 96 | Takes the route as argument and returns its length. 97 | 98 | *void routeinitializer(route&,int)* 99 | It initializes routes. 100 | 101 | *float calculatecost(route)* 102 | Takes the route as argument and returns the cost. 103 | 104 | *int feasibility(route)* 105 | Takes the route as argument and checks its feasibility and returns zero if feasible. 106 | 107 | *float insert(route,int,int)* 108 | Insert a given customer in a given route in a given position and returns its insertion cost. The arguments used are route, customer (candidate), and position. 109 | 110 | *float permutation(route, int)* 111 | This function tries all possible positions in a given route for a given customer and returns a minimum insertion cost. It takes route and customer as arguments. 112 | 113 | *int mininsertion position(route, int)* 114 | This function returns the position that has the minimum insertion cost for a given customer in a given route. 115 | 116 | *int minroute(route[], int)* 117 | This function returns the route with minimum insertion cost for a given customer using route array and customer as arguments. 118 | 119 | *float inspriority(route[], int)* 120 | This function takes route array and customer and returns the insertion priority for the given customer. 121 | 122 | *int selectcustomer()* 123 | It selects a random customer from the restricted candidate list to be inserted. 124 | 125 | *int check(int)* 126 | This function checks whether a customer (argument) is already routed and returns zero if not routed. 127 | 128 | *void routedcustomer(int)* 129 | This function adds a customer (argument) to already routed list(if routed). 130 | 131 | *void changeroute(route&, int, int)* 132 | This function makes permanent change to the given route taking route, customer and position as argument. 133 | 134 | *float updateglobal(route&, route)* 135 | Updates global best solution and returns the total distance or cost. 136 | 137 | *float calculatetimecost(route)* 138 | Calculates the distance from depot to the last customer served in the route taken as argument. This distance is required in order to check whether time window is violated. 139 | 140 | *float calculategainintra(route, int, int)* 141 | Takes route and the customers involved in the two opt move as argument and calculate the net gain in distance for the given two opt move. 142 | 143 | *void changer(route&, int, int)* 144 | Implements permanent change in the route for the given customers, i.e. two opt move. 145 | 146 | *void intrarouteimprovement(route&)* 147 | Takes the given route as argument and performs all possible two opt moves and the function calculategainintra returns the corresponding gain for each move, and the best improvement is implemented using the function void changer. 148 | 149 | *void interrouteimprovement(route& p,route& q)* 150 | Takes the two route as argument and performs all possible edge exchanges and the function calculategain returns the corresponding gain for each move, and the best improvement is implemented using the function void changerinter. 151 | 152 | *float calculategain(route p,route q,int petro1[],int petro2[],int edge1,int edge2)* 153 | Takes routes, route segments and edges to be cut as argument and performs the cross exchange and returns the corresponding gain. 154 | 155 | *void deletion(route&t,int edge)* 156 | This is the operational function used by calculate gain to try the inter tour operation. It helps in removing a segment from the route as argument. 157 | 158 | *void insert(route&t, int customer)* 159 | This is the operational function used by calculate gain to try the inter tour operation. It helps in adding a segment to the route. 160 | 161 | *void changerinter(route &p,route &q,int petro1[],int petro2[],int edge1,int edge2)* 162 | This function performs the best inter-route improvement permanently. 163 | 164 | ## Reference 165 | Zäpfel, Günther, Roland Braune, and Michael Bögl. Metaheuristic search concepts: A tutorial with applications to production and logistics. Springer Science & Business Media, 2010. 166 | 167 | -------------------------------------------------------------------------------- /VRP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | using namespace std; 8 | float randomseed = 3; 9 | int routed[600] = {0}; 10 | int extreme, a = 40; 11 | float dist[601][601]; 12 | int demand[601]; 13 | int v; 14 | const float BIG = 100000; 15 | struct route { 16 | int R[40]; 17 | } routes[40], globalbest[40]; 18 | float globalcost = 999999; 19 | 20 | 21 | 22 | //Please refer README for more info on the below functions: 23 | 24 | int seeder(int array[]); 25 | int calculatelength(route); 26 | void routeinitializer(route&, int); 27 | float calculatecost(route); 28 | int feasibility(route); 29 | float insert(route, int, int); 30 | float permutation(route, int); 31 | int mininsertionposition(route, int); 32 | int minroute(route[], int); 33 | float inspriority(route[], int); 34 | int selectcustomer(); 35 | int check(int); 36 | void routedcustomer(int); 37 | void changeroute(route& , int, int); 38 | float updateglobal(route&, route); 39 | float calculatetimecost(route); 40 | float times(route); 41 | float demands(route); 42 | void intrarouteimprovement(route&); 43 | float calculategainintra(route, int, int); 44 | void changer(route&, int, int); 45 | void interrouteimprovement(route& p, route& q); 46 | float calculategain(route p, route q, int petro1[], int petro2[], int edge1, int edge2); 47 | void deletion(route&t, int edge ); 48 | void insert(route&t, int customer); 49 | void changerinter(route &p, route &q, int petro1[], int petro2[], int edge1, int edge2); 50 | 51 | 52 | int main() { 53 | ifstream infile, filein; 54 | ofstream fileout, filesout; 55 | fileout.open("outputone.txt"); 56 | filesout.open("outputtwo.txt"); 57 | infile.open("dataone.txt"); 58 | for (int po = 0; po < 601; po++) { 59 | for (int qo = 0; qo < 601; qo++) { 60 | infile >> dist[po][qo]; 61 | } 62 | } 63 | 64 | 65 | infile.close(); 66 | 67 | filein.open("datatwo.txt"); 68 | int jo; 69 | for (jo = 0; jo < 601; jo++) { 70 | filein >> demand[jo]; 71 | } 72 | 73 | 74 | filein.close(); 75 | int i, p, q, t, demand_sum = 0; 76 | float r = 0; 77 | for (i = 0; i < 601; i++) { 78 | demand_sum += demand[i]; 79 | } 80 | v = (demand_sum / 1000) + 1; 81 | cout << "the number of seeds are " << v << endl; 82 | int seed[29] = {0}; 83 | for (p = 0; p < 601; p++) { 84 | if (dist[0][p] > r) { 85 | r = dist[0][p]; 86 | } 87 | } 88 | for (p = 1; p < 601; p++) { 89 | if (dist[0][p] == r) { 90 | seed[0] = p; 91 | } 92 | } 93 | routedcustomer(seed[0]); 94 | for (q = 1; q < v; q++) { 95 | seed[q] = seeder(seed); 96 | } 97 | cout << "the initial seeds are" << endl; 98 | for (int d = 0; d < v; d++) { 99 | cout << "seed" << d << "= " << seed[d] << endl; 100 | } 101 | //construction starts from here.. 102 | //after calculation of seed customers.. 103 | int count = 1; 104 | 105 | while (count != 10) { 106 | 107 | for (int e = 0; e < 600; e++) { 108 | routed[e] = 0; 109 | } 110 | for (int w = 0; w < v; w++) { 111 | routed[w] = seed[w]; 112 | } 113 | 114 | 115 | for (int h = 0; h < v; h++) { 116 | routeinitializer(routes[h], seed[h]); //for reference copy the struct variable should b global.. 117 | } 118 | 119 | extreme = v; 120 | int cus; 121 | int oppa = 0; 122 | while (oppa != 571) { 123 | cus = selectcustomer(); 124 | if (cus != 0) { 125 | int tion = minroute(routes, cus); 126 | int tata = mininsertionposition(routes[tion], cus); 127 | changeroute(routes[tion], tata, cus); 128 | 129 | routedcustomer(cus); 130 | } 131 | 132 | oppa++; 133 | } 134 | 135 | for (int me = 0; me < 600; me++) { 136 | filesout << routed[me] << endl; 137 | } 138 | 139 | float totaldistance = 0; 140 | for (int fiesta = 0; fiesta < extreme; fiesta++) { 141 | totaldistance = totaldistance + calculatecost(routes[fiesta]); 142 | } 143 | 144 | cout << " result of iteration " << count << " is " << totaldistance << " with feasibility " << check(0) << "and no of R's " << extreme << endl; 145 | 146 | 147 | 148 | for (int lo = 0; lo < 600; lo++) { 149 | for (int e = 0; e < extreme; e++) { 150 | 151 | for (int f = 0; f < extreme; f++) 152 | 153 | { 154 | if (e == f) { 155 | 156 | intrarouteimprovement(routes[e]); 157 | } else { 158 | int length1 = 0, length2 = 0, length3 = 0; 159 | length1 = calculatelength(routes[e]); 160 | length2 = calculatelength(routes[f]); 161 | length3 = length1 + length2; 162 | if (length3 < 39) { 163 | interrouteimprovement(routes[e], routes[f]); 164 | } 165 | } 166 | } 167 | } 168 | } 169 | 170 | 171 | 172 | totaldistance = 0; 173 | for (int fiesta = 0; fiesta < extreme; fiesta++) { 174 | totaldistance = totaldistance + calculatecost(routes[fiesta]); 175 | } 176 | cout << " result of iteration after improvement " << count << " is " << totaldistance << " with feasibility " << check(0) << "and no of R's " << extreme << endl; 177 | 178 | 179 | if (totaldistance < globalcost) { 180 | if (extreme <= a) { 181 | globalcost = 0; 182 | for (int benz = 0; benz < extreme; benz++) { 183 | a = extreme; 184 | globalcost = globalcost + updateglobal(globalbest[benz], routes[benz]); 185 | } 186 | } 187 | } 188 | count++; 189 | 190 | } 191 | cout << endl << "the global best route is" << endl; 192 | for (int aveo = 0; aveo < a; aveo++) { 193 | int ford = calculatelength(globalbest[aveo]); 194 | cout << endl; 195 | fileout << endl; 196 | cout << "the fees of route " << aveo << " is " << feasibility(globalbest[aveo]); 197 | cout << " the distance of route " << aveo << " is " << calculatecost(globalbest[aveo]); 198 | cout << " the length of route " << aveo << " is " << calculatelength(globalbest[aveo]); 199 | cout << " the time for route " << aveo << " is " << times(globalbest[aveo]); 200 | cout << " the demend for route " << aveo << " is " << demands(globalbest[aveo]); 201 | for (int uva = 0; uva < ford; uva++) { 202 | cout << " " << globalbest[aveo].R[uva]; 203 | fileout << " " << globalbest[aveo].R[uva]; 204 | } 205 | } 206 | 207 | cout << endl << "global best cost is " << globalcost; 208 | 209 | fileout.close(); 210 | filesout.close(); 211 | 212 | system("pause"); 213 | return 0; 214 | } 215 | 216 | 217 | 218 | 219 | 220 | int seeder(int array[]) { //function calculating and returning seeds.. 221 | 222 | int q, n, j, m = 0, x, y = 0, s; 223 | float min, max_array[600] = {0}, max = 0; 224 | while (array[m] != 0) { 225 | y++; 226 | m++; 227 | } 228 | for (n = 1; n < 601; n++) { 229 | if (check(n) == 0) { 230 | min = 10000; 231 | for (j = 0; j < y; j++) { 232 | if (dist[array[j]][n] < min) { 233 | min = dist[array[j]][n]; 234 | } 235 | } 236 | max_array[n - 1] = min; 237 | } 238 | } 239 | for (x = 0; x < 600; x++) { 240 | if (max_array[x] > max) { 241 | max = max_array[x]; 242 | } 243 | } 244 | for (j = 0; j < y; j++) { 245 | for (q = 1; q < 601; q++) { 246 | if (check(q) == 0) { 247 | if (dist[array[j]][q] == max) { 248 | s = q; 249 | } 250 | } 251 | } 252 | } 253 | routedcustomer(s); 254 | return s; 255 | } 256 | 257 | 258 | 259 | int calculatelength(route l) { //a function to calculate length.. 260 | int i = 1; 261 | int p = 2; 262 | while (l.R[i] != 0) { 263 | i++; 264 | p++; 265 | } 266 | return p; 267 | } 268 | 269 | 270 | void routeinitializer(route&o, int x) { //a func which initializes the routes. 271 | int i = 0; 272 | o.R[i] = 0; 273 | i++; 274 | o.R[i] = x; 275 | i++; 276 | o.R[i] = 0; 277 | 278 | } 279 | 280 | 281 | float calculatecost(route p) { // a function to calculate cost.. 282 | int i, j, l; 283 | float cost = 0; 284 | l = calculatelength(p); 285 | 286 | 287 | for (i = 0, j = 1; i < (l - 1), j < l; i++, j++) { 288 | cost = cost + dist[p.R[i]][p.R[j]]; 289 | } 290 | 291 | return cost; 292 | } 293 | 294 | float times(route t) { 295 | int l = calculatelength(t); 296 | float costs, time, timecost; 297 | timecost = calculatetimecost(t); 298 | //costs=calculatecost(t); 299 | time = (0.08333333 * (l - 2) + 0.025 * timecost); 300 | return time; 301 | } 302 | 303 | float demands(route t) { 304 | float f = 0; 305 | int i; 306 | int l = calculatelength(t); 307 | for (i = 0; i < l; i++) { 308 | f = f + demand[t.R[i]]; 309 | } 310 | return f; 311 | } 312 | 313 | 314 | int feasibility(route t) { //a func to check feasibility.. 315 | int f = 0; 316 | int i, spider, constraint1 = 0, constraint2 = 0, constraint3 = 0, constraint4 = 0; 317 | int l = calculatelength(t); 318 | float costs, time, timecost; 319 | timecost = calculatetimecost(t); 320 | costs = calculatecost(t); 321 | time = (0.08333333 * (l - 2) + 0.025 * timecost); 322 | for (i = 0; i < l; i++) { 323 | f = f + demand[t.R[i]]; 324 | } 325 | if (f <= 1000) { 326 | constraint1 = 1; 327 | } 328 | if ((l - 2) <= 35) { 329 | constraint2 = 1; 330 | } 331 | if (costs <= 65) { 332 | constraint3 = 1; 333 | } 334 | if (time <= 3) { 335 | constraint4 = 1; 336 | } 337 | spider = (constraint1 + constraint2 + constraint3 + constraint4); 338 | if (spider == 4) { 339 | return 0; 340 | } else { 341 | return 1; 342 | } 343 | } 344 | 345 | float calculatetimecost(route p) { // a function to calculate cost.. 346 | int i, j, l; 347 | float cost = 0; 348 | l = calculatelength(p); 349 | for (i = 0, j = 1; i < (l - 2), j < (l - 1); i++, j++) { 350 | cost = cost + dist[p.R[i]][p.R[j]]; 351 | } 352 | return cost; 353 | } 354 | 355 | 356 | 357 | float insert(route t, int position, int customer) { //func to insert a customer 358 | //in agiven position in a 359 | //given route and returns 360 | float d1 = calculatecost(t); //insertion cost.. 361 | int l = calculatelength(t); 362 | 363 | for (int c = (l - 1); c >= (position - 1); c--) { 364 | t.R[c + 1] = t.R[c]; 365 | } 366 | t.R[position - 1] = customer; 367 | 368 | float d2 = calculatecost(t); 369 | int i = feasibility(t); 370 | float d3 = (d2 - d1); 371 | if (i == 0) { 372 | return d3; 373 | } else { 374 | return BIG; 375 | } 376 | } 377 | 378 | 379 | 380 | float permutation(route t, int customer) { //a func which tries all possible positions in a given route for a customer and returns the min insertion cost.. 381 | int l = calculatelength(t); 382 | float cost[40] = {0}; 383 | for (int position = 2; position <= l; position++) { 384 | cost[position - 2] = insert(t, position, customer); 385 | } 386 | float min = 1000000; 387 | for (int i = 0; i < (l - 1); i++) { 388 | if (cost[i] < min) { 389 | min = cost[i]; 390 | } 391 | } 392 | return min; 393 | } 394 | 395 | 396 | 397 | int mininsertionposition(route t, int customer) { //a func which returns min insrtn cost position.. 398 | int l = calculatelength(t); 399 | float cost[40] = {0}; 400 | for (int position = 2; position <= l; position++) { 401 | cost[position - 2] = insert(t, position, customer); 402 | } 403 | float min = 1000000; 404 | for (int i = 0; i < (l - 1); i++) { 405 | if (cost[i] < min) { 406 | min = cost[i]; 407 | } 408 | } 409 | int h; 410 | for (int j = 0; j < (l - 1); j++) { 411 | if (cost[j] == min) { 412 | h = j + 2; 413 | } 414 | } 415 | return h; 416 | } 417 | 418 | 419 | 420 | int minroute(route c[], int customer) { //wait a minute..brilliant!! 421 | 422 | float a[40]; 423 | for (int h = 0; h < 40; h++) { 424 | a[h] = 100000; 425 | } 426 | 427 | for (int j = 0; j < extreme; j++) { // try replacing v with another global variable..for u know what.. 428 | a[j] = permutation(c[j], customer); 429 | } 430 | float min = 999999; 431 | for (int q = 0; q < extreme; q++) { 432 | if (a[q] < min) 433 | {min = a[q];} 434 | 435 | } 436 | int y; 437 | for (int k = 0; k < 40; k++) { 438 | if (a[k] == min) { 439 | y = k; 440 | } 441 | } 442 | return y; 443 | } 444 | 445 | 446 | 447 | float inspriority(route c[], int customer) { //a func which returns inspriority.. 448 | 449 | float a[40]; 450 | for (int h = 0; h < 40; h++) { 451 | a[h] = 100000; 452 | } 453 | 454 | for (int j = 0; j < extreme; j++) { // try replacing v with another global variable..for u know what.. 455 | a[j] = permutation(c[j], customer); 456 | } 457 | float min = 999999; 458 | for (int q = 0; q < extreme; q++) { 459 | if (a[q] < min) 460 | {min = a[q];} 461 | } 462 | float priority = 0; 463 | for (int n = 0; n < extreme; n++) { 464 | priority = priority + (a[n] - min); 465 | } 466 | return priority; 467 | } 468 | 469 | 470 | 471 | int check(int customer) { //checks whether a customer is already routed.. 472 | int flag = 0; 473 | for (int i = 0; i < 600; i++) { 474 | if (routed[i] == customer) { 475 | flag = 1; 476 | } 477 | } 478 | if (flag == 1) { 479 | return 1; 480 | } else { 481 | return 0; //returns 0 if not routed.. 482 | } 483 | } 484 | 485 | 486 | 487 | int selectcustomer() { //function to select a customer... 488 | int c; 489 | int p = 0; 490 | float pro[601]; 491 | for (int k = 0; k < 601; k++) { 492 | pro[k] = -99; 493 | } 494 | 495 | float a[601]; 496 | for (int f = 0; f < 601; f++) { 497 | a[f] = -98; 498 | } 499 | float sumo = 1; 500 | int flag = 0; 501 | for (int customer = 1; customer <= 600; customer++) { 502 | c = check(customer); 503 | 504 | if (c == 0) { 505 | 506 | pro[p] = inspriority(routes, customer); 507 | a[customer] = pro[p]; 508 | p++; 509 | } 510 | } 511 | 512 | if (p != 0) { 513 | int iteration, index; 514 | float temp; 515 | for (iteration = 1; iteration < p; iteration++) { 516 | for (index = 0; index < (p - iteration); index++) { 517 | if (pro[index] < pro[index + 1]) { 518 | temp = pro[index]; 519 | pro[index] = pro[index + 1]; 520 | pro[index + 1] = temp; 521 | } 522 | } 523 | } 524 | float ptr[600] = {0}; 525 | int w; 526 | float ya; 527 | //srand(randomseed); 528 | srand(time(NULL)); 529 | int ra = (rand() % 100) + 1; 530 | ya = (ra * 0.01); 531 | w = (ya * p); 532 | if (w < 100) { 533 | w = p; 534 | } 535 | 536 | float random; 537 | 538 | for (int n = 0; n < w; n++) { 539 | ptr[n] = pro[n]; 540 | } 541 | random = ptr[rand() % w]; 542 | 543 | for (int l = 0; l < 601; l++) { 544 | if (a[l] == random) { 545 | flag = l; 546 | } 547 | } 548 | randomseed = randomseed++; 549 | } 550 | 551 | return flag; 552 | } 553 | 554 | 555 | void routedcustomer(int customer) { //a function to insert a customer into routed list.. 556 | for (int n = 0; n < 600; n++) { 557 | if (routed[n] == 0) { 558 | routed[n] = customer; 559 | break; 560 | } 561 | } 562 | } 563 | 564 | 565 | 566 | void changeroute(route& t, int position, int customer) { //func to make permanant changes.. 567 | 568 | int l = calculatelength(t); 569 | 570 | for (int c = (l - 1); c >= (position - 1); c--) { 571 | t.R[c + 1] = t.R[c]; 572 | } 573 | t.R[position - 1] = customer; 574 | 575 | } 576 | 577 | 578 | 579 | float updateglobal(route& global, route current) { //updates global best routes.. 580 | 581 | int ford = calculatelength(current); 582 | for (int uva = 0; uva < ford; uva++) { 583 | global.R[uva] = current.R[uva]; 584 | } 585 | 586 | float totaldistance = 0; 587 | totaldistance = calculatecost(global); 588 | 589 | return totaldistance; 590 | } 591 | 592 | 593 | 594 | 595 | void intrarouteimprovement(route&p) { //for intraroute improvements.. 596 | int l = calculatelength(p); 597 | 598 | float darray[40][40]; 599 | for (int row = 0; row < 40; row++) { 600 | for (int col = 0; col < 40; col++) { 601 | darray[row][col] = 0; 602 | } 603 | } 604 | float check; 605 | for (int i = 1; i < (l - 2); i++) { 606 | for (int j = 1; j < (l - 2); j++) { 607 | 608 | darray[i - 1][j - 1] = calculategainintra(p, i, j); 609 | 610 | } 611 | } 612 | int wow, now; 613 | float max = -999999; 614 | for (int row = 0; row < (l - 2); row++) { 615 | for (int col = 0; col < (l - 2); col++) { 616 | if (darray[row][col] > max) { 617 | max = darray[row][col]; 618 | wow = row + 1; 619 | now = col + 1; 620 | } 621 | } 622 | } 623 | 624 | if (max > 0) { 625 | changer(p, wow, now); 626 | } 627 | } 628 | 629 | 630 | 631 | 632 | float calculategainintra(route t , int i, int j) 633 | 634 | { 635 | int fees = 1; 636 | float d3 = 0; 637 | float d1 = 0; 638 | float d2 = 0; 639 | if ((j - i) > 1) { 640 | 641 | int temp; 642 | d1 = calculatecost(t); 643 | for (int k = i, g = j; (g - k) > 1; k++, g--) { 644 | 645 | temp = t.R[k + 1]; 646 | t.R[k + 1] = t.R[g]; 647 | t.R[g] = temp; 648 | 649 | } 650 | d2 = calculatecost(t); 651 | 652 | if ((d1 - d2) > 0) { 653 | 654 | fees = feasibility(t); 655 | 656 | } 657 | d3 = (d1 - d2); 658 | 659 | } 660 | if ((fees == 0)) { 661 | return d3; 662 | } else { 663 | return -9; 664 | } 665 | } 666 | 667 | 668 | 669 | 670 | 671 | void changer(route&t, int i, int j) { 672 | float temp; 673 | for (int k = i, g = j; (g - k) > 1; k++, g--) { 674 | 675 | temp = t.R[k + 1]; 676 | t.R[k + 1] = t.R[g]; 677 | t.R[g] = temp; 678 | } 679 | } 680 | 681 | 682 | 683 | 684 | void interrouteimprovement(route& p, route& q) { 685 | int l1, l2; 686 | float check; 687 | l1 = calculatelength(p); 688 | //cout<<" length 1 "<0; a++, b--) { 708 | ptr1[a] = p.R[b]; 709 | } 710 | ptr1[edge1 - 1] = 0; 711 | for (int x = 0, z = (edge2 - 1); x0; x++, z--) { 712 | ptr[x] = q.R[z]; 713 | } 714 | ptr[edge2 - 1] = 0; 715 | 716 | darray[(edge1 - 1)][(edge2 - 1)] = calculategain(p, q, ptr1, ptr, edge1, edge2); 717 | 718 | } 719 | } 720 | 721 | 722 | 723 | int wow, now; 724 | float max = -999999; 725 | for (int row = 0; row < (l1 - 1); row++) { 726 | for (int col = 0; col < (l2 - 1); col++) { 727 | if (darray[row][col] > max) { 728 | max = darray[row][col]; 729 | wow = row + 1; 730 | now = col + 1; 731 | } 732 | } 733 | } 734 | 735 | for (int a = 0, b = (wow - 1); a0; a++, b--) { 736 | ptr1[a] = p.R[b]; 737 | } 738 | ptr1[wow - 1] = 0; 739 | for (int x = 0, z = (now - 1); x0; x++, z--) { 740 | ptr[x] = q.R[z]; 741 | } 742 | ptr[now - 1] = 0; 743 | 744 | changerinter(p, q, ptr1, ptr, wow, now); 745 | 746 | } 747 | 748 | 749 | 750 | float calculategain(route p, route q, int petro1[], int petro2[], int edge1, int edge2) { 751 | 752 | int l1, l2; 753 | float actualcost, c1, c2, modifiedcost, cm1, cm2, gain; 754 | c1 = calculatecost(p); 755 | c2 = calculatecost(q); 756 | l1 = calculatelength(p); 757 | l2 = calculatelength(q); 758 | 759 | actualcost = (c1 + c2); 760 | deletion(p, edge1); 761 | deletion(q, edge2); 762 | 763 | int c, d, length1, length2; 764 | 765 | for (int y = 0; y < edge2; y++) { 766 | c = petro2[y]; 767 | insert(p, c); 768 | } 769 | 770 | for (int y = 0; y < edge1; y++) { 771 | d = petro1[y]; 772 | insert(q, d); 773 | } 774 | 775 | length1 = calculatelength(p); 776 | length2 = calculatelength(q); 777 | cm1 = calculatecost(p); 778 | cm2 = calculatecost(q); 779 | modifiedcost = (cm1 + cm2); 780 | gain = (actualcost - modifiedcost); 781 | int fees1 = 0; 782 | int fees2 = 0; 783 | int summer = 0; 784 | fees1 = feasibility(p); 785 | fees2 = feasibility(q); 786 | summer = (fees1 + fees2); 787 | if (summer == 0) { 788 | //cout<<"gain is "<= 0; c--) { 817 | t.R[c + 1] = t.R[c]; 818 | } 819 | t.R[0] = customer; 820 | } 821 | 822 | 823 | 824 | void changerinter(route &p, route &q, int petro1[], int petro2[], int edge1, int edge2) { 825 | int l1, l2; 826 | float actualcost, c1, c2, modifiedcost, cm1, cm2, gain; 827 | c1 = calculatecost(p); 828 | c2 = calculatecost(q); 829 | l1 = calculatelength(p); 830 | l2 = calculatelength(q); 831 | 832 | actualcost = (c1 + c2); 833 | deletion(p, edge1); 834 | deletion(q, edge2); 835 | 836 | int c, d, length1, length2; 837 | 838 | for (int y = 0; y < edge2; y++) { 839 | c = petro2[y]; 840 | insert(p, c); 841 | } 842 | 843 | for (int y = 0; y < edge1; y++) { 844 | d = petro1[y]; 845 | insert(q, d); 846 | } 847 | } 848 | 849 | 850 | -------------------------------------------------------------------------------- /datatwo.txt: -------------------------------------------------------------------------------- 1 | 90 2 | 25 3 | 42 4 | 44 5 | 71 6 | 40 7 | 36 8 | 37 9 | 98 10 | 40 11 | 26 12 | 30 13 | 21 14 | 44 15 | 55 16 | 33 17 | 63 18 | 26 19 | 32 20 | 96 21 | 60 22 | 33 23 | 65 24 | 61 25 | 35 26 | 38 27 | 97 28 | 89 29 | 40 30 | 78 31 | 26 32 | 31 33 | 37 34 | 20 35 | 46 36 | 24 37 | 30 38 | 30 39 | 95 40 | 90 41 | 30 42 | 27 43 | 27 44 | 43 45 | 44 46 | 22 47 | 38 48 | 22 49 | 32 50 | 23 51 | 94 52 | 24 53 | 51 54 | 37 55 | 40 56 | 89 57 | 78 58 | 26 59 | 95 60 | 30 61 | 82 62 | 99 63 | 70 64 | 28 65 | 36 66 | 35 67 | 20 68 | 36 69 | 83 70 | 49 71 | 45 72 | 32 73 | 43 74 | 57 75 | 32 76 | 22 77 | 81 78 | 32 79 | 53 80 | 65 81 | 40 82 | 22 83 | 22 84 | 23 85 | 85 86 | 40 87 | 28 88 | 66 89 | 40 90 | 30 91 | 20 92 | 91 93 | 37 94 | 46 95 | 20 96 | 35 97 | 63 98 | 37 99 | 80 100 | 22 101 | 68 102 | 21 103 | 80 104 | 36 105 | 60 106 | 28 107 | 72 108 | 38 109 | 42 110 | 24 111 | 100 112 | 20 113 | 40 114 | 35 115 | 50 116 | 71 117 | 95 118 | 31 119 | 89 120 | 24 121 | 74 122 | 93 123 | 36 124 | 40 125 | 98 126 | 57 127 | 25 128 | 56 129 | 25 130 | 62 131 | 26 132 | 61 133 | 74 134 | 36 135 | 29 136 | 50 137 | 53 138 | 53 139 | 27 140 | 40 141 | 79 142 | 23 143 | 30 144 | 71 145 | 35 146 | 46 147 | 37 148 | 23 149 | 33 150 | 34 151 | 33 152 | 33 153 | 100 154 | 59 155 | 23 156 | 25 157 | 28 158 | 30 159 | 34 160 | 40 161 | 24 162 | 76 163 | 78 164 | 77 165 | 29 166 | 31 167 | 37 168 | 28 169 | 25 170 | 30 171 | 20 172 | 69 173 | 53 174 | 65 175 | 77 176 | 28 177 | 100 178 | 40 179 | 92 180 | 32 181 | 49 182 | 27 183 | 73 184 | 32 185 | 30 186 | 52 187 | 83 188 | 40 189 | 34 190 | 31 191 | 30 192 | 85 193 | 26 194 | 69 195 | 23 196 | 30 197 | 30 198 | 73 199 | 55 200 | 31 201 | 53 202 | 38 203 | 28 204 | 31 205 | 78 206 | 32 207 | 22 208 | 59 209 | 25 210 | 93 211 | 72 212 | 76 213 | 29 214 | 61 215 | 62 216 | 20 217 | 33 218 | 36 219 | 33 220 | 34 221 | 55 222 | 78 223 | 31 224 | 54 225 | 80 226 | 28 227 | 73 228 | 30 229 | 22 230 | 52 231 | 65 232 | 35 233 | 100 234 | 39 235 | 31 236 | 23 237 | 29 238 | 29 239 | 30 240 | 34 241 | 83 242 | 40 243 | 22 244 | 53 245 | 32 246 | 65 247 | 91 248 | 31 249 | 29 250 | 35 251 | 71 252 | 58 253 | 36 254 | 62 255 | 50 256 | 62 257 | 70 258 | 21 259 | 66 260 | 23 261 | 96 262 | 30 263 | 80 264 | 47 265 | 34 266 | 28 267 | 93 268 | 45 269 | 22 270 | 20 271 | 87 272 | 56 273 | 27 274 | 90 275 | 60 276 | 38 277 | 22 278 | 54 279 | 28 280 | 40 281 | 67 282 | 56 283 | 63 284 | 34 285 | 54 286 | 33 287 | 30 288 | 65 289 | 30 290 | 29 291 | 24 292 | 37 293 | 61 294 | 89 295 | 84 296 | 68 297 | 76 298 | 64 299 | 23 300 | 50 301 | 46 302 | 31 303 | 28 304 | 64 305 | 29 306 | 26 307 | 42 308 | 57 309 | 20 310 | 70 311 | 40 312 | 77 313 | 38 314 | 74 315 | 39 316 | 24 317 | 36 318 | 22 319 | 30 320 | 25 321 | 28 322 | 41 323 | 78 324 | 60 325 | 80 326 | 26 327 | 81 328 | 30 329 | 34 330 | 76 331 | 40 332 | 80 333 | 60 334 | 60 335 | 35 336 | 78 337 | 60 338 | 65 339 | 40 340 | 92 341 | 28 342 | 40 343 | 48 344 | 23 345 | 60 346 | 25 347 | 49 348 | 20 349 | 26 350 | 63 351 | 35 352 | 60 353 | 72 354 | 30 355 | 31 356 | 42 357 | 38 358 | 57 359 | 21 360 | 25 361 | 28 362 | 29 363 | 81 364 | 100 365 | 51 366 | 70 367 | 29 368 | 96 369 | 75 370 | 23 371 | 71 372 | 75 373 | 48 374 | 40 375 | 53 376 | 69 377 | 30 378 | 93 379 | 20 380 | 22 381 | 34 382 | 46 383 | 22 384 | 49 385 | 28 386 | 80 387 | 37 388 | 53 389 | 20 390 | 46 391 | 40 392 | 37 393 | 59 394 | 39 395 | 88 396 | 25 397 | 37 398 | 95 399 | 37 400 | 71 401 | 22 402 | 56 403 | 26 404 | 31 405 | 37 406 | 25 407 | 23 408 | 35 409 | 40 410 | 35 411 | 31 412 | 91 413 | 29 414 | 80 415 | 28 416 | 61 417 | 25 418 | 37 419 | 45 420 | 40 421 | 46 422 | 31 423 | 41 424 | 65 425 | 70 426 | 75 427 | 93 428 | 87 429 | 59 430 | 48 431 | 35 432 | 30 433 | 60 434 | 75 435 | 44 436 | 68 437 | 63 438 | 30 439 | 77 440 | 78 441 | 75 442 | 37 443 | 23 444 | 63 445 | 96 446 | 37 447 | 63 448 | 43 449 | 37 450 | 36 451 | 27 452 | 47 453 | 80 454 | 22 455 | 26 456 | 89 457 | 56 458 | 39 459 | 40 460 | 82 461 | 53 462 | 58 463 | 47 464 | 95 465 | 26 466 | 35 467 | 24 468 | 52 469 | 22 470 | 50 471 | 47 472 | 100 473 | 79 474 | 97 475 | 80 476 | 81 477 | 23 478 | 81 479 | 85 480 | 91 481 | 96 482 | 78 483 | 41 484 | 97 485 | 32 486 | 52 487 | 67 488 | 98 489 | 35 490 | 35 491 | 80 492 | 61 493 | 64 494 | 23 495 | 24 496 | 39 497 | 44 498 | 32 499 | 35 500 | 40 501 | 30 502 | 21 503 | 49 504 | 33 505 | 90 506 | 38 507 | 37 508 | 20 509 | 80 510 | 26 511 | 97 512 | 77 513 | 27 514 | 40 515 | 34 516 | 24 517 | 45 518 | 21 519 | 22 520 | 83 521 | 39 522 | 34 523 | 32 524 | 42 525 | 73 526 | 50 527 | 23 528 | 36 529 | 31 530 | 82 531 | 61 532 | 80 533 | 40 534 | 26 535 | 72 536 | 48 537 | 31 538 | 36 539 | 32 540 | 55 541 | 37 542 | 69 543 | 35 544 | 25 545 | 41 546 | 71 547 | 33 548 | 43 549 | 31 550 | 56 551 | 37 552 | 41 553 | 68 554 | 28 555 | 81 556 | 39 557 | 74 558 | 31 559 | 83 560 | 43 561 | 82 562 | 21 563 | 49 564 | 62 565 | 68 566 | 29 567 | 28 568 | 27 569 | 32 570 | 30 571 | 44 572 | 39 573 | 55 574 | 38 575 | 70 576 | 74 577 | 25 578 | 46 579 | 44 580 | 94 581 | 29 582 | 43 583 | 57 584 | 43 585 | 24 586 | 28 587 | 41 588 | 88 589 | 35 590 | 37 591 | 81 592 | 23 593 | 24 594 | 43 595 | 57 596 | 40 597 | 50 598 | 22 599 | 40 600 | 32 601 | --------------------------------------------------------------------------------