/*Implementation of PStep_SeparationAlgorithm.h

It contains the member functions of PStep_SeparationAlgorithm7

*/

#include "PStep_SeparationAlgorithm.h"

//PStep_SeparationAlgorithm7:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Separate
//------------------------------------------------------------------------------------

//Separate cuts using the package of Lysgaard. Separate capacity cuts, if it fails
//separate framed capacity cuts. Then separate in revolving order (until one is succesful
//or all have failed) homogenous multistar, strengthened comb and 2 edge hypotour cuts.
void PStep_SeparationAlgorithm7::Separate(){

	//Prepare the selected edges
	SetCurrentEdges();

	//Check whether there are any positively selected edges
	if (NumberOfEdgesPlusOne > 1){
		
		//Obtain current number of capacity cuts
		int NumberOfCCBeforeSeparation = AlgorithmMembers.NumberOfCapacityCuts;

		//Separate capacity cuts
		SeparateCCLysgaard();
		
		//Check whether new capacity cuts were added
		if (NumberOfCCBeforeSeparation == AlgorithmMembers.NumberOfCapacityCuts){

			//Obtain current number of framed capacity cuts
			int NumberOfFCCBeforeSeparation = AlgorithmMembers.NumberOfFramedCapacityCuts;

			//Separate framed capacity cuts
			SeparateFCCLysgaard();

			//Check whether new capacity cuts were added
			if (NumberOfFCCBeforeSeparation == AlgorithmMembers.NumberOfFramedCapacityCuts){
				//No violated capacity cuts were identified, separate cuts using revolving separation
				
				//Check which revolving separation routine should be used
				if (RevolvingIndex == 1){
					RevolvingSeparation1();
				}
				else if (RevolvingIndex == 2){
					RevolvingSeparation2();
				}
				else{
					RevolvingSeparation3();
				}

			}
			
		}
		
	}

}

//Revolving separationg routines:
//------------------------------------------------------------------------------------

//Separate cuts of multiple types using the package of Lysgaard. If the separation of one
//type fails, move to the next type. The types are in order: 
//homogenous multistar, strengthened comb and 2 edge hypotour cuts
void PStep_SeparationAlgorithm7::RevolvingSeparation1(){

	//Obtain current number of homogeneous mutlistar cuts
	int NumberOfHMCBeforeSeparation = AlgorithmMembers.NumberOfHomogeneousMultistarCuts;

	//Separate homogeneous multistar cuts
	SeparateHMCLysgaard();

	//Check whether new homogeneous multistar cuts were added
	if (NumberOfHMCBeforeSeparation == AlgorithmMembers.NumberOfHomogeneousMultistarCuts){
		//No violated homogeneous multistar cuts were identified, separate strengthened comb cuts

		//Obtain current number of strengthened comb cuts
		int NumberOfSCombBeforeSeparation = AlgorithmMembers.NumberOfSCombCuts;

		//Separate strengthened comb cuts
		SeparateSCombLysgaard();

		//Check whether new strengthened comb cuts were added
		if (NumberOfSCombBeforeSeparation == AlgorithmMembers.NumberOfSCombCuts){
			//No violated strengthened comb cuts were identified, separate 2 edge hypotour cuts

			//Separate 2 edge hypotour cuts
			Separate2EHLysgaard();

		}

	}

	//Update revolving index
	RevolvingIndex = 2;

}

//Separate cuts of multiple types using the package of Lysgaard. If the separation of one
//type fails, move to the next type. The types are in order: 
//strengthened comb, 2 edge hypotour cuts and homogenous multistar
void PStep_SeparationAlgorithm7::RevolvingSeparation2(){

	//Obtain current number of strengthened comb cuts
	int NumberOfSCombBeforeSeparation = AlgorithmMembers.NumberOfSCombCuts;

	//Separate strengthened comb cuts
	SeparateSCombLysgaard();

	//Check whether new strengthened comb cuts were added
	if (NumberOfSCombBeforeSeparation == AlgorithmMembers.NumberOfSCombCuts){
		//No violated strengthened comb cuts were identified, separate 2 edge hypotour cuts

		//Obtain current number of 2 edge hypotour cuts
		int NumberOf2EHBeforeSeparation = AlgorithmMembers.NumberOf2EHCuts;

		//Separate 2 edge hypotour cuts
		Separate2EHLysgaard();

		//Check whether new 2 edge hypotour cuts were added
		if (NumberOf2EHBeforeSeparation == AlgorithmMembers.NumberOf2EHCuts){
			//No violated 2 edge hypotour cuts were identified, separate homogeneous multistar cuts

			//Separate homogeneous multistar cuts
			SeparateHMCLysgaard();

		}

	}

	//Update revolving index
	RevolvingIndex = 3;

}

//Separate cuts of multiple types using the package of Lysgaard. If the separation of one
//type fails, move to the next type. The types are in order: 
//2 edge hypotour cuts, homogenous multistar and strengthened comb
void PStep_SeparationAlgorithm7::RevolvingSeparation3(){

	//Obtain current number of 2 edge hypotour cuts
	int NumberOf2EHBeforeSeparation = AlgorithmMembers.NumberOf2EHCuts;

	//Separate 2 edge hypotour cuts
	Separate2EHLysgaard();

	//Check whether new 2 edge hypotour cuts were added
	if (NumberOf2EHBeforeSeparation == AlgorithmMembers.NumberOf2EHCuts){
		//No violated 2 edge hypotour cuts were identified, separate homogeneous multistar cuts

		//Obtain current number of homogeneous mutlistar cuts
		int NumberOfHMCBeforeSeparation = AlgorithmMembers.NumberOfHomogeneousMultistarCuts;

		//Separate homogeneous multistar cuts
		SeparateHMCLysgaard();

		//Check whether new homogeneous multistar cuts were added
		if (NumberOfHMCBeforeSeparation == AlgorithmMembers.NumberOfHomogeneousMultistarCuts){
			//No violated homogeneous multistar cuts were identified, separate strengthened comb cuts

			//Separate strengthened comb cuts
			SeparateSCombLysgaard();

		}

	}

	//Update revolving index
	RevolvingIndex = 1;

}