int main(int argc, char **argv) { int i; problem *env; double gamma, gamma0, gamma1, tau, slope; double start_time; solution_data utopia1; solution_data utopia2; solution_data solutions[MAX_NUM_PAIRS]; int numsolutions = 0, numprobs = 0, numinfeasible = 0; solution_pairs pairs[MAX_NUM_PAIRS]; int numpairs = 0, cur_position = 0, first = 0, last = 0, previous = 0; double *indices, *values; int length; int solution1, solution2; double utopia[2]; node_desc *root= NULL; base_desc *base = NULL; double compare_sol_tol, ub = 0.0; start_time = wall_clock(NULL); /* Initialize the SYMPHONY environment */ OsiSymSolverInterface si; /* Get pointer to the SYMPHONY environment */ env = si.getSymphonyEnvironment(); /* Parse the command line */ si.parseCommandLine(argc, argv); /* Read in the problem */ si.loadProblem(); /* Find a priori problem bounds */ si.findInitialBounds(); /* Set some parameters */ compare_sol_tol = p->par.compare_solution_tolerance; si.setSymParam(OsiSymGranularity,-MAX(p->lp_par.rho, compare_sol_tol)); #ifdef BINARY_SEARCH printf("Using binary search with tolerance = %f...\n", p->par.binary_search_tolerance); #endif #ifdef LIFO printf("Using LIFO search order...\n"); #endif if (p->lp_par.rho > 0){ printf("Using secondary objective weight %.8f\n", cnrp->lp_par.rho); } printf("\n"); #ifdef SAVE_CUT_POOL printf("Saving the global cut pool between iterations...\n"); si.createPermanentCutPools(); si.setSymParam(OsiSymUsePermanentCutPools, TRUE); #endif /* First, calculate the utopia point */ p->lp_par.gamma = 1.0; p->lp_par.tau = 0.0; printf("***************************************************\n"); printf("***************************************************\n"); printf("Now solving with gamma = 1.0 tau = 0.0 \n", gamma, tau); printf("***************************************************\n"); printf("***************************************************\n\n"); /* Solve */ si.branchAndBound(); numprobs++; /* Store the solution */ length = solutions[numsolutions].length = p->best_sol.xlength; indices = solutions[numsolutions].indices = (int *) calloc(length, ISIZE); values = solutions[numsolutions].values = (double *) calloc(length, DSIZE); memcpy((char *) indices, p->bestsol.xind, length * ISIZE); memcpy((char *) values, p->bestsol.xval, length * DSIZE); solutions[numsolutions].gamma = 1.0; solutions[numsolutions].tau = 0.0; solutions[numsolutions].obj[0] = p->obj[0]; solutions[numsolutions++].obj[1] = p->obj[1]; utopia[0] = p->obj[0]; cnrp->lp_par.gamma = 0.0; cnrp->cg_par.tau = cnrp->lp_par.tau = 1.0; printf("***************************************************\n"); printf("***************************************************\n"); printf("Now solving with gamma = 0.0 tau = 1.0 \n", gamma, tau); printf("***************************************************\n"); printf("***************************************************\n\n"); /* Solve */ si.branchAndBound(); numprobs++; /* Store the solution */ length = solutions[numsolutions].length = p->best_sol.xlength; indices = solutions[numsolutions].indices = (int *) calloc(length, ISIZE); values = solutions[numsolutions].values = (double *) calloc(length, DSIZE); memcpy((char *) indices, p->bestsol.xind, length * ISIZE); memcpy((char *) values, p->bestsol.xval, length * DSIZE); solutions[numsolutions].gamma = 0.0; solutions[numsolutions].tau = 1.0; solutions[numsolutions].obj[0] = p->obj[0]; solutions[numsolutions++].obj[1] = p->obj[1]; utopia[1] = p->obj[1]; p->utopia[1] = utopia[1]; p->utopia[0] = utopia[0]; printf("***************************************************\n"); printf("***************************************************\n"); printf("Utopia point has fixed cost %.3f and variable cost %.3f \n", utopia[0], utopia[1]); printf("***************************************************\n"); printf("***************************************************\n\n"); /* Add the first pair to the list */ #ifdef BINARY_SEARCH pairs[first].gamma1 = 1.0; pairs[first].gamma2 = 0.0; #endif pairs[first].solution1 = 0; pairs[first].solution2 = 1; first = last = 0; numpairs = 1; /* Keep taking pairs off the list and processing them until there are none left */ while (numpairs > 0 && numpairs < MAX_NUM_PAIRS && numsolutions < MAX_NUM_SOLUTIONS && numinfeasible < MAX_NUM_INFEASIBLE){ #ifdef LIFO solution1 = pairs[last].solution1; solution2 = pairs[last].solution2; cur_position = last; if (--last < 0){ last = MAX_NUM_PAIRS - 1; } numpairs--; #else solution1 = pairs[first].solution1; solution2 = pairs[first].solution2; cur_position = first; if (++first > MAX_NUM_PAIRS-1) first = 0; numpairs--; #endif #ifdef BINARY_SEARCH gamma = (pairs[cur_position].gamma1 + pairs[cur_position].gamma2)/2; #elif defined(FIND_NONDOMINATED_SOLUTIONS) gamma = (utopia[1] - solutions[solution1].obj[1])/ (utopia[0] - solutions[solution2].obj[0] + utopia[1] - solutions[solution1].obj[1]); #else slope = (solutions[solution1].obj[1] - solutions[solution2].obj[1])/ (solutions[solution2].obj[0] - solutions[solution1].obj[0]); gamma = slope/(1+slope); #endif tau = 1 - gamma; p->lp_par.gamma = gamma; p->lp_par.tau = tau; /* Find upper bound */ env->has_ub = FALSE; env->ub = MAXDOUBLE; #ifndef BINARY_SEARCH for (i = 0; i < numsolutions; i++){ #ifdef FIND_NONDOMINATED_SOLUTIONS ub = MAX(gamma*(solutions[i].obj[0] - utopia[0]), tau*(solutions[i].obj[1] - utopia[1])); #else ub = gamma*solutions[i].obj[0] + tau*solutions[i].obj[1]; #endif if (ub < env->ub){ env->has_ub = TRUE; env->ub = ub - compare_sol_tol; } } #endif printf("***************************************************\n"); printf("***************************************************\n"); printf("Now solving with gamma = %.6f tau = %.6f \n", gamma, tau); printf("***************************************************\n"); printf("***************************************************\n\n"); p->obj[0] = p->obj[1] = 0.0; si.branchAndBound(); numprobs++; #ifdef BINARY_SEARCH if (p->obj[0] - solutions[solution1].obj[0] < compare_sol_tol && solutions[solution1].obj[1] - p->obj[1] < compare_sol_tol){ if (pairs[cur_position].gamma1 - gamma > cnrp->par.binary_search_tolerance){ if (++last > MAX_NUM_PAIRS - 1) last = 0; pairs[last].solution1 = solution1; pairs[last].solution2 = solution2; pairs[last].gamma1 = gamma; pairs[last].gamma2 = pairs[cur_position].gamma2; numpairs++; } continue; } if (solutions[solution2].obj[0] - p->obj[0] < compare_sol_tol && p->obj[1] - solutions[solution2].obj[1] < compare_sol_tol){ if (gamma - pairs[cur_position].gamma2 > cnrp->par.binary_search_tolerance){ if (++last > MAX_NUM_PAIRS - 1) last = 0; pairs[last].solution1 = solution1; pairs[last].solution2 = solution2; pairs[last].gamma1 = pairs[cur_position].gamma1; pairs[last].gamma2 = gamma; numpairs++; } continue; } #else if (p->obj[0] == 0.0 && p->obj[1] == 0.0){ numinfeasible++; continue; }else if (p->obj[0] - solutions[solution1].obj[0] < compare_sol_tol && solutions[solution1].obj[1] - p->obj[1] < compare_sol_tol){ numinfeasible++; continue; }else if (solutions[solution2].obj[0] - p->obj[0] < compare_sol_tol && p->obj[1] - solutions[solution2].obj[1] < compare_sol_tol){ numinfeasible++; continue; } #endif /* Insert new solution */ numinfeasible = 0; if (last + 2 == MAX_NUM_PAIRS){ last = 0; previous = MAX_NUM_PAIRS - 1; }else if (last + 2 == MAX_NUM_PAIRS + 1){ last = 1; previous = 0; }else{ last += 2; previous = last - 1; } #ifdef BINARY_SEARCH pairs[previous].gamma1 = pairs[cur_position].gamma1; pairs[previous].gamma2 = gamma; pairs[last].gamma1 = gamma; pairs[last].gamma2 = pairs[cur_position].gamma2; #endif pairs[previous].solution1 = solution1; pairs[previous].solution2 = solution2; pairs[last].solution1 = solution2; pairs[last].solution2 = solution2+1; numpairs += 2; for (i = numsolutions; i > solution2; i--){ solutions[i] = solutions[i-1]; } numsolutions++; #ifndef LIFO if (first < last){ for (i = first; i < last - 1; i++){ if (pairs[i].solution1 >= solution2){ pairs[i].solution1++; } if (pairs[i].solution2 >= solution2){ pairs[i].solution2++; } } }else{ for (i = first; i < MAX_NUM_PAIRS - (last == 0 ? 1 : 0); i++){ if (pairs[i].solution1 >= solution2){ pairs[i].solution1++; } if (pairs[i].solution2 >= solution2){ pairs[i].solution2++; } } for (i = 0; i < last - 1; i++){ if (pairs[i].solution1 >= solution2){ pairs[i].solution1++; } if (pairs[i].solution2 >= solution2){ pairs[i].solution2++; } } } #endif length = solutions[solutions2].length = p->best_sol.xlength; indices = solutions[solutions2].indices = (int *) calloc(length, ISIZE); values = solutions[solutions2].values = (double *) calloc(length, DSIZE); memcpy((char *) indices, p->bestsol.xind, length * ISIZE); memcpy((char *) values, p->bestsol.xval, length * DSIZE); solutions[solution2].gamma = gamma; solutions[solution2].tau = tau; solutions[solution2].obj[0] = p->obj[0]; solutions[solution2].obj[1] = p->obj[1]; } printf("\n********************************************************\n"); if (numsolutions >= MAX_NUM_SOLUTIONS){ printf("Maximum number of solutions (%i) reached\n\n", MAX_NUM_SOLUTIONS); } if (numinfeasible >= MAX_NUM_INFEASIBLE){ printf("Maximum number of infeasible subproblems (%i) reached\n\n", MAX_NUM_INFEASIBLE); } if (numpairs >= MAX_NUM_PAIRS){ printf("Maximum number of solution pairs (%i) reached\n\n", MAX_NUM_PAIRS); printf("\n********************************************************\n"); #ifdef FIND_NONDOMINATED_SOLUTIONS printf( "* Found set of non-dominated solutions!!!!!!! *\n"); #else printf( "* Found set of supported solutions!!!!!!! *\n"); #endif }else{ printf("\n********************************************************\n"); #ifdef FIND_NONDOMINATED_SOLUTIONS printf( "* Found complete set of non-dominated solutions!!!!!!! *\n"); #else printf( "* Found complete set of supported solutions!!!!!!! *\n"); #endif } printf( "* Now displaying stats... *\n"); printf( "********************************************************\n\n"); #ifdef SAVE_CUT_POOL for (i = 0; i < env->par.tm_par.max_cp_num; i++){ env->comp_times.bc_time.cut_pool += env->cp[i]->cut_pool_time; env->warm_start->stat.cuts_in_pool += env->cp[i]->cut_num; } #endif print_statistics(&(env->comp_times.bc_time), &(env->warm_start->stat), 0.0, 0.0, 0, start_time); printf("\nNumber of subproblems solved: %i\n", numprobs); printf("Number of solutions found: %i\n\n", numsolutions); printf("***************************************************\n"); printf("***************************************************\n"); #ifdef FIND_NONDOMINATED_SOLUTIONS printf("Displaying non-dominated solution values and breakpoints\n"); #else printf("Displaying supported solution values and breakpoints\n"); #endif printf("***************************************************\n"); printf("***************************************************\n\n"); gamma0 = 1.0; for (i = 0; i < numsolutions - 1; i++){ #ifdef FIND_NONDOMINATED_SOLUTIONS gamma1 = (utopia[1] - solutions[i].obj[1])/ (utopia[0] - solutions[i+1].obj[0] + utopia[1] - solutions[i].obj[1]); #else slope = (solutions[i].obj[1] - solutions[i+1].obj[1])/ (solutions[i+1].obj[0] - solutions[i].obj[0]); gamma1 = slope/(1+slope); #endif printf("First Objective: %.3f Second Objective: %.3f ", solutions[i].obj[0], solutions[i].obj[1]); printf("Range: %.6f - %.6f\n", gamma1, gamma0); gamma0 = gamma1; } printf("First Objective: %.3f Second Objective: %.3f ", solutions[i].obj[0], solutions[i].obj[1]); printf("Range: %.6f - %.6f\n", 0.0, gamma0); for (i = 0 ; i < numsolutions; i++){ FREE(solutions[i].values); FREE(solutions[i].indices); } return(0); }