void solve_tsp(int A[SIZE][SIZE]){ // pick the 1st node of the tour list_node* tmp_p = (list_node*) scalable_malloc (sizeof (list_node)); tmp_p->next = NULL; tmp_p->val = 0; solve_tsp_rec(A, tmp_p, 1, 0); }
void solve_tsp_rec(int A[SIZE][SIZE], int partial_solution[SIZE], int position, int partial_weight) { int i,j; int used; int myweight; #ifdef DEBUG printf("Calling tsp_rec with pos=%d and partial_weight=%d\n", position, partial_weight); #endif #ifdef PARTIAL_WEIGHT_CUTOFF if (partial_weight >= solution_weight) return; #endif for(i=0; i<SIZE; i++) { // 1. check if i was already used in the solution so far. // if so, skip it. used = 0; for(j=0; j<position; j++) { if (partial_solution[j]==i) { used = 1; break; } } if (used) continue; partial_solution[position] = i; myweight = partial_weight + A[partial_solution[position-1]][i]; if (position==SIZE-1) { // 2a. termination myweight += A[i][0]; #ifdef DEBUG for(j=0; j<SIZE; j++) { printf("%d,", partial_solution[j]); } printf(" weight = %d\n\n", myweight); #endif if (myweight < solution_weight) { solution_weight = myweight; // Save solution for(j=0; j<SIZE; j++) solution[j] = partial_solution[j]; } } else { // 2b. recursion solve_tsp_rec(A, partial_solution, position+1, myweight); } } }
void solve_tsp(int A[SIZE][SIZE]){ partial_solution[0] = 0; solve_tsp_rec(A, partial_solution, 1, 0); }
void ser_solve_tsp_rec(const int (*A)[SIZE], list_node* partial_solution, int position, int partial_weight) { #ifdef PARTIAL_WEIGHT_CUTOFF #ifdef NO_LOCKS if (partial_weight >= my_weight.local() ) return; #else if (partial_weight >= solution_weight) return; #endif #endif int i; for(i=0; i<SIZE; i++){ // 1. check if i was already used in the solution so far. // if so, skip it. int used = 0; int j = position; list_node* tmp_p = partial_solution; while(tmp_p != NULL) { if (tmp_p->val == i) { used = 1; break; } tmp_p = tmp_p->next; } if (!used) { //partial_solution[position] = i; // allocate a node tmp_p = (list_node*) scalable_malloc(sizeof(list_node)); #ifdef DEBUG if(tmp_p==NULL) {out_of_memory++;//atomic} #endif if (tmp_p != NULL) { int myweight; tmp_p->next = partial_solution; tmp_p->val = i; myweight = partial_weight + A[partial_solution->val][i]; if (position==SIZE-1) { // 2a. termination #ifdef NO_LOCKS myweight += A[i][0]; if (myweight < my_weight.local() ) { my_weight.local() = myweight; } #else myweight += A[i][0]; #ifdef DOUBLE_CHECK if (myweight < solution_weight) { #endif // acquire lock tbb::mutex::scoped_lock myLock(solution_lock); if (myweight < solution_weight) { // update solution solution_weight = myweight; solution = tmp_p; } // implicit lock release #ifdef DOUBLE_CHECK } #endif #endif } else { // 2b. recursion ser_solve_tsp_rec(A, tmp_p, position+1, myweight); } scalable_free (tmp_p); } } // end if(!used) } // end spawn } void solve_tsp_rec(const int (*A)[SIZE], list_node* partial_solution, int position, int partial_weight); class tspBody { public: //int* A[SIZE]; const int (*A)[SIZE]; list_node* partial_solution; int position; int partial_weight; void operator () (const tbb::blocked_range<int> &range) const { int i; for (i=range.begin(); i<range.end(); i++) { // 1. check if node i was already used in the solution so far. // if so, skip it. int used = 0; int j = position; list_node* tmp_p = partial_solution; while(tmp_p != NULL) { if (tmp_p->val == i) { used = 1; break; } tmp_p = tmp_p->next; } if (!used) { //partial_solution[position] = i; // allocate a node tmp_p = (list_node*) scalable_malloc( sizeof(list_node) ); #ifdef DEBUG if(tmp_p==NULL) {out_of_memory++;//atomic} #endif if (tmp_p != NULL) { int myweight; tmp_p->next = partial_solution; tmp_p->val = i; myweight = partial_weight + A[partial_solution->val][i]; if (position==SIZE-1) { // 2a. termination #ifdef NO_LOCKS myweight += A[i][0]; if (myweight < my_weight.local() ) { my_weight.local() = myweight; } #else myweight += A[i][0]; #ifdef DOUBLE_CHECK if (myweight < solution_weight) { #endif tbb::mutex::scoped_lock myLock(solution_lock); if (myweight < solution_weight) { // lock solution solution_weight = myweight; solution = tmp_p; } // implicit lock release #ifdef DOUBLE_CHECK } #endif #endif } else { // 2b. recursion #ifdef CUTOFF if (position+1>=CUTOFF_LEVEL) ser_solve_tsp_rec(A, tmp_p, position+1, myweight); else solve_tsp_rec(A, tmp_p, position+1, myweight); #else solve_tsp_rec(A, tmp_p, position+1, myweight); #endif } scalable_free (tmp_p); } } // end if(!used) } // end for loop } // Constructor tspBody(const int A[SIZE][SIZE], list_node* partial_solution, int position, int partial_weight): A(A), partial_solution(partial_solution), position(position), partial_weight(partial_weight) {} };