Ejemplo n.º 1
0
void FacilityLocation::builSolutionGraph()
{
	if (s == NULL)
		s = new Graph();

	activeRouters = 0;
	activeArcs = 0;

	s->nVertices = g->nVertices;
	s->nTerminals = g->nTerminals;
	s->nArcs = g->nArcs;
	s->reserve(g->nVertices + 1);

	for (int i = 0; i < g->nTerminals; ++i)
	{
		Vertex terminal = g->terminals[i];

		s->addTerminal(terminal);
		s->addVertex(terminal);
	}

	for (auto& vit : vHash[Variable::V_Y])
	{
		int col = vit.second;
		Variable var = vit.first;
		Vertex v = var.getVertex1();
		int code = v.getCode();


		if (!v.isTerminal() && fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			++activeRouters;
			v.setColor("red");
			s->vertices[code] = v;
		}
	}
	printf("");

	for (auto & vit : vHash[Variable::V_X])
	{
		Arc arc = vit.first.getArc();
		int col = vit.second;

		if (fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			Vertex router = arc.getHead();
			Vertex terminal = arc.getTail();

			auto & element = g->arcSet[router.getCode()].find(arc);
			if (element != g->arcSet[router.getCode()].end())
			{
				arc.setColor("red");
				arc.setPenwidht(3.5);

				s->addArc(arc);
			}
			else
			{
				std::vector<Arc> path;
				findShortestPath(router, terminal, g, path);

				for (int i = 0; i < path.size(); ++i)
				{
					Arc aux = path[i];
					aux.setColor("red");
					aux.setPenwidht(1.5);

					s->addArc(aux);
					s->vertices[aux.getHead().getCode()].setColor("red");
				}
				activeArcs += path.size();
				printf("");
			}
		}

	}
	printf("");

	for (auto& vit : vHash[Variable::V_Z])
	{
		Variable v = vit.first;
		int col = vit.second;
		Arc arc = v.getArc();

		if (fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			++activeArcs;
			arc.setColor("red");
			arc.setPenwidht(3.5);
		}
		else
		{
			arc.setColor("black");
			arc.setStyle("dotted");
			arc.setPenwidht(1.0);
		}
		s->addArc(arc);
	}
	printf("");
#ifdef DEBUG
	s->toDot();
#endif

	return;
}
Ejemplo n.º 2
0
SolverMIP::SOLVERSTAT FacilityLocation::solveLRExtentedFormulations(MulltipleCutSetSeparation _cutSetSepFunc, double _tol)
{
	int pos = 0;
	int nbCuts = 0;
	int sentinel = 0;
	int MAX_ITER = 100;
	int tailOffCounter = 0;
	int tailOffTol = 3;
	int printInterval = 5;
	double currentLp = 0., lastLp = 0.;
	bool noViolatedCutFound = true;
	std::set<long> hashTable;
	TypeVariableHashPtr vHashPtr = &(vHash);
	std::vector<std::set<int>*> cutSets;
	SolverMIP::SOLVERSTAT ret = SolverMIP::SOLVERSTAT::SOLVERSTAT_UNKNOWN;

	if (xSol != NULL)
		delete[] xSol;

	xSol = new double[getNCols()];
	
	clock_t start = clock();
	do
	{
		lastLp = currentLp;
		status = SolverMIP::solve(SolverMIP::METHOD::METHOD_DUAL);

		if (status == SolverMIP::SOLVERSTAT::SOLVERSTAT_MIPOPTIMAL || status == SolverMIP::SOLVERSTAT::SOLVERSTAT_LPOPTIMAL ||
			status == SolverMIP::SOLVERSTAT::SOLVERSTAT_FEASIBLE)
		{
			ret = SolverMIP::SOLVERSTAT::SOLVERSTAT_FEASIBLE;
			currentLp = getObjVal();

			// Getting fractional node solution
			getX();

			if (sentinel % printInterval == 0)
			{
				printf("\n---- iter: %d\n", sentinel + 1);
				printf("OBJ_VAL = %lf\n", currentLp);
			}

#ifndef DEBUG
			//Printing xNode solution
			printf("\n\n---- iter: %d\n", sentinel + 1);
			for (int varType = Variable::V_X; varType != Variable::V_UNKNOWN; varType += 10)
			{
				VariableHash::iterator vit = vHashPtr->at((Variable::VARTYPE)varType).begin();
				for (; vit != vHashPtr->at((Variable::VARTYPE)varType).end(); ++vit)
				{
					int idx = vit->second;

					if (xSol[idx] > SOLVER_EPS)
						std::cout << (vit->first).toString() << "(" << idx << "); " << xSol[idx] << std::endl;
					printf("");
				}
				printf("");
			}
#endif
			// Verifying optimality conditions
			if (fabs(currentLp - lastLp) < _tol)
			{
				++tailOffCounter;
				if (tailOffCounter > tailOffTol)
				{
					ret = SolverMIP::SOLVERSTAT::SOLVERSTAT_LPOPTIMAL;
					break;
				}
			}
			else
				tailOffCounter = 0;

			// Calling the separation routine
			pos = cutSets.size();
			int cutSize = _cutSetSepFunc(g, vHashPtr, xSol, cutSets, true);

			// If a fractional cycle is found...
			if (cutSets.size() - pos > 0)
			{
				noViolatedCutFound = false;

				for (int i = pos; i < cutSets.size(); ++i)
				{
					std::set<int>* sPtr = cutSets[i];
					// Check whether the cut has already been generated
					unsigned long hashVal = hashFunc(*sPtr);
					std::set<long>::iterator it = hashTable.find(hashVal);
					if (it != hashTable.end())
					{
#ifdef DEBUG
						int warnCode = 990;
						std::string aux = convertSetToString(s);
						std::string msg = "The identified cut set was already separated " + convertSetToString(s);
						warningMsg(NULL, __func__, msg.data(), warnCode);
#endif
					}
					else
						hashTable.insert(hashVal);

					// ... we must find the cut set ...
					std::vector<Variable> cutSet;
					for (VariableHash::iterator vit = vHashPtr->at(Variable::V_Z).begin(); vit != vHashPtr->at(Variable::V_Z).end(); ++vit)
					{
						Variable z = vit->first;
						int head = z.getArc().getHead().getCode();
						int tail = z.getArc().getTail().getCode();

						std::set<int>::iterator hIt = sPtr->find(head);
						std::set<int>::iterator tIt = sPtr->find(tail);

						// ... which is composed by those arcs with one endpoint in S
						bool isHeadInS = hIt != sPtr->end();
						bool isTailInS = tIt != sPtr->end();
						if (!(isHeadInS && isTailInS) && (isHeadInS || isTailInS))
						{
							cutSet.push_back(z);
						}
					}

					// Identifying the y-variables involved in cut set constraints
					// And split them into two sets
					std::vector<Variable> sVec;
					std::vector<Variable> sCompVec;
					for (VariableHash::iterator vit = vHashPtr->at(Variable::V_Y).begin(); vit != vHashPtr->at(Variable::V_Y).end(); ++vit)
					{
						Variable v = vit->first;
						int nodeIdx = v.getVertex1().getCode();

						if (sPtr->find(nodeIdx) != sPtr->end())
						{
							sVec.push_back(v);
						}
						else
						{
							sCompVec.push_back(v);
						}
					}

					// Translating valid inequalities found into cplex/matrix representation
					int nzcnt = cutSet.size() + 2;
					std::vector<int> idx(nzcnt);
					std::vector<double> val(nzcnt);
					for (int i = 0; i < sVec.size(); ++i)
					{
						idx[0] = sVec[i].getColIdx();
						val[0] = -1.0;
						for (int j = 0; j < sCompVec.size(); ++j)
						{
							idx[1] = sCompVec[j].getColIdx();
							val[1] = -1.0;

							for (int k = 0; k < cutSet.size(); ++k)
							{
								idx[k + 2] = cutSet[k].getColIdx();
								val[k + 2] = 1.0;
							}

							// Adding user generated cut
							int nRows = 1;
							double rhs = -1;
							char sense = 'G';
							int rmatbeg = 0;
							int newColsAdded = 0;
							status = CPXaddrows(env, lp, newColsAdded, nRows, nzcnt, &rhs, &sense, &rmatbeg, &idx[0], &val[0], NULL, NULL);
							//status = CPXcutcallbackadd(_env, _cbdata, _wherefrom, nzcnt, -1, 'G', &idx[0], &val[0], CPX_USECUT_FORCE);
							if (status)
							{
								int warnCode = 999;
								std::string msg = "Failed to add integer cut.";
								warningMsg(NULL, __func__, msg.data(), warnCode);
							}
							else
								nbCuts++;

							printf("");
						}
					}
				}
#ifdef DEBUG
					// salva um arquivo .lp com o LP atual
					writeProbLP(".\\lpRelax");
#endif
			}
			else
			{
				// No violated cut was found
				noViolatedCutFound = true;
			}
		
			// If no violated cut was found
			if (noViolatedCutFound)
			{
				ret = SolverMIP::SOLVERSTAT::SOLVERSTAT_LPOPTIMAL;
				break;
			}
		}
		else
		{
			int warnCode = 201;
			std::string msg = "Model is infeasible";
			warningMsg(typeid(*this).name(), __func__, msg.data(), warnCode);

			// salva um arquivo .lp com o LP atual
			writeProbLP(".\\infeasible");

			ret = SolverMIP::SOLVERSTAT::SOLVERSTAT_INFEASIBLE;
			break;
		}

	} while (++sentinel < MAX_ITER);

	// Deallocating memory
	for (int i = 0; i < cutSets.size(); ++i)
	{
		if (cutSets[i] != NULL)
		{
			delete cutSets[i];
			cutSets[i] = NULL;
		}
	}

	clock_t end = clock();
	printf("\n-----");
	printf("\n----- iter: %d", sentinel + 1);
	printf("\n----- OBJ_VAL = %lf", currentLp);
	printf("\n----- Exectution time: %.4f", (end - start) / (double)CLOCKS_PER_SEC);

	return ret;
}
Ejemplo n.º 3
0
void Flow::builSolutionGraph()
{
	if (s == NULL)
		s = new Graph();

	int activeRouters = 0;
	int activeArcs = 0;

	s->nVertices = g->nVertices;
	s->nTerminals = g->nTerminals;
	s->nArcs = g->nArcs;
	s->reserve(g->nVertices + 1);

	for (int i = 0; i < g->nTerminals; ++i)
	{
		Vertex terminal = g->terminals[i];

		s->addTerminal(terminal);
		s->addVertex(terminal);
	}

	for (auto & vit : vHash[Variable::V_X])
	{
		int col = vit.second;
		Variable var = vit.first;
		Arc arc = var.getArc();
		Vertex h = var.getArc().getHead();
		Vertex t = var.getArc().getTail();

		if (!h.isTerminal() && xSol[col] > SOLVER_EPS)
		{
			++activeRouters;
			h.setColor("red");
			s->vertices[h.getCode()] = h;
		}

		if (!t.isTerminal() && xSol[col] > SOLVER_EPS)
		{
			++activeRouters;
			t.setColor("red");
			s->vertices[t.getCode()] = t;
		}

		if (xSol[col] > SOLVER_EPS)
		{
			++activeArcs;
			arc.setColor("red");
			arc.setPenwidht(3.5);
		}
		else
		{
			arc.setColor("black");
			arc.setStyle("dotted");
			arc.setPenwidht(1.0);
		}
		s->addArc(arc);
	}

#ifdef DEBUG
	s->toDot();
#endif

	return;

}