ILOBRANCHCALLBACK0(stopBranching)
{
	try {
		if (newBestSolution)
			if (this->getObjValue() < slnBest)
			{
				//cout << "obj nhanh nay:" << this->getObjValue() << " qua be so voi optimal hien tai = " << slnBest + 1<< " nen stop" << endl;
				nbReject++;
				this->prune();
				return;
			}
			else
				return;


		if (this->getBestObjValue() < slnBest + 1 && this->getObjValue() < slnBest + 1)
		{
			cout << "da tim thay optimal solution" << endl;;
			this->abort();
			return;
		}
		if (this->getObjValue() < slnBest + 1)
		{
			//cout << "obj nhanh nay:" << this->getObjValue() << " qua be so voi optimal hien tai = " << slnBest + 1<< " nen stop" << endl;
			nbReject++;
			this->prune();
			return;
		}


		if (earlyStopping == false)
			return;

		IloNumArray lbYmaster(this->getEnv());
		IloNumArray ubYmaster(this->getEnv());

		this->getLBs(lbYmaster, yMaster);
		this->getUBs(ubYmaster, yMaster);

		IloNumArray y_valBC(this->getEnv(), ttdp.N);
		vector<int> fixedNodes;

		long long h = 0;
		int unfixed = 0;
		int score = 0;

		int lb[11] = { 0 };
		for (int i = 0;i < ttdp.nbCat;i++) lb[i] = 0;

		int pos = 0;
		for (int i = 0;i < ttdp.N;i++)
			if (lbYmaster[i] == 1 && ubYmaster[i] == 1)
			{
				y_valBC[i] = 1;

				fixedNodes.push_back(i);
				//cout << i << " ";
				for (int j = 0;j < ttdp.category[i].size();j++)
					lb[ttdp.category[i][j]]++;

				score += ttdp.score[i];
			}
			else
			{
				if (lbYmaster[i] - ubYmaster[i])
					unfixed++;

				y_valBC[i] = 0;

				if (ownBranching && lbYmaster[i] - ubYmaster[i])
					if (ttdp.score[i] > ttdp.score[pos])
						pos = i;


			}
		//cout << endl;


		if (fixedNodes.size() == 2)
			return;

		if (unfixed == 0)
			return;

		if (score <= slnBest)
			if (!ownBranching)
			{
				return;
			}
			else //issues happen here
			{
				this->makeBranch(yFull[pos], 1, IloCplex::BranchDown, this->getObjValue());
				this->makeBranch(yFull[pos], 0, IloCplex::BranchUp, this->getObjValue());
				return;
			}



		for (int i = 0;i < ttdp.nbCat;i++)
			if (lb[i] < ttdp.lbCategory[i])
				return;

		//int ranVal = rand() % (int)( slnBest +1);

		//if (ranVal > score)
		//	return;


		updateSlaveModel(y_valBC);
		int startTime = this->getCplexTime();
		cplexSlave.solve();
		int endTime = this->getCplexTime();

		if (cplexSlave.getStatus() == IloAlgorithm::Infeasible)
		{
			cout << "we stop branching here because of infeasible POIs: ";
			for (int i = 0;i < fixedNodes.size();i++)
				cout << fixedNodes[i] << " ";
			cout << "at the node " << this->getNodeId() << " with " << unfixed << " unfixed variables and " << endTime - startTime << endl;

			nbReject++;

			inBranching = true;

			prepareCut(y_valBC);

			y_valBC.end();lbYmaster.end();ubYmaster.end();


			this->prune();

			return;
		}
		else
		{
			cout << "New solution found while branching: ";
			for (int i = 0;i < ttdp.N;i++)
				if (lbYmaster[i] == 1 && ubYmaster[i] == 1)
				{
					cout << i << " ";
				}
			cout << " with a value of " << score << endl;

			slnBest = score;
			LocalBranching(y_valBC);
			y_valBC.end();lbYmaster.end();ubYmaster.end();

			if (ownBranching) //issues happen here
			{
				this->makeBranch(yFull[pos], 1, IloCplex::BranchDown, this->getObjValue());
				this->makeBranch(yFull[pos], 0, IloCplex::BranchUp, this->getObjValue());
				return;
			}

		}
	}
	catch (IloException& ex) {
		cerr << "Error: " << ex << endl;
	}



}