/*Header file of the PStep_Brancher class

This class represents a function to branch on a node in the branching tree after a corresponding
relaxed solution has been found.

This file also includes derived classes of PStep_Brancher.

Implementation of PStep_MostFractionalEdgeBrancher can be found in PStep_MostFractionalEdgeBrancher.cpp.
Implementation of PStep_LysgaardBrancher can be found in PStep_LysgaardBrancher.cpp.

*/

#ifndef _PSTEP_TREENODEBRANCHER_H
#define _PSTEP_TREENODEBRANCHER_H

#include "PStep_AlgorithmMembers.h"

//Class used to represent a function to branch on a node in the branching tree.
//It branches on AlgorithmMembers.CurrentTreeNode. The current node is deleted
//from AlgorithmMembers.Nodes while the new node(s) are added to it.
class PStep_Brancher{
public:

	//Reference to AlgorithmMembers
	PStep_AlgorithmMembers& AlgorithmMembers;

	//Constructor functions
	//------------------------------------------------------------------------------------

	//Basic constructor
	PStep_Brancher(PStep_AlgorithmMembers& NewAlgorithmMembers)
		:AlgorithmMembers(NewAlgorithmMembers)
	{};

	//Branching functions
	//------------------------------------------------------------------------------------

	//Branch on AlgorithmMembers.CurrentTreeNode. The current node is deleted
	//from AlgorithmMembers.Nodes while the new node(s) are added to it.
	virtual void Branch()=0;

};

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Class used to represent a function to branch on a node in the branching tree.
//It branches on AlgorithmMembers.CurrentTreeNode. The current node is deleted
//from AlgorithmMembers.Nodes while the new node(s) are added to it.
//The most fractional edge is selected for branching.
//Only edges not connected to the depot are considered.
class PStep_MostFractionalEdgeBrancher : public PStep_Brancher{
public:

	//Constructor functions
	//------------------------------------------------------------------------------------

	//Basic constructor
	PStep_MostFractionalEdgeBrancher(PStep_AlgorithmMembers& NewAlgorithmMembers)
		:PStep_Brancher(NewAlgorithmMembers)
	{};

	//Branching functions
	//------------------------------------------------------------------------------------

	//Branch on AlgorithmMembers.CurrentTreeNode. The current node is deleted
	//from AlgorithmMembers.Nodes while the new node(s) are added to it.
	//Branch on the most fractional edge.
	//Only edges not connected to the depot are considered.
	virtual void Branch();

protected:

	//Branch on the most fractional edge.
	//Only edges not connected to the depot are considered.
	void BranchOnMostFractionalEdge();

};

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Class used to represent a function to branch on a node in the branching tree.
//It branches on AlgorithmMembers.CurrentTreeNode. The current node is deleted
//from AlgorithmMembers.Nodes while the new node(s) are added to it.
//The Lysgaard package is used to select a single set of edges to branch on.
//A set of edges is selected of which the degree of the current selection is
//in between 2 and 4, and as close as possible to 
//AlgorithmMembers.AlgorithmSettings.LysgaardTarget.
class PStep_LysgaardBrancher : public PStep_Brancher{
public:

	//Demand as required by Lysgaard
	//Lysgaard requires a 0 as first entry, and Demand[i] to correspond to customer i.
	//Also demand is required to be integer.
	int* LysgaardDemand;

	//Separation members:
	//------------------------------------------------------------------------------------
	//The current number of selected edges, plus one
	//Lysgaard requires a bogus first edge in the array.
	int NumberOfEdgesPlusOne;
	//Initialize arrays with edge information.
	int *EdgeTail;
	int *EdgeHead;
	double *EdgeX;

	//Constructor functions
	//------------------------------------------------------------------------------------

	//Basic constructor
	PStep_LysgaardBrancher(PStep_AlgorithmMembers& NewAlgorithmMembers);

	//Branching functions
	//------------------------------------------------------------------------------------

	//Branch on AlgorithmMembers.CurrentTreeNode. The current node is deleted
	//from AlgorithmMembers.Nodes while the new node(s) are added to it.
	//The Lysgaard package is used to select a single set of edges to branch on.
	//A set of edges is selected of which the degree of the current selection is
	//in between 2 and 4, and as close as possible to 
	//AlgorithmMembers.AlgorithmSettings.LysgaardTarget.
	virtual void Branch();

	//Other functions:
	//------------------------------------------------------------------------------------

	//Set the separation members pertaining to the used edges in the current solution,
	//i.e., NumberOfEdgesPlusOne, EdgeHead, EdgeTail, EdgeX.
	void SetCurrentEdges();

	//Destructor functions
	//------------------------------------------------------------------------------------

	//Default destructor
	virtual ~PStep_LysgaardBrancher();
};

#endif