void
DL_my_algo_PacketScheduler2::RBsAllocation ()
{
#ifdef SCHEDULER_DEBUG
	std::cout << " ---- DL_my_algo_PacketScheduler2::my_algo";
#endif

  FlowsToSchedule* flows = GetFlowsToSchedule ();
  
  int nbOfRBs = GetMacEntity ()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetDlSubChannels ().size ();

  //create a matrix of flow metrics
  double metrics[nbOfRBs][flows->size ()];
  /*
  for (int i = 0; i < nbOfRBs; i++)
    {
	  for (int j = 0; j < flows->size (); j++)
	    {
		  metrics[i][j] = ComputeSchedulingMetric (flows->at (j)->GetBearer (),
				                                   flows->at (j)->GetSpectralEfficiency ().at (i),
	    		                                   i);
	    }
    }*/

#ifdef SCHEDULER_DEBUG
  std::cout << ", available RBs " << nbOfRBs << ", flows " << flows->size () << std::endl;
  /*for (int ii = 0; ii < flows->size (); ii++)
    {
	  std::cout << "\t metrics for flow "
			  << flows->at (ii)->GetBearer ()->GetApplication ()->GetApplicationID () << ":";
	  for (int jj = 0; jj < nbOfRBs; jj++)
	    {
		  std::cout << " " << metrics[jj][ii];
	    }
	  std::cout << std::endl;
    }*/
#endif


  AMCModule *amc = GetMacEntity ()->GetAmcModule ();
  double l_dAllocatedRBCounter = 0;

  int l_iNumberOfUsers = ((ENodeB*)this->GetMacEntity()->GetDevice())->GetNbOfUserEquipmentRecords();

  bool * l_bFlowScheduled = new bool[flows->size ()];
  int l_iScheduledFlows = 0;
  std::vector<double> * l_bFlowScheduledSINR = new std::vector<double>[flows->size ()];
  
  int radius=NetworkManager::Init()->GetCellByID (0)->GetRadius()*1000;              //get radius
  std::vector<UserEquipment*>* users = NetworkManager::Init()->GetUserEquipmentContainer();
  int nbUE=users->size();
  int nbCell = NetworkManager::Init()->GetNbCell();
  int nbFlows = total_flow::Init()->get_total_flows();
  const double guarantee_MB=total_flow::Init()->get_data_rate();        
  const double guarantee_bit = (guarantee_MB*1000*8.0)/100 ;            //bit per TTI
  static std::vector<bool> IsCell_Center(nbUE*nbFlows , false);
  static std::vector<double> credit(nbUE,0.0);
  vector<bool> flag(nbUE*nbFlows, false);
  
  for (int i=0;i<nbUE;i++)
  {
        //---------------get ue radius----------
        double x=users->at(i)->GetMobilityModel ()->GetAbsolutePosition()->GetCoordinateX();    //ue x,y position
        double y=users->at(i)->GetMobilityModel ()->GetAbsolutePosition()->GetCoordinateY();
        
        double x1=users->at(i)->GetCell () ->GetCellCenterPosition ()->GetCoordinateX ();       //enb x,y position
        double y1=users->at(i)->GetCell () ->GetCellCenterPosition ()->GetCoordinateY ();
                             
        double ue_radius=sqrt( (x-x1)*(x-x1) + (y-y1)*(y-y1) );          
        //Enb ID = users->at(i)->GetCell ()->GetIdCell()
        //UEid = users->at(i)->GetIDNetworkNode()
                        
        if(ue_radius < radius*2.0/3){
                for(int k=i*nbFlows;k<(i+1)*nbFlows;k++){                             
                        IsCell_Center[k]=true;
                }
        }else{
                for(int k=i*nbFlows;k<(i+1)*nbFlows;k++){                           
                        IsCell_Center[k]=false;
                }
        }           
  }

  //RBs allocation
  std::vector<vector<double> >  my_metrics(nbOfRBs, vector<double>(flows->size ()));
  
  int max_edge_RB=0;
        double edge_demand_bit=0;
        double center_demand_bit=0;
        double total_demand_bit=0;
        for(int k=0;k<flows->size ();k++)
        {
                if(IsCell_Center[flows->at (k)->GetBearer ()->GetApplication ()->GetApplicationID ()]==false){
                      edge_demand_bit+=flows->at (k)->GetDataToTransmit(); 
                }else{
                        center_demand_bit+=flows->at (k)->GetDataToTransmit();
                }
        }
        if( ( edge_demand_bit/(edge_demand_bit + center_demand_bit) ) * nbOfRBs <  1.0/5.0*nbOfRBs){
                max_edge_RB=( edge_demand_bit/( edge_demand_bit + center_demand_bit) ) * nbOfRBs;
        } else{
                max_edge_RB=1.0/5.0*nbOfRBs;
        }
        total_demand_bit = edge_demand_bit + center_demand_bit;
        
   vector<double> copy_credit(nbUE , 0.0 );
   copy_credit.assign(credit.begin(), credit.end());
   for(int i=0;i<nbUE;i++){
        if(copy_credit[i]>0){
               copy_credit[i]=0; 
        }
   } 
   double min= *min_element(copy_credit.begin(), copy_credit.end());
   for(int i=0;i<nbUE;i++){
        copy_credit[i]-=min;
   }

   double max= *max_element(copy_credit.begin(), copy_credit.end());
   if(max==0){
        max=1;
   }
   double sum_credit=0;
   for(int i=0;i<nbUE;i++){
        //cout << "copy_credit[" << i << "] = " << copy_credit[i]/max << endl;
        sum_credit+=(2-copy_credit[i]/max);
   }

  vector<double> cqi(flows->size (),0.0);
  for (int j = 0; j < flows->size (); j++)
  {
      for (int s = 0; s < nbOfRBs; s++)
      { 
            cqi.at(j)+=flows->at (j)->GetCqiFeedbacks ().at(s);
      }
      cqi.at(j)/=nbOfRBs;
  }
  

  for (int s = 0; s < nbOfRBs; s++)
  {
      for (int j = 0; j < flows->size (); j++)
      {            
	        my_metrics[s][j] = mlwdf_ComputeSchedulingMetric (flows->at (j)->GetBearer (),
	                                   flows->at (j)->GetSpectralEfficiency ().at (s),
		                                   s,copy_credit[flows->at (j)->GetBearer ()->GetApplication ()->GetApplicationID ()/nbFlows]/max ,
                                                      sum_credit/nbUE ,flows->at (j)->GetDataToTransmit(),flows->at (j)->GetCqiFeedbacks ().at(s)/cqi.at(j));
      }
      
      for (int j = 0; j < flows->size (); j++)
      {
                metrics[s][j] = ComputeSchedulingMetric1 (flows->at (j)->GetBearer (),
                                           flows->at (j)->GetSpectralEfficiency ().at (s),
   		                                   s,flows->at (j)->GetDataToTransmit(),
		                                   total_demand_bit,copy_credit[flows->at (j)->GetBearer ()->GetApplication ()->GetApplicationID ()/nbFlows]/max ,
                                                      sum_credit/nbUE);
      }
	    
      if (l_iScheduledFlows == flows->size ())
          break;

      double targetMetric = 0;
      bool RBIsAllocated = false;
      FlowToSchedule* scheduledFlow;
      int l_iScheduledFlowIndex = 0;
      
      //std::cout << "avg_cqi = " << avg_cqi << std::endl;

      RBIsAllocated = false;
      if(s<max_edge_RB)
      {
            targetMetric=-1;
            for(int k=0;k<flows->size ();k++)
            {          
                if(metrics[s][k] > targetMetric && !l_bFlowScheduled[k] && flows->at (k)->GetDataToTransmit() >0 
                        && IsCell_Center[flows->at (k)->GetBearer ()->GetApplication ()->GetApplicationID ()]==false)
                {
                        targetMetric=metrics[s][k];
                        RBIsAllocated = true;
                        scheduledFlow = flows->at (k);
                        l_iScheduledFlowIndex = k;
                }
            }
            if(!RBIsAllocated)
            {
                targetMetric=-1;
                for(int k=0;k<flows->size ();k++)
                {
                        if(my_metrics[s][k] > targetMetric && !l_bFlowScheduled[k] && flows->at (k)->GetDataToTransmit() >0 )
                        {
                                targetMetric=my_metrics[s][k];
                                RBIsAllocated = true;
                                scheduledFlow = flows->at (k);
                                l_iScheduledFlowIndex = k;
                        }
                }        
            }
      }else
      {
           targetMetric=-1;
           l_iScheduledFlowIndex=0;
           for (int k = 0; k < flows->size (); k++)
           {    
               if (my_metrics[s][k] > targetMetric && !l_bFlowScheduled[k] && flows->at (k)->GetDataToTransmit() >0 )
               {
                        targetMetric = my_metrics[s][k];
                        RBIsAllocated = true;
                        scheduledFlow = flows->at (k);
                        l_iScheduledFlowIndex = k;               
                        //std::cout << "\tschedule to flow : " << flows->at (k)->GetBearer ()->GetApplication ()->GetApplicationID () << std::endl;  
               }                   
           }     
      }

        
      if (RBIsAllocated)
        {
          l_dAllocatedRBCounter++;

          scheduledFlow->GetListOfAllocatedRBs()->push_back (s); // the s RB has been allocated to that flow!

#ifdef SCHEDULER_DEBUG
         /* std::cout << "\t *** RB " << s << " assigned to the "
                  " flow " << scheduledFlow->GetBearer ()->GetApplication ()->GetApplicationID ()
                  << std::endl;*/
            std::cout << "\t *** RB " << s << " assigned to the "
                  " flow " << scheduledFlow->GetBearer ()->GetApplication ()->GetApplicationID ()
                  << "  cqi   " << scheduledFlow->GetCqiFeedbacks ().at (s)
                  << "  cell_center  " << IsCell_Center[scheduledFlow->GetBearer ()->GetApplication ()->GetApplicationID ()]
                  << std::endl;
#endif
          double sinr = amc->GetSinrFromCQI (scheduledFlow->GetCqiFeedbacks ().at (s));
          l_bFlowScheduledSINR[l_iScheduledFlowIndex].push_back(sinr);

          double effectiveSinr = GetEesmEffectiveSinr (l_bFlowScheduledSINR[l_iScheduledFlowIndex]);
          int mcs = amc->GetMCSFromCQI (amc->GetCQIFromSinr (effectiveSinr));
          int transportBlockSize = amc->GetTBSizeFromMCS (mcs, scheduledFlow->GetListOfAllocatedRBs ()->size ());
          if (transportBlockSize >= scheduledFlow->GetDataToTransmit() * 8)
          {
             #ifdef SCHEDULER_DEBUG   
              cout << "-- FLOW " << scheduledFlow->GetBearer ()->GetApplication ()->GetApplicationID () << ", demand = " << scheduledFlow->GetDataToTransmit()*8 << ", transportBlockSize = " 
              << transportBlockSize << endl;
              #endif
              l_bFlowScheduled[l_iScheduledFlowIndex] = true;
              l_iScheduledFlows++;
          }
        }
    }

  delete [] l_bFlowScheduled;
  delete [] l_bFlowScheduledSINR;


  //Finalize the allocation
  PdcchMapIdealControlMessage *pdcchMsg = new PdcchMapIdealControlMessage ();

  for (FlowsToSchedule::iterator it = flows->begin (); it != flows->end (); it++)
    {
      FlowToSchedule *flow = (*it);
      if (flow->GetListOfAllocatedRBs ()->size () > 0)
        {
          //cout << "----------------------------------" << endl;
          //this flow has been scheduled
          std::vector<double> estimatedSinrValues;
          for (int rb = 0; rb < flow->GetListOfAllocatedRBs ()->size (); rb++ )

            {
              double sinr = amc->GetSinrFromCQI (
                      flow->GetCqiFeedbacks ().at (flow->GetListOfAllocatedRBs ()->at (rb)));
	      //cout << "CQI = " << flow->GetCqiFeedbacks ().at (flow->GetListOfAllocatedRBs ()->at (rb)) << endl;
              estimatedSinrValues.push_back (sinr);
            }

          //compute the effective sinr
          double effectiveSinr = GetEesmEffectiveSinr (estimatedSinrValues);

          //get the MCS for transmission
          //cout << "effectiveCQI = " << amc->GetCQIFromSinr (effectiveSinr) << endl;
          int mcs = amc->GetMCSFromCQI (amc->GetCQIFromSinr (effectiveSinr));

          //define the amount of bytes to transmit
          //int transportBlockSize = amc->GetTBSizeFromMCS (mcs);
          int transportBlockSize = amc->GetTBSizeFromMCS (mcs, flow->GetListOfAllocatedRBs ()->size ());
          double bitsToTransmit = transportBlockSize;
          flow->UpdateAllocatedBits (bitsToTransmit);

#ifdef SCHEDULER_DEBUG
		  std::cout << "\t\t --> flow "	<< flow->GetBearer ()->GetApplication ()->GetApplicationID ()
				  << " has been scheduled: " <<
				  "\n\t\t\t nb of RBs " << flow->GetListOfAllocatedRBs ()->size () <<
				  "\n\t\t\t effectiveSinr " << effectiveSinr <<
				  "\n\t\t\t tbs " << transportBlockSize <<
				  "\n\t\t\t bitsToTransmit " << bitsToTransmit
				  << std::endl;
#endif

                credit[flow->GetBearer ()->GetApplication ()->GetApplicationID()/nbFlows]+=bitsToTransmit;               //new add

		  //create PDCCH messages
		  for (int rb = 0; rb < flow->GetListOfAllocatedRBs ()->size (); rb++ )
		    {
			  pdcchMsg->AddNewRecord (PdcchMapIdealControlMessage::DOWNLINK,
					  flow->GetListOfAllocatedRBs ()->at (rb),
									  flow->GetBearer ()->GetDestination (),
									  mcs);
		    }
	    }
    }

  if (pdcchMsg->GetMessage()->size () > 0)
    {
      GetMacEntity ()->GetDevice ()->GetPhy ()->SendIdealControlMessage (pdcchMsg);
    }
  delete pdcchMsg;
        
        for (int i = 0; i< nbUE ; i++ )                         //new add
	{
	        credit[i]-=guarantee_bit;
                //cout << "credit[" << i << "] = " << credit[i] << endl;
	}       
}
bool
WidebandCqiEesmErrorModel::CheckForPhysicalError (std::vector<int> channels, std::vector<int> mcs, std::vector<double> sinr)
{

  bool error = false;

  //compute the sinr vector associated to assigned sub channels
  std::vector<double> new_sinr;
  for (int i = 0; i < channels.size (); i++)
	{
	  new_sinr.push_back (sinr.at (channels.at (i)));
	}

#ifdef  BLER_DEBUG
  std::cout << "\n--> CheckForPhysicalError \n\t\t Channels: ";
  for (int i = 0; i < channels.size (); i++)
	{
	  std::cout << channels.at (i) << " ";
	}
  std::cout << "\n\t\t MCS: ";
    for (int i = 0; i < mcs.size (); i++)
  	{
  	  std::cout << mcs.at (i) << " ";
  	}
    std::cout << "\n\t\t SINR: ";
  for (int i = 0; i < new_sinr.size (); i++)
	{
	  std::cout << new_sinr.at (i) << " ";
	}
  std::cout << "\n"<< std::endl;
#endif


  double effective_sinr = GetEesmEffectiveSinr (new_sinr);
  double randomNumber = (rand () %100 ) / 100.;
  int mcs_ = mcs.at (0);
  double bler;

  if (_channel_AWGN_)
    {
	  bler = GetBLER_AWGN (effective_sinr, mcs_);
    }
  else if (_channel_TU_)
    {
	  bler = GetBLER_TU (effective_sinr, mcs_);
    }
  else
    {
	  bler = GetBLER_AWGN (effective_sinr, mcs_);
    }

#ifdef BLER_DEBUG
	  std::cout <<"CheckForPhysicalError: , effective SINR:" << effective_sinr
			  << ", selected CQI: " << mcs_
			  << ", random " << randomNumber
			  << ", BLER: " << bler << std::endl;
#endif

  if (randomNumber < bler)
	{
	  error = true;
	  if (_TEST_BLER_) std::cout << "BLER PDF " << effective_sinr << " 1" << std::endl;
	}
  else
	{
	  if (_TEST_BLER_) std::cout << "BLER PDF " << effective_sinr << " 0" << std::endl;
	}

  return error;
}
void
DownlinkPacketScheduler::RBsAllocation ()
{
#ifdef SCHEDULER_DEBUG
	std::cout << " ---- DownlinkPacketScheduler::RBsAllocation";
#endif


  FlowsToSchedule* flows = GetFlowsToSchedule ();
  int nbOfRBs = GetMacEntity ()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetDlSubChannels ().size ();

  //create a matrix of flow metrics
  double metrics[nbOfRBs][flows->size ()];
  for (int i = 0; i < nbOfRBs; i++)
    {
	  for (int j = 0; j < flows->size (); j++)
	    {
		  metrics[i][j] = ComputeSchedulingMetric (flows->at (j)->GetBearer (),
				                                   flows->at (j)->GetSpectralEfficiency ().at (i),
	    		                                   i);
	    }
    }

#ifdef SCHEDULER_DEBUG
  std::cout << ", available RBs " << nbOfRBs << ", flows " << flows->size () << std::endl;
  for (int ii = 0; ii < flows->size (); ii++)
    {
	  std::cout << "\t metrics for flow "
			  << flows->at (ii)->GetBearer ()->GetApplication ()->GetApplicationID () << ":";
	  for (int jj = 0; jj < nbOfRBs; jj++)
	    {
		  std::cout << " " << metrics[jj][ii];
	    }
	  std::cout << std::endl;
    }
#endif


  AMCModule *amc = GetMacEntity ()->GetAmcModule ();
  double l_dAllocatedRBCounter = 0;

  int l_iNumberOfUsers = ((ENodeB*)this->GetMacEntity()->GetDevice())->GetNbOfUserEquipmentRecords();

  bool * l_bFlowScheduled = new bool[flows->size ()];
  int l_iScheduledFlows = 0;
  std::vector<double> * l_bFlowScheduledSINR = new std::vector<double>[flows->size ()];
  for (int k = 0; k < flows->size (); k++)
      l_bFlowScheduled[k] = false;

  //RBs allocation
  for (int s = 0; s < nbOfRBs; s++)
    {
      if (l_iScheduledFlows == flows->size ())
          break;

      double targetMetric = 0;
      bool RBIsAllocated = false;
      FlowToSchedule* scheduledFlow;
      int l_iScheduledFlowIndex = 0;

      for (int k = 0; k < flows->size (); k++)
        {
          if (metrics[s][k] > targetMetric && !l_bFlowScheduled[k]  && flows->at (k)->GetDataToTransmit() >0 )
            {
              targetMetric = metrics[s][k];
              RBIsAllocated = true;
              scheduledFlow = flows->at (k);
              l_iScheduledFlowIndex = k;
            }
        }

      if (RBIsAllocated)
        {
          l_dAllocatedRBCounter++;

          scheduledFlow->GetListOfAllocatedRBs()->push_back (s); // the s RB has been allocated to that flow!

#ifdef SCHEDULER_DEBUG
          std::cout << "\t *** RB " << s << " assigned to the "
                  " flow " << scheduledFlow->GetBearer ()->GetApplication ()->GetApplicationID ()
                  << std::endl;
#endif
          double sinr = amc->GetSinrFromCQI (scheduledFlow->GetCqiFeedbacks ().at (s));
          l_bFlowScheduledSINR[l_iScheduledFlowIndex].push_back(sinr);

          double effectiveSinr = GetEesmEffectiveSinr (l_bFlowScheduledSINR[l_iScheduledFlowIndex]);
          int mcs = amc->GetMCSFromCQI (amc->GetCQIFromSinr (effectiveSinr));
          int transportBlockSize = amc->GetTBSizeFromMCS (mcs, scheduledFlow->GetListOfAllocatedRBs ()->size ());
          if (transportBlockSize >= scheduledFlow->GetDataToTransmit() * 8)
          {
              l_bFlowScheduled[l_iScheduledFlowIndex] = true;
              l_iScheduledFlows++;
          }

        }
    }

  delete [] l_bFlowScheduled;
  delete [] l_bFlowScheduledSINR;


  //Finalize the allocation
  PdcchMapIdealControlMessage *pdcchMsg = new PdcchMapIdealControlMessage ();

  for (FlowsToSchedule::iterator it = flows->begin (); it != flows->end (); it++)
    {
      FlowToSchedule *flow = (*it);
      if (flow->GetListOfAllocatedRBs ()->size () > 0)
        {
          //this flow has been scheduled
          std::vector<double> estimatedSinrValues;
          for (int rb = 0; rb < flow->GetListOfAllocatedRBs ()->size (); rb++ )

            {
              double sinr = amc->GetSinrFromCQI (
                      flow->GetCqiFeedbacks ().at (flow->GetListOfAllocatedRBs ()->at (rb)));

              estimatedSinrValues.push_back (sinr);
            }

          //compute the effective sinr
          double effectiveSinr = GetEesmEffectiveSinr (estimatedSinrValues);

          //get the MCS for transmission

          int mcs = amc->GetMCSFromCQI (amc->GetCQIFromSinr (effectiveSinr));

          //define the amount of bytes to transmit
          //int transportBlockSize = amc->GetTBSizeFromMCS (mcs);
          int transportBlockSize = amc->GetTBSizeFromMCS (mcs, flow->GetListOfAllocatedRBs ()->size ());
          double bitsToTransmit = transportBlockSize;
          flow->UpdateAllocatedBits (bitsToTransmit);

#ifdef SCHEDULER_DEBUG
		  std::cout << "\t\t --> flow "	<< flow->GetBearer ()->GetApplication ()->GetApplicationID ()
				  << " has been scheduled: " <<
				  "\n\t\t\t nb of RBs " << flow->GetListOfAllocatedRBs ()->size () <<
				  "\n\t\t\t effectiveSinr " << effectiveSinr <<
				  "\n\t\t\t tbs " << transportBlockSize <<
				  "\n\t\t\t bitsToTransmit " << bitsToTransmit
				  << std::endl;
#endif

		  //create PDCCH messages
		  for (int rb = 0; rb < flow->GetListOfAllocatedRBs ()->size (); rb++ )
		    {
			  pdcchMsg->AddNewRecord (PdcchMapIdealControlMessage::DOWNLINK,
					  flow->GetListOfAllocatedRBs ()->at (rb),
									  flow->GetBearer ()->GetDestination (),
									  mcs);
		    }
	    }
    }

  if (pdcchMsg->GetMessage()->size () > 0)
    {
      GetMacEntity ()->GetDevice ()->GetPhy ()->SendIdealControlMessage (pdcchMsg);
    }
  delete pdcchMsg;
}
void
EnhancedUplinkPacketScheduler::RBsAllocation ()
{
	/* This is an implementation of an algorithm based on  first maximum expansion algorithm reported in
	 * L. Temiño, G. Berardinelli, S. Frattasi,  and P.E. Mogensen,
	 * "Channel-aware scheduling algorithms for SC-FDMA in LTE uplink",  in Proc. PIMRC 2008
	 * The main difference is that here we have a given number of RB's to allocate to the UE
	 * based on its pending queue status whereas the original attempts to allocate till another
	 * UE has a better channel response
	 */
#ifdef SCHEDULER_DEBUG
	std::cout << " ---- UL RBs Allocation";
#endif

	UsersToSchedule *users = GetUsersToSchedule ();
	UserToSchedule* scheduledUser;
	int nbOfRBs = GetMacEntity ()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

	int availableRBs;     // No of RB's not allocated
	int unallocatedUsers; // No of users who remain unallocated
	int selectedUser;     // user to be selected for allocation
	int selectedPRB;      // PRB to be selected for allocation
	double bestMetric;    // best metric to identify user/RB combination
	int left, right;      // index of left and left PRB's to check
	bool Allocated[nbOfRBs];
	bool allocationMade;
	double metrics[nbOfRBs][users->size ()];
	int requiredPRBs[users->size ()];


	//Some initialization
	availableRBs = nbOfRBs;
	unallocatedUsers = users->size ();
	for(int i=0; i < nbOfRBs; i++)
		Allocated[i] = false;

	//create a matrix of flow metrics
	for (int i = 0; i < nbOfRBs; i++)
	{
		for (int j = 0; j < users->size (); j++)
		{
			metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
		}
	}

	//create number of required PRB's per scheduled users
	for(int j=0; j < users->size(); j++)
	{
		scheduledUser = users->at(j);
#ifdef SCHEDULER_DEBUG
		cout << "\n" << "User "  << j; // << "CQI Vector";
#endif

		std::vector<double> sinrs;
		for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
				c != scheduledUser->m_channelContition.end (); c++)
		{
			//cout << *c <<" ";
			sinrs.push_back (GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (*c));
		}


		double effectiveSinr =  GetEesmEffectiveSinr (sinrs);

		int mcs = GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
			  GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
		scheduledUser->m_selectedMCS = mcs;
		requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
				  (GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
#ifdef SCHEDULER_DEBUG
		cout << " EffSINR = " << effectiveSinr << "  MCS = " << mcs << "\n";
#endif
	}

#ifdef SCHEDULER_DEBUG
  //std::cout << ", available RBs " << nbOfRBs << ", users " << users->size () << std::endl;
  for (int ii = 0; ii < users->size (); ii++)
    {
	  std::cout << "Metrics for user "
			  << users->at (ii)->m_userToSchedule->GetIDNetworkNode () << "\n";
	  for (int jj = 0; jj < nbOfRBs; jj++)
	    {
		  //std::cout  << setw(3) << metrics[jj][ii]/1000 << " ";
		  printf("%3d  ", (int) (metrics[jj][ii]/1000.0));
	    }
	  std::cout << std::endl;
    }
#endif

  //RBs allocation

  while(availableRBs > 0 && unallocatedUsers > 0) //
  {
	  // First step: find the best user-RB combo
	  selectedPRB = -1;
	  selectedUser = -1;
	  bestMetric = (double) (-(1<<30));

	  for(int i=0; i < nbOfRBs; i++)
	  {
		  if (!Allocated[i]){ // check only unallocated PRB's
			  for(int j=0; j < users->size (); j++)
			  {
				  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
						  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
					  if (bestMetric < metrics[i][j]){
						  selectedPRB = i;
						  selectedUser = j;
						  bestMetric = metrics[i][j];
					  }
			  }

		  }
	  }
	  // Now start allocating for the selected user at the selected PRB the required blocks
	  // using how many PRB's are needed for the user
	  if (selectedUser != -1)
	  {
		  scheduledUser = users->at(selectedUser);
		  scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
		  Allocated[selectedPRB] = true;
		  left =  selectedPRB - 1;
		  right = selectedPRB + 1;
		  availableRBs--;
		  unallocatedUsers--;

		  allocationMade = true;
		  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
		  { // search right and left of initial allocation
			  allocationMade = false;
			  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
				  break; // nothing is available, since we need to have contiguous allocation

			  if (    (right < nbOfRBs) && (! Allocated[right]) &&
					  (
							  ((left >=0) &&
							  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
							  || (left < 0) || Allocated[left]// OR no more left
					  )
				)
			  {
				  //Allocate PRB at right to the user
				  Allocated[right] = true;
				  scheduledUser->m_listOfAllocatedRBs.push_back (right);
				  right++;
				  allocationMade = true;
				  availableRBs--;
			  } else if ( (left >=0) && (! Allocated[left]) &&
						  (
							  ((right < nbOfRBs) &&
							  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
							  || (right >= nbOfRBs) || Allocated[right]// OR no more right
						   )
						)
			  {
				  //Allocate PRB at left to the user
				  Allocated[left] = true;
				  scheduledUser->m_listOfAllocatedRBs.push_back (left);
				  left--;
				  allocationMade = true;
				  availableRBs--;
			  }
		  } // end of for
		  if (allocationMade){
			  scheduledUser->m_transmittedData = GetMacEntity ()->GetAmcModule ()->
					  GetTBSizeFromMCS (scheduledUser->m_selectedMCS, scheduledUser->m_listOfAllocatedRBs.size()) / 8;
#ifdef SCHEDULER_DEBUG
			  printf("Scheduled User = %d mcs = %d Required RB's = %d Allocated RB's= %d\n",
		 				  scheduledUser->m_userToSchedule->GetIDNetworkNode(),
		 				  scheduledUser->m_selectedMCS,
		 				  requiredPRBs[selectedUser], scheduledUser->m_listOfAllocatedRBs.size() );
			  for(int i=0; i<scheduledUser->m_listOfAllocatedRBs.size(); i++)
				  printf("%d ", scheduledUser->m_listOfAllocatedRBs.at(i));
			  printf("\n------------------\n");
#endif
		  }
	  } else { // nothing to do exit the allocation loop
		  break;
	  }
  } //while

}
bool
PowerBasedHoManager::CheckHandoverNeed (UserEquipment* ue)
{
	/*//test RX cqi success?
	  std::cout<<"PBHM: UE "<<ue->GetIDNetworkNode();
		ENodeB *testenb=nm->GetENodeBByID(ue->GetTargetNode()->GetIDNetworkNode());
		std::vector<int> testtemp=testenb->GetUserEquipmentRecord(ue->GetIDNetworkNode())->GetCQI();
		int testj=0;
		for(std::vector<int>::iterator testit=testtemp.begin();testit!=testtemp.end();testit++,testj++){
			std::cout<<"cqi="<<testtemp.at(testj)<<std::endl;
		}*/
	return false;
	//std::cout<<"power based ho"<<std::endl;//test
	/*
  NetworkNode *targetNode = ue->GetTargetNode ();

  double TXpower = 10 * log10 (
		  pow (10., (targetNode->GetPhy()->GetTxPower() - 30)/10)
		  /
		  targetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
  double pathLoss = ComputePathLossForInterference(targetNode, ue);

  double targetRXpower = TXpower - pathLoss;
  double RXpower;


  std::vector<ENodeB*> *listOfNodes = NetworkManager::Init ()->GetENodeBContainer ();
  std::vector<ENodeB*>::iterator it;
  for (it = listOfNodes->begin (); it != listOfNodes->end (); it++)
    {
	  if ((*it)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it);

	      TXpower = 10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  std::vector<HeNodeB*> *listOfNodes2 = NetworkManager::Init ()->GetHomeENodeBContainer();
  std::vector<HeNodeB*>::iterator it2;
  for (it2 = listOfNodes2->begin (); it2 != listOfNodes2->end (); it2++)
    {
	  if ((*it2)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it2);

	      TXpower =   10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );

	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  if (ue->GetTargetNode ()->GetIDNetworkNode () != targetNode->GetIDNetworkNode ())
    {
	  m_target = targetNode;
	  return true;
    }
  else
    {
	  return false;
    }*/
	//mouan
	//NetworkNode *targetNode = ue->GetTargetNode ();
	NetworkNode *targetNode;

	//if(targetNode->GetNodeType()==NetworkNode::TYPE_ENODEB){
	std::cout<<"enb vs ue"<<std::endl;//test
	ENodeB *targetenb;
		int compare[2];
		int selected_bus_id=0;
		{
			std::vector<ENodeB *> *enbs=nm->GetENodeBContainer();
			double mindis=9999999.0;
			for(std::vector<ENodeB *>::iterator ie=enbs->begin();ie!=enbs->end();ie++){
				CartesianCoordinates *dis=(*ie)->GetCell()->GetCellCenterPosition();
				double temp=dis->GetDistance(ue->GetMobilityModel()->GetAbsolutePosition());
				if(mindis>temp){
					mindis=temp;
					targetenb=(*ie);
				}
			}
			if(targetenb==NULL){
				std::cout<<"ERROR! targetenb==NULL"<<std::endl;
			}
			else{
				targetNode=nm->GetNetworkNodeByID(targetenb->GetIDNetworkNode());
			}
		//ENodeB *targetenb=nm->GetENodeBByID(targetNode->GetIDNetworkNode());
		//std::vector<int> uecqi=targetenb->GetUserEquipmentRecord(ue->GetIDNetworkNode())->GetCQI();
			std::vector<double> mouan_bstoueSinr;
			  std::vector<double> rxSignalValues;
			  std::vector<double>::iterator it;

			  rxSignalValues = ue->GetPhy()->GetTxSignal()->Getvalues();

			  //compute noise + interference
			  double interference;
			  if (ue->GetPhy()->GetInterference () != NULL)
				{
					ENodeB *node;
					interference = 0;

					std::vector<ENodeB*> *eNBs = NetworkManager::Init ()->GetENodeBContainer ();
					std::vector<ENodeB*>::iterator it;

					//std::cout << "Compute interference for UE " << ue->GetIDNetworkNode () << " ,target node " << ue->GetTargetNode ()->GetIDNetworkNode ()<< std::endl;

					for (it = eNBs->begin (); it != eNBs->end (); it++)
					{
					  node = (*it);
					  if (node->GetIDNetworkNode () != targetenb->GetIDNetworkNode () &&
						  node->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw () ==
						  ue->GetTargetNode ()->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw ())
						{
						  double powerTXForSubBandwidth = 10 * log10 (
								  pow (10., (node->GetPhy()->GetTxPower() - 30)/10)
								  /
								  node->GetPhy()->GetBandwidthManager ()->GetUlSubChannels().size ());


						  double nodeInterference_db = powerTXForSubBandwidth - 10 - ComputePathLossForInterference (node, ue); // in dB
						  double nodeInterference = pow(10, nodeInterference_db/10);

						  interference += nodeInterference;

						  /*
						  std::cout << "\t add interference from eNB " << node->GetIDNetworkNode ()
								  << " " << powerTXForSubBandwidth << " "  << ComputePathLossForInterference (node, ue)
								  << " " << nodeInterference_db << " " << nodeInterference
								  << " --> tot: " << interference
								  << std::endl;
						  */
						}
					}
				}
			  else
				{
				  interference = 0;
				}

			  double noise_interference = 10. * log10 (pow(10., -148.95/10) + interference); // dB


			  for (it = rxSignalValues.begin(); it != rxSignalValues.end(); it++)
				{
				  double power; // power transmission for the current sub channel [dB]
				  if ((*it) != 0.)
					{
					  power = (*it);
					}
				  else
					{
					  power = 0.;
					}
				  mouan_bstoueSinr.push_back (power - noise_interference);
				}
			  AMCModule *amc = ue->GetProtocolStack ()->GetMacEntity ()->GetAmcModule ();
			  std::vector<int> uecqi = amc->CreateCqiFeedbacks (mouan_bstoueSinr);
			  
		/*std::vector<double> spectralEfficiency;
		//std::vector<int> cqiFeedbacks = ueRecord->GetCQI ();
		int numberOfCqi = uecqi.size ();
		for (int i = 0; i < numberOfCqi; i++)
		{
		  double sEff = GetMacEntity ()->GetAmcModule ()->GetEfficiencyFromCQI (uecqi.at (i));
		  spectralEfficiency.push_back (sEff);//i didn't do * 180000.0,because just for compare
		}*/

		//copy start (from enhance-uplink-scheduler.cpp)

		UplinkPacketScheduler *ulps=targetenb->GetULScheduler();

		UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
		UplinkPacketScheduler::UserToSchedule* scheduledUser;
		int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

		int availableRBs;     // No of RB's not allocated
		int unallocatedUsers; // No of users who remain unallocated
		int selectedUser;     // user to be selected for allocation
		int selectedPRB;      // PRB to be selected for allocation
		double bestMetric;    // best metric to identify user/RB combination
		int left, right;      // index of left and left PRB's to check
		if(nbOfRBs>1000||users->size()>1000){
			std::cout<<"ERROR! some value wrong."<<std::endl;
			return false;
		}
		bool Allocated[nbOfRBs];
		bool allocationMade;
		double metrics[nbOfRBs][users->size ()];
		int requiredPRBs[users->size ()];
		//std::vector<int> m_mouan;
		int m_mouan[users->size()];
		int ueat=-1;

		//test
		int tt=0;
		for(UplinkPacketScheduler::UsersToSchedule::iterator test=users->begin();test!=users->end();test++){
			tt++;
		}
		std::cout<<"3:"<<users->size()<<"="<<tt<<std::endl;//test

		for(int i=0 ; i < users->size() ; i++){
			std::cout<<"A ";//test
			m_mouan[i]=0;
		}
std::cout<<"3end"<<std::endl;//test

std::cout<<"4"<<std::endl;//test

		//Some initialization
		availableRBs = nbOfRBs;
		unallocatedUsers = users->size ();
		for(int i=0; i < nbOfRBs; i++)
			Allocated[i] = false;

		//create a matrix of flow metrics
		for (int i = 0; i < nbOfRBs; i++)
		{
			for (int j = 0; j < users->size (); j++)
			{
				//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
				double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (uecqi.at(i));
				metrics[i][j] = spectralEfficiency * 180000;
			}
		}
std::cout<<"5"<<std::endl;//test
		//create number of required PRB's per scheduled users
		for(int j=0; j < users->size(); j++)
		{
			std::cout<<"1 "<<std::endl;//test
			scheduledUser = users->at(j);
std::cout<<"2 "<<std::endl;//test
			std::vector<double> sinrs;
			for(int c=0;c<scheduledUser->m_channelContition.size();c++)
			//for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
			//		c != scheduledUser->m_channelContition.end (); c++)
			{
				//cout << *c <<" ";
				std::cout<<"a="<<c<<"="<<scheduledUser->m_channelContition.at(c)<<std::endl;//test
				std::cout<<"size="<<scheduledUser->m_channelContition.size()<<std::endl;//test
				std::cout<<"id="<<scheduledUser->m_userToSchedule->GetIDNetworkNode()<<std::endl;//test

				//if(scheduledUser->m_channelContition.at(c)>14)scheduledUser->m_channelContition.at(c)=14;
				//else if(scheduledUser->m_channelContition.at(c)<0)scheduledUser->m_channelContition.at(c)=0;
				if(scheduledUser->m_channelContition.at(c)>14||scheduledUser->m_channelContition.at(c)<0){
					return false;
				}

				sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (scheduledUser->m_channelContition.at(c)));
				
				std::cout<<"b "<<std::endl;//test
			}
std::cout<<"3 "<<std::endl;//test

			double effectiveSinr =  GetEesmEffectiveSinr (sinrs);
std::cout<<"4 "<<std::endl;//test
			int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
				  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
			//scheduledUser->m_selectedMCS = mcs;
std::cout<<"5 "<<std::endl;//test
			requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
					  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
			std::cout<<"6end"<<std::endl;//test
		}
std::cout<<"6"<<std::endl;//test
		  //RBs allocation

		  while(availableRBs > 0 && unallocatedUsers > 0) //
		  {
			  // First step: find the best user-RB combo
			  selectedPRB = -1;
			  selectedUser = -1;
			  bestMetric = (double) (-(1<<30));

			  for(int i=0; i < nbOfRBs; i++)
			  {
				  if (!Allocated[i]){ // check only unallocated PRB's
					  for(int j=0; j < users->size (); j++)
					  {
						  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
								  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
							  if (bestMetric < metrics[i][j]){
								  selectedPRB = i;
								  selectedUser = j;
								  bestMetric = metrics[i][j];
							  }
					  }

				  }
			  }
			  // Now start allocating for the selected user at the selected PRB the required blocks
			  // using how many PRB's are needed for the user
			  if (selectedUser != -1)
			  {
				  scheduledUser = users->at(selectedUser);
				  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
				  m_mouan[selectedUser]++;
				  Allocated[selectedPRB] = true;
				  left =  selectedPRB - 1;
				  right = selectedPRB + 1;
				  availableRBs--;
				  unallocatedUsers--;

				  allocationMade = true;
				  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
				  { // search right and left of initial allocation
					  allocationMade = false;
					  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
						  break; // nothing is available, since we need to have contiguous allocation

					  if (    (right < nbOfRBs) && (! Allocated[right]) &&
							  (
									  ((left >=0) &&
									  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
									  || (left < 0) || Allocated[left]// OR no more left
							  )
						)
					  {
						  //Allocate PRB at right to the user
						  Allocated[right] = true;
						  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
						  m_mouan[selectedUser]++;
						  right++;
						  allocationMade = true;
						  availableRBs--;
					  } else if ( (left >=0) && (! Allocated[left]) &&
								  (
									  ((right < nbOfRBs) &&
									  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
									  || (right >= nbOfRBs) || Allocated[right]// OR no more right
								   )
								)
					  {
						  //Allocate PRB at left to the user
						  Allocated[left] = true;
						  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
						  m_mouan[selectedUser]++;
						  left--;
						  allocationMade = true;
						  availableRBs--;
					  }
				  } // end of for
				  
				  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==ue->GetIDNetworkNode()){
					ueat=selectedUser;
					printf("selected user %d is ueat\n",ueat);//test
				  }
			  } else { // nothing to do exit the allocation loop
				  break;
			  }
		  } //while
std::cout<<"7"<<std::endl;//test
			//copy end
if(ueat==-1)return false;//temp
			compare[1]=m_mouan[ueat];//m_mouan[ueat];//bs vs ue result
		  }
			std::cout<<"enb vs ue end"<<std::endl;//test

			//bus route
		  
		  std::vector<Bus *> *buses=nm->GetBusContainer();
		  std::vector<Bus *>::iterator select_bus;

		  for(select_bus=buses->begin();select_bus != buses->end();select_bus++)
		  {

			  Bus *selectedbus=(*select_bus);

			  std::vector<double> mouan_bustoueSinr;
			  std::vector<double> rxSignalValues;
			  std::vector<double>::iterator it;

			  rxSignalValues = ue->GetPhy()->GetTxSignal()->Getvalues();

			  //compute noise + interference
			  double interference;
			  if (ue->GetPhy()->GetInterference () != NULL)
				{
					ENodeB *node;
					interference = 0;

					std::vector<ENodeB*> *eNBs = NetworkManager::Init ()->GetENodeBContainer ();
					std::vector<ENodeB*>::iterator it;

					//std::cout << "Compute interference for UE " << ue->GetIDNetworkNode () << " ,target node " << ue->GetTargetNode ()->GetIDNetworkNode ()<< std::endl;

					for (it = eNBs->begin (); it != eNBs->end (); it++)
					{
					  node = (*it);
					  if (//node->GetIDNetworkNode () != ue->GetTargetNode ()->GetIDNetworkNode () &&
						  node->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw () ==
						  ue->GetTargetNode ()->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw ())
						{
						  double powerTXForSubBandwidth = 10 * log10 (
								  pow (10., (node->GetPhy()->GetTxPower() - 30)/10)
								  /
								  node->GetPhy()->GetBandwidthManager ()->GetUlSubChannels().size ());


						  double nodeInterference_db = powerTXForSubBandwidth - 10 - ComputePathLossForInterference (node, ue); // in dB
						  double nodeInterference = pow(10, nodeInterference_db/10);

						  interference += nodeInterference;

						  /*
						  std::cout << "\t add interference from eNB " << node->GetIDNetworkNode ()
								  << " " << powerTXForSubBandwidth << " "  << ComputePathLossForInterference (node, ue)
								  << " " << nodeInterference_db << " " << nodeInterference
								  << " --> tot: " << interference
								  << std::endl;
						  */
						}
					}
				}
			  else
				{
				  interference = 0;
				}

			  double noise_interference = 10. * log10 (pow(10., -148.95/10) + interference); // dB


			  for (it = rxSignalValues.begin(); it != rxSignalValues.end(); it++)
				{
				  double power; // power transmission for the current sub channel [dB]
				  if ((*it) != 0.)
					{
					  power = (*it);
					}
				  else
					{
					  power = 0.;
					}
				  mouan_bustoueSinr.push_back (power - noise_interference);
				}
			  AMCModule *amc = ue->GetProtocolStack ()->GetMacEntity ()->GetAmcModule ();
			  std::vector<int> mouan_bustouecqi = amc->CreateCqiFeedbacks (mouan_bustoueSinr);

			  //run the bus scheduler

			    UplinkPacketScheduler *ulps=selectedbus->GetULScheduler();

				UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
				UplinkPacketScheduler::UserToSchedule* scheduledUser;
				int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

				int availableRBs;     // No of RB's not allocated
				int unallocatedUsers; // No of users who remain unallocated
				int selectedUser;     // user to be selected for allocation
				int selectedPRB;      // PRB to be selected for allocation
				double bestMetric;    // best metric to identify user/RB combination
				int left, right;      // index of left and left PRB's to check
				bool Allocated[nbOfRBs];
				bool allocationMade;
				double metrics[nbOfRBs][users->size ()];
				int requiredPRBs[users->size ()];
				//std::vector<int> m_mouan;
				int m_mouan[users->size()];
				int ueat;
				for(int i=0;i<users->size();i++)m_mouan[i]=0;


				//Some initialization
				availableRBs = nbOfRBs;
				unallocatedUsers = users->size ();
				for(int i=0; i < nbOfRBs; i++)
					Allocated[i] = false;

				//create a matrix of flow metrics
				for (int i = 0; i < nbOfRBs; i++)
				{
					for (int j = 0; j < users->size (); j++)
					{
						//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
						double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (mouan_bustouecqi.at(i));
						metrics[i][j] = spectralEfficiency * 180000;
					}
				}

				//create number of required PRB's per scheduled users
				for(int j=0; j < users->size(); j++)
				{
					scheduledUser = users->at(j);

					std::vector<double> sinrs;
					for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
							c != scheduledUser->m_channelContition.end (); c++)
					{
						//cout << *c <<" ";
						sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (*c));
					}


					double effectiveSinr =  GetEesmEffectiveSinr (sinrs);

					int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
						  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
					//scheduledUser->m_selectedMCS = mcs;
					requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
							  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
				}

				  //RBs allocation

				  while(availableRBs > 0 && unallocatedUsers > 0) //
				  {
					  // First step: find the best user-RB combo
					  selectedPRB = -1;
					  selectedUser = -1;
					  bestMetric = (double) (-(1<<30));

					  for(int i=0; i < nbOfRBs; i++)
					  {
						  if (!Allocated[i]){ // check only unallocated PRB's
							  for(int j=0; j < users->size (); j++)
							  {
								  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
										  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
									  if (bestMetric < metrics[i][j]){
										  selectedPRB = i;
										  selectedUser = j;
										  bestMetric = metrics[i][j];
									  }
							  }

						  }
					  }
					  // Now start allocating for the selected user at the selected PRB the required blocks
					  // using how many PRB's are needed for the user
					  if (selectedUser != -1)
					  {
						  scheduledUser = users->at(selectedUser);
						  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
						  m_mouan[selectedUser]++;
						  Allocated[selectedPRB] = true;
						  left =  selectedPRB - 1;
						  right = selectedPRB + 1;
						  availableRBs--;
						  unallocatedUsers--;

						  allocationMade = true;
						  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
						  { // search right and left of initial allocation
							  allocationMade = false;
							  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
								  break; // nothing is available, since we need to have contiguous allocation

							  if (    (right < nbOfRBs) && (! Allocated[right]) &&
									  (
											  ((left >=0) &&
											  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
											  || (left < 0) || Allocated[left]// OR no more left
									  )
								)
							  {
								  //Allocate PRB at right to the user
								  Allocated[right] = true;
								  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
								  m_mouan[selectedUser]++;
								  right++;
								  allocationMade = true;
								  availableRBs--;
							  } else if ( (left >=0) && (! Allocated[left]) &&
										  (
											  ((right < nbOfRBs) &&
											  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
											  || (right >= nbOfRBs) || Allocated[right]// OR no more right
										   )
										)
							  {
								  //Allocate PRB at left to the user
								  Allocated[left] = true;
								  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
								  m_mouan[selectedUser]++;
								  left--;
								  allocationMade = true;
								  availableRBs--;
							  }
						  } // end of for
						  
						  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==ue->GetIDNetworkNode()){
							ueat=selectedUser;
							printf("selected user %d is ueat\n",ueat);//test
						  }
					  } else { // nothing to do exit the allocation loop
						  break;
					  }
				  }//end while
				  if(m_mouan[ueat]>compare[0]){
					compare[0]=m_mouan[ueat];//bus vs ue
					selected_bus_id=selectedbus->GetIDNetworkNode();
				  }
		  }//end for
std::cout<<"bus vs ue end"<<std::endl;//test
		  //bus vs bs

		  {
			//ENodeB *targetenb=nm->GetENodeBByID(targetNode->GetIDNetworkNode());
			std::vector<int> buscqi=targetenb->GetUserEquipmentRecord(selected_bus_id)->GetCQI();
			/*std::vector<double> spectralEfficiency;
			//std::vector<int> cqiFeedbacks = ueRecord->GetCQI ();
			int numberOfCqi = uecqi.size ();
			for (int i = 0; i < numberOfCqi; i++)
			{
			  double sEff = GetMacEntity ()->GetAmcModule ()->GetEfficiencyFromCQI (uecqi.at (i));
			  spectralEfficiency.push_back (sEff);//i didn't do * 180000.0,because just for compare
			}*/

			//copy start (from enhance-uplink-scheduler.cpp)
			UplinkPacketScheduler *ulps=targetenb->GetULScheduler();

			UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
			UplinkPacketScheduler::UserToSchedule* scheduledUser;
			int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

			int availableRBs;     // No of RB's not allocated
			int unallocatedUsers; // No of users who remain unallocated
			int selectedUser;     // user to be selected for allocation
			int selectedPRB;      // PRB to be selected for allocation
			double bestMetric;    // best metric to identify user/RB combination
			int left, right;      // index of left and left PRB's to check
			bool Allocated[nbOfRBs];
			bool allocationMade;
			double metrics[nbOfRBs][users->size ()];
			int requiredPRBs[users->size ()];
			//std::vector<int> m_mouan;
			int m_mouan[users->size()];
			int busat;
			for(int i=0;i<users->size();i++)m_mouan[i]=0;


			//Some initialization
			availableRBs = nbOfRBs;
			unallocatedUsers = users->size ();
			for(int i=0; i < nbOfRBs; i++)
				Allocated[i] = false;

			//create a matrix of flow metrics
			for (int i = 0; i < nbOfRBs; i++)
			{
				for (int j = 0; j < users->size (); j++)
				{
					//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
					double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (buscqi.at(i));
					metrics[i][j] = spectralEfficiency * 180000;
				}
			}

			//create number of required PRB's per scheduled users
			for(int j=0; j < users->size(); j++)
			{
				scheduledUser = users->at(j);

				std::vector<double> sinrs;
				for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
						c != scheduledUser->m_channelContition.end (); c++)
				{
					//cout << *c <<" ";
					sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (*c));
				}


				double effectiveSinr =  GetEesmEffectiveSinr (sinrs);

				int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
					  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
				//scheduledUser->m_selectedMCS = mcs;
				requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
						  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
			}

			  //RBs allocation

			  while(availableRBs > 0 && unallocatedUsers > 0) //
			  {
				  // First step: find the best user-RB combo
				  selectedPRB = -1;
				  selectedUser = -1;
				  bestMetric = (double) (-(1<<30));

				  for(int i=0; i < nbOfRBs; i++)
				  {
					  if (!Allocated[i]){ // check only unallocated PRB's
						  for(int j=0; j < users->size (); j++)
						  {
							  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
									  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
								  if (bestMetric < metrics[i][j]){
									  selectedPRB = i;
									  selectedUser = j;
									  bestMetric = metrics[i][j];
								  }
						  }

					  }
				  }
				  // Now start allocating for the selected user at the selected PRB the required blocks
				  // using how many PRB's are needed for the user
				  if (selectedUser != -1)
				  {
					  scheduledUser = users->at(selectedUser);
					  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
					  m_mouan[selectedUser]++;
					  Allocated[selectedPRB] = true;
					  left =  selectedPRB - 1;
					  right = selectedPRB + 1;
					  availableRBs--;
					  unallocatedUsers--;

					  allocationMade = true;
					  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
					  { // search right and left of initial allocation
						  allocationMade = false;
						  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
							  break; // nothing is available, since we need to have contiguous allocation

						  if (    (right < nbOfRBs) && (! Allocated[right]) &&
								  (
										  ((left >=0) &&
										  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
										  || (left < 0) || Allocated[left]// OR no more left
								  )
							)
						  {
							  //Allocate PRB at right to the user
							  Allocated[right] = true;
							  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
							  m_mouan[selectedUser]++;
							  right++;
							  allocationMade = true;
							  availableRBs--;
						  } else if ( (left >=0) && (! Allocated[left]) &&
									  (
										  ((right < nbOfRBs) &&
										  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
										  || (right >= nbOfRBs) || Allocated[right]// OR no more right
									   )
									)
						  {
							  //Allocate PRB at left to the user
							  Allocated[left] = true;
							  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
							  m_mouan[selectedUser]++;
							  left--;
							  allocationMade = true;
							  availableRBs--;
						  }
					  } // end of for
					  
					  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==selected_bus_id){
						busat=selectedUser;
						printf("selected bus %d is busat\n",busat);//test
					  }
				  } else { // nothing to do exit the allocation loop
					  break;
				  }
			  } //while
				//copy end
			  if(compare[0]>m_mouan[busat]){
				  compare[0]=m_mouan[busat];
			  }
				//compare[1]=m_mouan[ueat];//m_mouan[ueat];//bs vs ue result
		  }
		  if(compare[0]>compare[1]){//using bs
			  if(ue->GetTargetNode()->GetIDNetworkNode()==targetenb->GetIDNetworkNode()){
				  return false;
			  }
			  else{
				  m_target=nm->GetNetworkNodeByID(targetenb->GetIDNetworkNode());
				  //std::cout<<"HO TRUE"<<std::endl;//test

				  NetworkNode* newTagertNode = m_target;

		#ifdef HANDOVER_DEBUG
				  std::cout << "** HO ** \t time: " << time << " user " <<  ue->GetIDNetworkNode () <<
        				  " old eNB " << targetNode->GetIDNetworkNode () <<
        				  " new eNB " << newTagertNode->GetIDNetworkNode () << std::endl;
		#endif
				  double time=0;
				  nm->HandoverProcedure(time, ue, targetNode, newTagertNode);

				  return true;
			  }
		  }
		  else{//using bus
			  if(ue->GetTargetNode()->GetIDNetworkNode()==selected_bus_id){
				  return false;
			  }
			  else{
				  m_target=nm->GetNetworkNodeByID(selected_bus_id);
				  //std::cout<<"HO TRUE"<<std::endl;//test
				  
				  NetworkNode* newTagertNode = m_target;

		#ifdef HANDOVER_DEBUG
				  std::cout << "** HO ** \t time: " << time << " user " <<  ue->GetIDNetworkNode () <<
        				  " old eNB " << targetNode->GetIDNetworkNode () <<
        				  " new eNB " << newTagertNode->GetIDNetworkNode () << std::endl;
		#endif
				  double time=0;
				  nm->HandoverProcedure(time, ue, targetNode, newTagertNode);

				  return true;
			  }
		  }
		  //std::cout<<"enb vs bus end"<<std::endl;//test
	/*}
	else{//default bus route
		;
	}

  double TXpower = 10 * log10 (
		  pow (10., (targetNode->GetPhy()->GetTxPower() - 30)/10)
		  /
		  targetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
  double pathLoss = ComputePathLossForInterference(targetNode, ue);

  double targetRXpower = TXpower - pathLoss;
  double RXpower;


  std::vector<ENodeB*> *listOfNodes = NetworkManager::Init ()->GetENodeBContainer ();
  std::vector<ENodeB*>::iterator it;
  for (it = listOfNodes->begin (); it != listOfNodes->end (); it++)
    {
	  if ((*it)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it);

	      TXpower = 10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  std::vector<HeNodeB*> *listOfNodes2 = NetworkManager::Init ()->GetHomeENodeBContainer();
  std::vector<HeNodeB*>::iterator it2;
  for (it2 = listOfNodes2->begin (); it2 != listOfNodes2->end (); it2++)
    {
	  if ((*it2)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it2);

	      TXpower =   10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );

	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  if (ue->GetTargetNode ()->GetIDNetworkNode () != targetNode->GetIDNetworkNode ())
    {
	  m_target = targetNode;
	  return true;
    }
  else
    {
	  return false;
    }*/
}