int main(int argc, char *argv[]){ if(argc<3){ printf("useage:./solve file time_limit\n"); return 0; } srand(11); read_inst(argv[1]); int time_limit=atoi(argv[2]); //solveIP(10); solveLP(); cpu_time(); int cnt=0; double ratio=0.5; int i=len_rdCost1-1; double maxRdc=0.0; maxIte=n*10; while(cpu_time()<time_limit && maxRdc<UB-LB-EPSILON){ double t_remain=time_limit-cpu_time(); if(t_remain<EPSILON) break; if(i<0) maxRdc= UB - LB; else maxRdc=rdCost_sort1[i].value-EPSILON; printf("iteration %d, cup_time:%lf, maxRdc %lf, LB =%lf\n", cnt, cpu_time(),maxRdc, LB); solveIP(t_remain,cnt, maxRdc); cnt++; printf("--------------\n\n"); i--; //while(i>=0&&rdCost_sort1[i].value<maxRdc+0.1){i--;} } printf("best LB is %lf, cpu_time %lf\n", LB, cpu_time()); deleteAll(); return 0; }
Vector<Tree *> ColumnGenSolve::route(int tim) const { // Open a console for output OFStream con("con"); auto clkStart = clock(); // Constant definition const Board *board = solver->board; const Vector<TerminalSet *> &termsets = board->terminalSets; const Matrix<int> &map = board->map; const int t = termsets.size() - 1; const int n = board->height; const int m = board->width; if(n * m >= 1250) cout << "solving subproblem " << n << " * " << m << "\n"; // Two useful Vectors /* Vector<Point> allPoints; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) allPoints.push_back(Point(i, j)); */ Matrix<double> all1; all1.resize(n, m); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) all1[i][j] = 1; // The tree set, initially empty Vector<Vector<Pair<Tree, GRBVar>>> treesets; for(int idx = 1; idx <= t; idx++) { // Current tree set Vector<Pair<Tree, GRBVar>> vec; // Add the set to the set list treesets.push_back(vec); } // Answer history Vector<double> tarAns; for(int T = 0;; T++){ // Solve the integer (binary) programming problem double curAns = solveLP(treesets, 1); tarAns.push_back(curAns); // Construct current best answer Vector<Tree *> ans; for(const auto &treeset: treesets) { for(const auto &treeVar: treeset) if(treeVar.second.get(GRB_DoubleAttr_X) > 0.5) { ans.push_back(new Tree(treeVar.first)); goto found; } ans.push_back(NULL); found:; } bool updated = false; // Build weight map for unrouted set Matrix<double> mapObs; mapObs.resize(n, m); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(map[i][j] == -1) mapObs[i][j] = M; else mapObs[i][j] = 1; for(int idx = 1; idx <= t; idx++) if(ans[idx - 1]) for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(ans[idx - 1]->map.get(i, j)) mapObs[i][j] = M; // Try to generate from each set for(int idx = 1; idx <= t; idx++) { if(termsets[idx]->points.empty()) continue; if(!ans[idx - 1]){ // If unrouted, try to generate from the map above if(suggestTree(termsets, treesets, mapObs, n, m, idx)) updated = true; }else{ // If routed { // Try to reroute current set Matrix<double> mapObs2 = mapObs; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if( mapObs2[i][j] >= M / 2 && ans[idx - 1]->map.get(i, j) ) mapObs2[i][j] = 1; if(suggestTree(termsets, treesets, mapObs2, n, m, idx)) updated = true; } { /* Try to reroute current set and try to route another tree rather than current tree */ Matrix<double> mapObs2 = mapObs; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if( mapObs2[i][j] >= M / 2 && !ans[idx - 1]->map.get(i, j) ) mapObs2[i][j] = M * M; if(suggestTree(termsets, treesets, mapObs2, n, m, idx)) updated = true; } { /* Try to solve integer programming without current set and try to avoid overlap between current tree and the solution above */ solveLP(treesets, 1, NULL, NULL, idx); Vector<Tree *> tmpAns; for(int i = 0; i < t; i++) if(i != idx - 1) { for(const auto &treeVar: treesets[i]) if(treeVar.second.get(GRB_DoubleAttr_X) > 0.5) { tmpAns.push_back(new Tree(treeVar.first)); goto found2; } tmpAns.push_back(NULL); found2:; } else tmpAns.push_back(NULL); // OK, let's construct weight map Matrix<double> mapObs2; mapObs2.resize(n, m); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(map[i][j] == -1) mapObs2[i][j] = M * M; else mapObs2[i][j] = 1; for(int nidx = 1; nidx <= t; nidx++) if(tmpAns[nidx - 1]) for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(tmpAns[nidx - 1]->map.get(i, j)) mapObs2[i][j] = M; if(suggestTree(termsets, treesets, mapObs2, n, m, idx)) updated = true; // clean up for(auto tree: tmpAns) delete tree; } } } auto clkNow = clock(); // If solution didn't improve recently, // cut! if(T >= 1 && fabs(tarAns[T - 1] - tarAns[T]) < 0.5) return ans; // Output current colution info if(n * m >= 20) { cout << "iteration " << T << "\n"; cout << "current time: " << (int) ((clkNow - clkStart) / CLOCKS_PER_SEC) << " seconds\n"; cout << "curAns " << curAns << endl; cout << "column sizes:\n"; for(const auto &treeset: treesets) cout << treeset.size() << " "; cout << "\n"; cout.flush(); if(n * m >= 80) { Solution solution; solution.board = solver->board; solution.trees.push_back(NULL); for(auto tree: ans) if(tree) solution.trees.push_back(new Tree(*tree)); else solution.trees.push_back(NULL); solution.computeMap(); con << solution; con.flush(); } } // Still cannot generate, cut if(!updated) return ans; // Clean up for(auto tree: ans) delete tree; } }