int main(int argc,char ** argv){ int * visitado,otimo; Tour pop[TAMPOP], * melhor; struct tms before,after; if(argc != 3){ printf("USO : %s 'instancia' 'otimo' \n\n",argv[0]); return 1; } otimo = atoi(argv[2]); times(&before); read(argv[1],d,n); visitado = new_int(n); init_int(visitado,n); pop[0] = rand_tour(); pop[1] = rand_tour(); createSet(); LinKernighan(pop[0]); LinKernighan(pop[1]); pop[2] = new_tour(); pop[2]->c = new_int(n); pop[2]->pos = new_int(n); pop[3] = new_tour(); pop[3]->c = new_int(n); pop[3]->pos = new_int(n); PMX(pop[2],pop[3],pop[0],pop[1]); LinKernighan(pop[2]); LinKernighan(pop[3]); printf("PAI 1 : \n"); print_tour(pop[0]); printf("PAI 2 : \n"); print_tour(pop[1]); printf("FILHO 1 : \n"); print_tour(pop[2]); printf("FILHO 2 : \n"); print_tour(pop[3]); melhor = &pop[0]; //print_tour(melhor); times(&after); double tempo = (double)(after.tms_utime - before.tms_utime)/(double)100; double gap = ((double)((*(melhor))->cost-otimo)/(double) otimo) * 100.0; printf("%s\t%.2lfs\t%d\t%d\t%.3lf\n",argv[1],tempo,otimo,(*(melhor))->cost,gap); //printf("System time: %ld seconds\n", after.tms_stime - before.tms_stime); return 0; }
/** * DESC: Fills the population of tours with an initial set of tours. * * N : size of each tour. * mpi_rank : rank of the mpi process * arr_tours : an array of pointers to tours * (the array must be allocated, each tour should not) * arr_cities : the master Cities structure */ void populate_tours(int N, int mpi_rank, tour_t** arr_tours, tour_t* arr_cities, int* I, int *numFileTours) { int i=0; while (i<MAX_POPULATION) { #if USE_NEAREST_NEIGHBOR #if USE_HYBRID_PROBABILITY // use hybrid arr_tours[i] = ((rand() % 100) > USE_HYBRID_PROBABILITY) ? create_tour_rand(arr_cities) : create_tour_nn(arr_cities->city[i%N], N, arr_cities); #else // not hybrid arr_tours[i] = create_tour_nn(arr_cities->city[i%N], N, arr_cities); #endif #else // not nearest neighbor arr_tours[i] = create_tour_rand(arr_cities); #endif set_tour_fitness(arr_tours[i], N); i++; } if (*numFileTours>0) { printf("converting the tours...\n"); intToTour_t(arr_cities, I, *numFileTours, arr_tours); } for (i=0;i<*numFileTours;i++) { print_tour(arr_tours[i]); } }
/** * DESC: Terminates the program, also performing necessary "finalize" functions * for MPI. */ void terminate_program(int ecode) { #if MPIFLAG MPI_Finalize(); #endif // only runs for "successful" program termination. OOPS_TEXT; #if MPIFLAG if (mpi_rank==0) { #endif printf("randSeed: %i, citiesFile: '%s'\n", randSeed, citiesFile); NORMAL_TEXT; if (Tours[0]) { STRONG_TEXT; printf(" -- BEST TOUR --\n"); print_tour(Tours[0]); NORMAL_TEXT; } else { ERROR_TEXT; printf("Invalid best tour!\n"); NORMAL_TEXT; } if (ecode==0) { // done (just used to make sure that the program ran to completion) STRONG_TEXT; printf("Program ran to completion (done).\n"); NORMAL_TEXT; } else { ERROR_TEXT; printf("PROGRAM ABNORMALLY TERMINATED, ECODE: %i\n", ecode); NORMAL_TEXT; } #if MPIFLAG } #endif NORMAL_TEXT; #if BEST_TOUR_TRACKING dumpBestTours(); #endif printf("Took %i seconds to complete.\n", (time(0)-startTime)); // exit the program. exit(ecode); }
bool BKZReduction<FT>::slide_tour(const int loop, const BKZParam &par, int min_row, int max_row) { int p = (max_row - min_row) / par.block_size; if ((max_row - min_row) % par.block_size) ++p; bool clean; // this clean variable is only for the inner loop of slide reduction do { clean = true; // SVP reduction takes care of the LLL reduction as long as BKZ_BOUNDED_LLL is off for (int i = 0; i < p; ++i) { int kappa = min_row + i * par.block_size; int block_size = min(max_row - kappa, par.block_size); clean &= svp_reduction(kappa, block_size, par); } } while (!clean); for (int i = 0; i < p - 1; ++i) { int kappa = min_row + i * par.block_size + 1; svp_reduction(kappa, par.block_size, par, true); } FT new_potential = m.get_slide_potential(min_row, max_row, par.block_size); if (par.flags & BKZ_VERBOSE) { print_tour(loop, min_row, max_row); } if (par.flags & BKZ_DUMP_GSO) { std::ostringstream prefix; prefix << "End of SLD loop " << std::setw(4) << loop; prefix << " (" << std::fixed << std::setw(9) << std::setprecision(3) << (cputime() - cputime_start) * 0.001 << "s)"; dump_gso(par.dump_gso_filename, prefix.str()); } if (new_potential >= sld_potential) return true; sld_potential = new_potential; return false; }
bool BKZReduction<FT>::sd_tour(const int loop, const BKZParam &par, int min_row, int max_row) { int dummy_kappa_max = num_rows; bool clean = true; clean &= trunc_dtour(par, min_row, max_row); clean &= trunc_tour(dummy_kappa_max, par, min_row, max_row); if (par.flags & BKZ_VERBOSE) { print_tour(loop, min_row, max_row); } if (par.flags & BKZ_DUMP_GSO) { std::ostringstream prefix; prefix << "End of SD-BKZ loop " << std::setw(4) << loop; prefix << " (" << std::fixed << std::setw(9) << std::setprecision(3) << (cputime() - cputime_start) * 0.001 << "s)"; dump_gso(par.dump_gso_filename, prefix.str()); } return clean; }
int main(int argc, char *argv[]) { graph g = read_kattis(); if(g.n <= 3) // all solutions identical { for(size_t i = 0 ; i < g.n; ++i) printf("%d\n", i); graph_free(g); return 0; } // k neighbours can't be more than neighbours available if(g.n-1 < k) k = g.n-1; /* fputs("[distance matrix]\n", stderr); for(size_t i = 0; i < g.n; ++i) { for(size_t j = 0; j < g.n; ++j) fprintf(stderr, "%3d ", graph_get_dist(g, i, j)); fputc('\n', stderr); } fputs("\n[neighbour matrix]\n", stderr); for(size_t i = 0; i < g.n; ++i) { for(size_t j = 0; j < g.n; ++j) fprintf(stderr, "%3d ", graph_get_neighbour(g, i, j)); fputc('\n', stderr); }*/ size_t greedy[g.n]; greedy_tsp(g, greedy); greedy_tour = greedy; fprintf(stderr, "\n[greedy tour]\n"); print_tour(g, greedy); size_t tour[g.n]; size_t tour2[g.n]; for(size_t i = 0; i < g.n; ++i) tour2[i] = greedy[i]; size_t *tour_ptr = tour; size_t *best = tour2; fprintf(stderr, "\n[tours]\n"); for(size_t i = 0; i < 14; ++i) { solve_tsp(g, tour_ptr); print_tour(g, tour_ptr); if(tour_length(g, tour_ptr) < tour_length(g, best)) { size_t *tmp = best; best = tour_ptr; tour_ptr = tmp; } } fprintf(stderr, "\n[kattis (best)]\n"); print_kattis(g, best); fprintf(stderr, "[kattis length: %d]\n", tour_length(g,best)); graph_free(g); return 0; }
/** * DESC: Runs the Genetic Algorithm, including the GA steps and the performEAX * on pairs of parents. * memory_chunk : giant chunk of memory used for sub cycles * lcv : when set to false (0), exits the main loop * arr_tours : array of pointers to the tours in the population */ void run_genalg(char* memory_chunk, char *lcv, tour_t** arr_tours, tour_t** arr_children, int *mpi_procs) { // pick 100 pairs of parent tours int i; tour_t *parentTourPop[MAX_PAIR_TOURS][2]; /* the array of parent pairs [0]=parentA, [1]=parentB */ #if PRINT_TOURS_DURING_MERGING DPRINTF("-- printing tours BEFORE anything -- \n"); for (i=0; i < MAX_PAIR_TOURS; i++) { DPRINTF("m(\033[31m%i\033[0m)Tours[%i]: ", Tours[i], i); print_tour(Tours[i]); } #endif // Select parents for child creation (roulette wheel) for (i=0;i<MAX_PAIR_TOURS;i++) { parentTourPop[i][0]=roulette_select(arr_tours, MAX_POPULATION, 0); parentTourPop[i][1]=roulette_select(arr_tours, MAX_POPULATION, parentTourPop[i][0]); } if (MPIFLAG==0) { #if PRINT_ITERATION_PROGRESS int progressMultiple = MAX_PAIR_TOURS / 10; DPRINTF("Progress (starting at %i): \n", time(0)); #endif // run EAX on each pair of parents for (i=0;i<MAX_PAIR_TOURS;i++) { performEAX(memory_chunk, CitiesA, CitiesB, parentTourPop[i][0], parentTourPop[i][1], arr_children[i]); #if PRINT_ITERATION_PROGRESS if (i % progressMultiple == 0) { DPRINTF("%i percent at %i\n", (i / progressMultiple) * 10, time(0)); } } DPRINTF("...iteration finished!\n"); #else } #endif #if PRINT_TOURS_DURING_MERGING DPRINTF("-- printing tours BEFORE merging -- \n"); for (i=0; i < MAX_PAIR_TOURS; i++) { DPRINTF("m(\033[31m%i\033[0m)children[%i]: ", arr_children[i], i); print_tour(arr_children[i]); } #endif // Merge the generated tours back into the population mergeToursToPop(arr_tours, MAX_POPULATION, arr_children, MAX_PAIR_TOURS); #if PRINT_TOURS_DURING_MERGING DPRINTF("-- printing tours AFTER merging -- \n"); for (i=0; i < MAX_PAIR_TOURS; i++) { DPRINTF("m(\033[31m%i\033[0m)arr_tours[%i]: ", arr_tours[i], i); print_tour(arr_tours[i]); } #endif }
template <class FT> bool BKZReduction<FT>::bkz() { int flags = param.flags; int final_status = RED_SUCCESS; nodes = 0; bool sd = (flags & BKZ_SD_VARIANT); bool sld = (flags & BKZ_SLD_RED); algorithm = sd ? "SD-BKZ" : sld ? "SLD" : "BKZ"; if (sd && sld) { throw std::runtime_error("Invalid flags: SD-BKZ and Slide reduction are mutually exclusive!"); } if (flags & BKZ_DUMP_GSO) { std::ostringstream prefix; prefix << "Input"; dump_gso(param.dump_gso_filename, prefix.str(), false); } if (param.block_size < 2) return set_status(RED_SUCCESS); int i = 0; BKZAutoAbort<FT> auto_abort(m, num_rows); if (sd && !(flags & (BKZ_MAX_LOOPS | BKZ_MAX_TIME | BKZ_AUTO_ABORT))) { cerr << "Warning: SD Variant of BKZ requires explicit termination condition. Turning auto " "abort on!" << endl; flags |= BKZ_AUTO_ABORT; } if (flags & BKZ_VERBOSE) { cerr << "Entering " << algorithm << ":" << endl; print_params(param, cerr); cerr << endl; } cputime_start = cputime(); m.discover_all_rows(); if (sld) { m.update_gso(); sld_potential = m.get_slide_potential(0, num_rows, param.block_size); } // the following is necessary, since sd-bkz starts with a dual tour and // svp_reduction calls size_reduction, which needs to be preceeded by a // call to lll lower blocks to avoid seg faults if (sd) lll_obj.lll(0, 0, num_rows); int kappa_max = -1; bool clean = true; for (i = 0;; ++i) { if ((flags & BKZ_MAX_LOOPS) && i >= param.max_loops) { final_status = RED_BKZ_LOOPS_LIMIT; break; } if ((flags & BKZ_MAX_TIME) && (cputime() - cputime_start) * 0.001 >= param.max_time) { final_status = RED_BKZ_TIME_LIMIT; break; } if ((flags & BKZ_AUTO_ABORT) && auto_abort.test_abort(param.auto_abort_scale, param.auto_abort_max_no_dec)) { break; } try { if (sd) { clean = sd_tour(i, param, 0, num_rows); } else if (sld) { clean = slide_tour(i, param, 0, num_rows); } else { clean = tour(i, kappa_max, param, 0, num_rows); } } catch (RedStatus &e) { return set_status(e); } if (clean || param.block_size >= num_rows) break; } int dummy_kappa_max = num_rows; if (sd) { try { hkz(dummy_kappa_max, param, num_rows - param.block_size, num_rows); print_tour(i, 0, num_rows); } catch (RedStatus &e) { return set_status(e); } } if (sld) { try { int p = num_rows / param.block_size; if (num_rows % param.block_size) ++p; for (int j = 0; j < p; ++j) { int kappa = j * param.block_size + 1; int end = min(num_rows, kappa + param.block_size - 1); hkz(dummy_kappa_max, param, kappa, end); } print_tour(i, 0, num_rows); } catch (RedStatus &e) { return set_status(e); } } if (flags & BKZ_DUMP_GSO) { std::ostringstream prefix; prefix << "Output "; prefix << " (" << std::fixed << std::setw(9) << std::setprecision(3) << (cputime() - cputime_start) * 0.001 << "s)"; dump_gso(param.dump_gso_filename, prefix.str()); } return set_status(final_status); }