示例#1
0
void
PacketScheduler::ClearFlowsToSchedule ()
{
  FlowsToSchedule*  records = GetFlowsToSchedule ();
  FlowsToSchedule::iterator iter;

  for (iter = records->begin(); iter != records->end (); iter++)
    {
	  delete *iter;
    }

  GetFlowsToSchedule ()->clear ();
}
void
PacketScheduler::InsertFlowToSchedule (RadioBearer* bearer, int dataToTransmit, std::vector<double> specEff, std::vector<int> cqiFeedbacks)
{
#ifdef SCHEDULER_DEBUG
	std::cout << "\t  --> selected flow: "
			<< bearer->GetApplication ()->GetApplicationID ()
			<< " " << dataToTransmit << std::endl;
#endif

  FlowToSchedule *flowToSchedule = new FlowToSchedule(bearer, dataToTransmit);
  flowToSchedule->SetSpectralEfficiency (specEff);
  flowToSchedule->SetCqiFeedbacks (cqiFeedbacks);

  GetFlowsToSchedule ()->push_back(flowToSchedule);
}
void
DownlinkPacketScheduler::DoSchedule (void)
{
#ifdef SCHEDULER_DEBUG
	std::cout << "Start DL packet scheduler for node "
			<< GetMacEntity ()->GetDevice ()->GetIDNetworkNode()<< std::endl;
#endif

  UpdateAverageTransmissionRate ();
  SelectFlowsToSchedule ();

  if (GetFlowsToSchedule ()->size() == 0)
	{}
  else
	{
	  RBsAllocation ();
	}

  StopSchedule ();
}
void
DL_my_algo_PacketScheduler2::DoStopSchedule (void)
{
#ifdef SCHEDULER_DEBUG
  std::cout << "\t Creating Packet Burst" << std::endl;
#endif

  PacketBurst* pb = new PacketBurst ();

  //Create Packet Burst
  FlowsToSchedule *flowsToSchedule = GetFlowsToSchedule ();

  for (FlowsToSchedule::iterator it = flowsToSchedule->begin (); it != flowsToSchedule->end (); it++)
    {
	  FlowToSchedule *flow = (*it);

	  int availableBytes = flow->GetAllocatedBits ()/8;

	  if (availableBytes > 0)
	    {

		  flow->GetBearer ()->UpdateTransmittedBytes (availableBytes);

#ifdef SCHEDULER_DEBUG
	      std::cout << "\t  --> add packets for flow "
	    		  << flow->GetBearer ()->GetApplication ()->GetApplicationID () << std::endl;
#endif

	      RlcEntity *rlc = flow->GetBearer ()->GetRlcEntity ();
	      PacketBurst* pb2 = rlc->TransmissionProcedure (availableBytes);

#ifdef SCHEDULER_DEBUG
	      std::cout << "\t\t  nb of packets: " << pb2->GetNPackets () << std::endl;
#endif

	      if (pb2->GetNPackets () > 0)
	        {
	    	  std::list<Packet*> packets = pb2->GetPackets ();
	    	  std::list<Packet* >::iterator it;
	    	  for (it = packets.begin (); it != packets.end (); it++)
	    	    {
#ifdef SCHEDULER_DEBUG
	    		  std::cout << "\t\t  added packet of bytes " << (*it)->GetSize () << std::endl;
	    		  //(*it)->Print ();
#endif

	    		  Packet *p = (*it);
	    		  pb->AddPacket (p->Copy ());
	    	    }
	        }
	      delete pb2;
	    }
	  else
	    {}
    }

  //UpdateAverageTransmissionRate ();

  //SEND PACKET BURST

#ifdef SCHEDULER_DEBUG
  if (pb->GetNPackets () == 0)
    std::cout << "\t Send only reference symbols" << std::endl;
#endif

  GetMacEntity ()->GetDevice ()->SendPacketBurst (pb);
}
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;
	}       
}
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;
}
double
MwRulePacketScheduler::ComputeSchedulingMetric (RadioBearer *bearer, double spectralEfficiency, int subChannel)
{
#ifdef SCHEDULER_DEBUG
	std::cout << "\t ComputeSchedulingMetric for flow "
			<< bearer->GetApplication ()->GetApplicationID () << std::endl;
#endif

  double metric;

  if ((bearer->GetApplication ()->GetApplicationType () == Application::APPLICATION_TYPE_INFINITE_BUFFER)
	  ||
	  (bearer->GetApplication ()->GetApplicationType () == Application::APPLICATION_TYPE_CBR))
	{
	  metric = (spectralEfficiency * 180000.)
				/
				bearer->GetAverageTransmissionRate();

#ifdef SCHEDULER_DEBUG
	std::cout << "\t\t non real time flow: metric = " << metric << std::endl;
#endif

	}
  else
	{
	  QoSParameters *qos = bearer->GetQoSParameters ();
	  double HOL = bearer->GetHeadOfLinePacketDelay ();
	  double targetDelay = qos->GetMaxDelay ();

#ifdef SCHEDULER_DEBUG
	  std::cout << "\t\t real time flow: HOL = " << HOL << ", target delay = " << targetDelay;
#endif

	  //compute sum of HOL and average spectral efficiency
//#ifdef SCHEDULER_DEBUG
//	  std::cout << "\n\t\t\t compute sum HOL for all real time flows"<< std::endl;
//#endif

	  double sumHOL = 0;
	  int nbFlows = 0;
	  FlowsToSchedule *flowsToSchedule = GetFlowsToSchedule ();
	  FlowsToSchedule::iterator iter;
	  FlowToSchedule *flow;

	  for (iter = flowsToSchedule->begin (); iter != flowsToSchedule->end (); iter++)
	    {
		  flow = (*iter);
		  if (!flow->GetBearer ()->HasPackets ())
		    {}
		  else
			{
			  if ((flow->GetBearer ()->GetApplication ()->GetApplicationType ()
					  != Application::APPLICATION_TYPE_INFINITE_BUFFER)
			   		  &&
			          (flow->GetBearer ()->GetApplication ()->GetApplicationType ()
			        		  != Application::APPLICATION_TYPE_CBR))
			    {
			      sumHOL += flow->GetBearer ()->GetHeadOfLinePacketDelay ();
			      nbFlows++;

//#ifdef SCHEDULER_DEBUG
//	              std::cout << "\t\t\t --> HOL for flow " << flow->GetBearer ()->GetApplication ()->GetApplicationID ()
//	            		  << " = " << flow->GetBearer ()->GetHeadOfLinePacketDelay ()<< std::endl;
//#endif
			    }
			  else
			    {
//#ifdef SCHEDULER_DEBUG
//	              std::cout << "\t\t\t --> non real time flow, go on! " << std::endl;
//#endif
			    }
			}
	    }


	  //COMPUTE METRIC USING EXP RULE:
	  double numerator = (6/targetDelay) * HOL;
	  double denominator = (1 + sqrt (sumHOL/nbFlows));
	  double weight = (spectralEfficiency * 180000.)
				      /
	    	          bearer->GetAverageTransmissionRate();

	  metric = (exp (numerator / denominator)) * weight;

#ifdef SCHEDULER_DEBUG
	  std::cout << " --> metric = " << metric << std::endl;
#endif
	}

  return metric;
}