⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmsmanager.cpp

📁 这是cdma2000的一个分组调度算法实例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}

		//在对每个移动台进行处理时,还需要判断其通话时间是否完成,
		//若已经完成,则重新调用移动台初始化函数,重新初始化。
		pVoiceMs->SetVoiceActivity();

		if(pVoiceMs->GetSHOMsgNum())//判断切换事件队列是否为空			
		{//...... modified by cqm, Apr.9 ......//
			  if((pVoiceMs->SHOMsgProcess()>0)&&(m_iSlotCurrentNum%16==1))     //判断切换事件是否到时
			  {//..............................//每帧结束时才变更激活集
				 pVoiceMs->ChangeActiveSet();   //到时,变更激活集;否则直接更新激活集				 
			  }
		}
		//为空,更新激活集计算激活集内各BTS的业务信道C/I
		pVoiceMs->UpdateActiveSet();
		
		//计算激活集内各BTS的业务信道C/I
		pVoiceMs->ObtainC2I();

		
		//根据实际的C/I与目标C/I,对激活集内各
		//BTS发出功控信息(考虑PCBER的影响)
		pVoiceMs->PowerControl();

		//...... added by cqm, Apr.9 ......//
		if(m_iSlotCurrentNum%16==0)
		{    
			pVoiceMs->FERPrediction();		
		    pVoiceMs->FrameQualityDecision();	
			if(m_iSlotCurrentNum>INITIALSLOT)
			    pVoiceMs->GOSDecision();
		}

		//更新相邻集各个BTS到移动台的
		//慢衰落和快衰落值
		//更新移动台接收到的总功率值


		//根据判断结果和时延特性,创建
		//切换事件,写入切换事件队列
		pVoiceMs->SHOMsgGenerator();
		
		if(m_iSlotCurrentNum>INITIALSLOT)  //考虑初始化时间
		{
			m=pVoiceMs->GetServiceLength()-1;
			pVoiceMs->SetServiceLength(m);
		}
		//test...................
		if(m_iSlotCurrentNum==(480000+INITIALSLOT))
		{
			p=pVoiceMs->GetFERIndicator();
			if(((float(p)/(float)1500)>0.01)&&(!pVoiceMs->m_bIsSHOOut))
			{
				m_iBadNumOfVoice++;
				m_iVoiceUserOfCurrentDrop++;
			}
			else
				m_iVoiceUserOfCurrentDrop++;
		}

	}
}

//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:
//
//	AUTHOR:
//
//	AUDITOR:
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::VoiceStatistics()
//输出文件为voice.txt
{
		CStdioFile f;
	    char buf[50];
		
		//cyu于5.14修改
		//...... modified by cqm, Apr.9 ......//
//		m_fDropRatioOfVoice=float(m_iDropNumOfVoice)/float(m_iVoiceUserOfCurrentDrop);
		m_fBadRatioOfVoice=float(m_iBadNumOfVoice)/float(m_iVoiceUserOfCurrentDrop);
		//....................................//
     	  /* 打开数据文件准备写*/
    	if(!f.Open(m_sVoiceFile,
			CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
		{
	    #ifdef _DEBUG
	    	afxDump<<"Unable to open file"<<"\n";	//异常处理
	    #endif
		}
    	f.SeekToEnd();                             
		//使文件指针指向文件尾部,输出数据可以在文件尾部接着写
//		f.WriteString("话音用户掉话率\n");
//       _gcvt(m_fDropRatioOfVoice,8,buf);
//		f.WriteString(buf);
//		f.WriteString("\n");
		
		//...... modified by cqm, Apr.9 ......//
		f.WriteString("话音用户中断率(每扇区");
		_gcvt(m_iVoiceNumPerSector,8,buf);
		f.WriteString(buf);
		f.WriteString("用户):\n");
		_gcvt(m_fBadRatioOfVoice,8,buf);
		f.WriteString(buf);
		f.WriteString("\n");

		f.WriteString("话音用户中断数目:\n");
		_gcvt((float)m_iBadNumOfVoice,8,buf);
		f.WriteString(buf);
		f.WriteString("\n");
		f.WriteString("话音用户总数:\n");
		_gcvt((float)m_iVoiceUserOfCurrentDrop,8,buf);
		f.WriteString(buf);
		f.WriteString("\n");

		f.Close();
}


//孟松新增函数
//计算移动台到最近基站的距离(多个函数中用到)
float CMsManager::DistanceCaculte(LOCATION_TYPE MsLocation,
								  SECTORID_TYPE SectorID)
{
	float x1,x2,y1,y2;
	LOCATION_TYPE BsLocation;
	x1=MsLocation.x;
	y1=MsLocation.y;
	BsLocation=m_pServiceArea->GetCor(SectorID.stCellID);
	x2=BsLocation.x;
	y2=BsLocation.y;
	return (float)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:Process the data mobiles
//
//	AUTHOR:	Cheng Yu
//
//	AUDITOR:Ouyang Hui
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::DataProcess()
//循环处理数据业务移动台,根据移动台对应最佳扇区的分组数据信道功率
//计算适合的数据传输速率,并统计各个扇区对应的优先级最高者,
//做出相应标记(即把扇区对应的最佳用户进行付值)。然后,更新衰落值和最佳扇区。
{
	POSITION pos;
	CSector* pSector=NULL;

	//////////////////////////////////////////////////////////////////
	
	pos=m_FtpDataList.GetHeadPosition();
	CFtpDataMs* pFtpDataMs=NULL;
	while(pos!=NULL)				//ftp user
	{
		pFtpDataMs=m_FtpDataList.GetNext(pos);
		pFtpDataMs->FillDataQueue();

		pSector=m_pServiceArea->GetSector(pFtpDataMs
					->GetCurrentSector());
		
		//zx20010813 所有数据用户的平均速率都进行这样的递减操作,
		//只有传输了的用户才需要另外加上使其平均速率增高的部分(Rreq/Tc)


		pFtpDataMs->m_fAverageRate *= (float)((fConstTc-1.0)/fConstTc);	

		if(m_iSlotCurrentNum==1000)
		{
			#ifdef NEWMAXC2I
			pFtpDataMs->m_fAverageRate=(float)pFtpDataMs->m_lTotalGoodBitsNum/(1.25*1000);
			#endif
//			pFtpDataMs->m_lTotalGoodBitsNum=0;
		}	
		if(pFtpDataMs->IsTransmitingNow())
		{
						
			pSector->SetIsExistHighestPriority(true);//将该用户设为最高优先权指标用户

		}
		else	
		{
			pFtpDataMs->C2ICalculate();
			//在这里需要插入张定业编的时延函数
			pFtpDataMs->C2IFeedbackDelay();
			if(pFtpDataMs->m_fDelayedC2IValue==0.) continue;
			pFtpDataMs->C2IFeedback();
				//cyu于5.15修改
			if(pSector->IsExistHighestPriority()==false&&pFtpDataMs->m_lDataQueueSize>0)
			{
				pFtpDataMs->RatePrediction();
				RATE2CI_TYPE* pRatePrediction=pFtpDataMs->GetstRatePrediction();
				if((pFtpDataMs->GetCurrentPacketSize()>0)&&(pRatePrediction!=NULL))
				{
					Scheduling((CDataMs*)pFtpDataMs);//zx20010813
				}
			}
		}
	}
	
	pos=m_HttpDataList.GetHeadPosition();
	CHttpDataMs* pHttpDataMs=NULL;
	

	while(pos!=NULL)				//http user
	{
		pHttpDataMs=m_HttpDataList.GetNext(pos);

		pHttpDataMs->PacketCallProcess();

			//根据业务模型,产生新的数据包,加入数据队列
		pSector=m_pServiceArea->GetSector(pHttpDataMs
					->GetCurrentSector());//得到当前扇区指针


		//zx20010813 所有数据用户的平均速率都进行这样的递减操作,
		//只有传输了的用户才需要另外加上使其平均速率增高的部分(Rreq/Tc)
		pHttpDataMs->m_fAverageRate *= (float)((fConstTc-1.0)/fConstTc);

		if(m_iSlotCurrentNum==1000)
		{
			#ifdef NEWMAXC2I
			pHttpDataMs->m_fAverageRate=(float)pHttpDataMs->m_lTotalGoodBitsNum/(1.25*1000);
			#endif
		}	

		if(pHttpDataMs->IsTransmitingNow())
		//这里的在传输指的就是Subpacket的传输正在进行
		{						
			pSector->SetIsExistHighestPriority(true);//将该用户设为最高优先权指标用户
       	}
		else	
		{
			pHttpDataMs->C2ICalculate(); 
			//在这里需要插入张定业编的时延函数
			pHttpDataMs->C2IFeedbackDelay();
			if(pHttpDataMs->m_fDelayedC2IValue==0.) continue;
			pHttpDataMs->C2IFeedback();
			if(pSector->IsExistHighestPriority()==false&&pHttpDataMs->m_lDataQueueSize>=384)
			{
				pHttpDataMs->RatePrediction();
				RATE2CI_TYPE* pRatePrediction=pHttpDataMs->GetstRatePrediction();
				if((pHttpDataMs->GetCurrentPacketSize()>0)&&(pRatePrediction!=NULL))
				{
						Scheduling((CDataMs*)pHttpDataMs);
				}
			}		
		}
	}

}

//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:Set the best data mobile user in each sector
//
//	AUTHOR:	Cheng Yu
//
//	AUDITOR:Ouyang Hui
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::Scheduling(CDataMs* pDataMs)
{
	CSector* pSector=NULL;
	float priorityfactor;
	if (m_iSlotCurrentNum>1)
	{
		pSector=(m_pServiceArea->GetSector(pDataMs->GetCurrentSector()));
		priorityfactor=DataPriorityCalculate(pDataMs);//调用优先权指标计算函数
		
		#ifdef NEWMAXC2I 
		if(m_iSlotCurrentNum>1000)
		{
			if(pDataMs->m_fAverageRate>250.)
			{
				priorityfactor=0.;
			}
		}
		#endif

		if(priorityfactor>pSector->GetPriorityFactor())//如果大于当前优先权指标
		{
			pSector->SetPriorityFactor(priorityfactor);//重新写入优先权指标
			pSector->SetCurrentDataMs(pDataMs);//记入最佳用户指针
		}
		#ifdef NEWMAXC2I 
		if(m_iSlotCurrentNum>1000)
		{
			if(pDataMs->m_fAverageRate<15.0)
			{
				pSector->SetIsExistHighestPriority(true);
				pSector->SetCurrentDataMs(pDataMs);
			}
		}
		#endif
	}
}
//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:统计总的成功传输数据量
//
//	AUTHOR:	Cheng Yu
//
//	AUDITOR:Ouyang Hui
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::DataBitsAndPacketCumulate()
//对所有的成功传输的数据量,EP数量和错误的EP数量进行累加
{
	POSITION pos;
	pos=m_HttpDataList.GetHeadPosition();
	CHttpDataMs* pHttpDataMs=NULL;
	while(pos!=NULL)		
	{
		pHttpDataMs=m_HttpDataList.GetNext(pos);
		m_fTotalBits+=pHttpDataMs->GetTotalGoodBitsNum();
		m_lTotalErrorEP+=pHttpDataMs->GetErrorEPNum();
		m_lTotalGoodEP+=pHttpDataMs->GetSuccessfulEPNum();
//zdy新加属性累加
		m_lTotalErrorPacket+=pHttpDataMs->GetErrorPacketNum();				//总的差错Packet数
		m_lTotalGoodPacket+=pHttpDataMs->GetSuccessfulPacketNum();			//总的正确Packet数		

		m_lRealErrorSP+=pHttpDataMs->m_iRealErrorSP;
		m_lRealTotalSP+=pHttpDataMs->m_iRealTotalSP;	
		m_lDiscardedPacket+=pHttpDataMs->m_iDiscardedPacket;
		m_lErrorSPDCCH+=pHttpDataMs->m_iErrorSPDCCH;
	}
	
	pos=m_FtpDataList.GetHeadPosition();
	CFtpDataMs* pFtpDataMs=NULL;
	while(pos!=NULL)		
	{
		pFtpDataMs=m_FtpDataList.GetNext(pos);
		m_fTotalBits+=pFtpDataMs->GetTotalGoodBitsNum();
		m_lTotalErrorEP+=pFtpDataMs->GetErrorEPNum();
		m_lTotalGoodEP+=pFtpDataMs->GetSuccessfulEPNum();
//目前的ftp模型中还没有packet的概念,因此无需统计相关量
		m_lRealErrorSP+=pFtpDataMs->m_iRealErrorSP;
		m_lRealTotalSP+=pFtpDataMs->m_iRealTotalSP;
		m_lErrorSPDCCH+=pFtpDataMs->m_iErrorSPDCCH;
	}

}



//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:Calculate a data user's priority
//
//	AUTHOR:	Cheng Yu
//
//	AUDITOR:Ouyang Hui
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
float CMsManager::DataPriorityCalculate(CDataMs* pDataMs)
{
	float m=0.;

	if (pDataMs->GetCurrentPacketSize()<=0)
		m=0.;
	else
	{

		#ifdef MAXC2I
				m=pDataMs->GetFilterOutputC2I();
			#endif
		#ifdef RANDOMR
				m=xUniform();
			#endif
		#ifdef PROPFAIRNESS
				m=PropFairCalculate(pDataMs);
			#endif
		#ifdef NEWMAXC2I
				m=pDataMs->GetFilterOutputC2I();
	//			if(pDataMs->m_fAverageRate
			#endif
	}
			
	return m;
}
////cyu于5.15添加
float CMsManager::PropFairCalculate(CDataMs* pDataMs)
{
	float n=0.;
	
	RATE2CI_TYPE* pRatePrediction=pDataMs->GetstRatePrediction();
	n=pRatePrediction->fDataRate/pDataMs->m_fAverageRate;
	return n;
	
}


///////////////////////////////////////////////////////////////////////
////////////////  以下函数由孟松编写

//平均吞吐量计算输出函数
//completed by ms in 3.29

void CMsManager::MeanThroughputStatistics()	
//输出文件为meanthroughput.txt
{
	float MeanThroughput;
	char  buf[50];
	CStdioFile f;
	MeanThroughput=(float)(m_fTotalBits/SectorNumber/(m_fDropTime));//不考虑初始化时间

//	MeanThroughput=(float)(m_fTotalBits/(MM*NN*SectorNumber)/(m_fDropTime-INITIALSLOT*SlotSize/1000));//统计吞吐量时要减去初始化时间
   /* 打开数据文件准备写*/
	if(!f.Open(m_sSystemMeanThroughputFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
	{
	#ifdef _DEBUG
		afxDump<<"Unable to open file"<<"\n";	//异常处理
	#endif
	}
	f.SeekToEnd();//使文件指针指向文件尾部,输出数据可以在文件尾部接着写
	f.WriteString("平均吞吐量_每扇区的数据用户的平均吞吐量_bit/s/sector \n");
    _gcvt(MeanThroughput,8,buf); 
    f.WriteString(buf);
	f.WriteString("\n");
	f.Close();
}
			
//分组差错概率计算输出函数
//completed by ms in 3.29
void CMsManager::MeanPERStatistics()
//输出文件为meanper.txt
{  
    CStdioFile f;
	char buf[50];
	m_fMeanPER=(float)m_lTotalErrorEP/(m_lTotalErrorEP
		+m_lTotalGoodEP);
    /* 打开数据文件准备写*/
	if(!f.Open(m_sSystemMeanPERFile,
		CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
	{
	#ifdef _DEBUG
		afxDump<<"Unable to open file"<<"\n";	//异常处理
	#endif
	}
	f.SeekToEnd();                             //使文件指针指向文件尾部,输出数据可以在文件尾部接着写 
	f.WriteString("EP分组差错概率_所有数据用户的结果\n");
    _gcvt(m_fMeanPER,8,buf);                   //将浮点数转换成字符串
	f.WriteString(buf);
    f.WriteString("\n");

	float fMeanPacketER=float(m_lTotalErrorPacket)/(m_lTotalErrorPacket+m_lTotalGoodPacket);
	f.WriteString("Packet分组差错概率_所有http数据用户的结果\n");
    _gcvt(fMeanPacketER,8,buf);                   //将浮点数转换成字符串
	f.WriteString(buf);
    f.WriteString("\n");

	float fMeanRealPER=float(m_lRealErrorSP)/m_lRealTotalSP;
	f.WriteString("SP分组差错概率_所有数据用户的结果\n");
    _gcvt(fMeanRealPER,8,buf);                   //将浮点数转换成字符串
	f.WriteString(buf);
    f.WriteString("\n");

	float fMeanDiscardedRatio=float(m_lDiscardedPacket)/(m_lTotalErrorPacket+m_lTotalGoodPacket);
	f.WriteString("Packet丢弃概率_所有数据用户的结果\n");
    _gcvt(fMeanDiscardedRatio,8,buf);                   //将浮点数转换成字符串
	f.WriteString(buf);
    f.WriteString("\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -