示例#1
0
文件: mmkp.cpp 项目: AiTeamUSTC/ipge
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;
	}
}