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

📄 cmsmanager.cpp

📁 这是cdma2000的一个分组调度算法实例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////
//
//	CMsManager.cpp 移动台管理类的实现
//	建立者:程宇
//
/////////////////////////////////////////////////////////////////////////
//
//	修改记录:
//
//	2001年3月23日	欧阳晖
//		实现Initialization()函数
//
/////////////////////////////////////////////////////////////////////////

#include "CMsManager.h"
#include "CVoiceMs.h"
#include "CHttpDataMs.h"
#include "CFtpDataMs.h"
#include "sys_random.h"
#include "newran.h"
#include "CServiceArea.h"
#include "CLinkPrediction.h"
//#include "CVoiceLinkPrediction.h"//added by cqm


#include <string.h>
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:
//
//	AUTHOR:
//
//	AUDITOR:
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
CMsManager::~CMsManager()
{
	Clean();
}
void CMsManager::Clean()
{
	//clean the voice mobiles' list
	POSITION pos;
	pos=m_VoiceList.GetHeadPosition();
	while (pos!=NULL)
	{
		delete m_VoiceList.GetNext(pos);
	}
	m_VoiceList.RemoveAll();

	//clean the http data mobiles' list
	pos=m_HttpDataList.GetHeadPosition();
	while (pos!=NULL)
	{
		delete m_HttpDataList.GetNext(pos);
	}
	m_HttpDataList.RemoveAll();

	//clean the ftp data mobiles' list
	pos=m_FtpDataList.GetHeadPosition();
	while (pos!=NULL)
	{
		delete m_FtpDataList.GetNext(pos);
	}
	m_FtpDataList.RemoveAll();
}

//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:
//
//	AUTHOR:
//
//	AUDITOR:
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::Initialization(int iSlotNum,float fSlotTime,
								float fDropTime,
								CLinkPrediction* pLink)
{
	//完成类的初始化工作
	m_iVoiceNumInSys=m_iVoiceNumPerSector*SectorNumber;
	m_iDataNumInSys=m_iDataNumPerSector*SectorNumber;
	m_iHttpNum=int(m_iDataNumInSys*m_fFractionHttp);
	m_iFtpNum=int(m_iDataNumInSys*m_fFractionFtp);
	m_iSlotNum=iSlotNum;
	m_fSlotTime=fSlotTime;
	m_fDropTime=fDropTime;
	m_pLinkPrediction=pLink;
	m_fTotalBits=0.0;						//总的传输比特量		
    m_lTotalErrorEP=0;				//总的差错EP数
    m_lTotalGoodEP=0;				//总的正确EP数		
    m_fMeanThroughputPerSector=0.0;		//Drop内的平均吞吐量
    m_fMeanPER=0.0;						//Drop内的平均分组差错概率
	m_lRealErrorSP=0;
	m_lRealTotalSP=0;
	m_lDiscardedPacket=0;
	m_lErrorSPDCCH=0;
	//...... modified by cqm, Apr.9 ......//
	for(int i=0;i<SectorNumber;i++)
	{
		m_iDataNumGenerated[i]=0;
		m_iVoiceNumGenerated[i]=0;
	}
	//....................................//

	//...... added by cqm, Apr.9 ......//
	//话音FER vs Eb/N0表
	int ii;
	double fC2IIndex[26]=
	{	-21.10,	-20.85,	-20.60,	-20.35,	-20.10,	-19.85,	-19.60,	-19.35,
		-19.10,	-18.85,	-18.60,	-18.35,	-18.10,	-17.85,	-17.60,	-17.35,
		-17.10,	-16.85,	-16.60,	-16.35,	-16.10,	-15.85,	-15.60,	-15.35,
		-15.10,	-14.85
	};
	for (ii=0;ii<26;ii++)
		m_fC2IIndex[ii]=(float)fC2IIndex[ii];

	double fFER_3[26]=
	{	1,		1,		1,		1,		1,		0.90,	0.80,	0.70,
		0.60,	0.50,	0.45,	0.40,	0.35,	0.30,	0.20,	0.15,
		0.09,	0.04,	0.015,	0.007,	0.004,	0.002,	0.001,	0.0005,
		0.0003,	0.00015
	};
	for (ii=0;ii<26;ii++)
		m_fFER_3[ii]=(float)fFER_3[ii];

	double fFER_30[26]=
	{	1,		1,		1,		1,		0.95,	0.85,	0.70,	0.60,
		0.55,	0.45,	0.40,	0.30,	0.20,	0.15,	0.07,	0.04,
		0.025,	0.012,	0.004,	0.003,	0.002,	0.001,	0.0005,	0.0003,
		0.00015,0.00008
	};
	for (ii=0;ii<26;ii++)
		m_fFER_30[ii]=(float)fFER_30[ii];

	double fFER_100[26]=
	{	1,		1,		1,		0.90,	0.80,	0.75,	0.70,	0.55,
		0.50,	0.40,	0.30,	0.20,	0.15,	0.10,	0.05,	0.02,
		0.011,	0.008,	0.003,	0.002,	0.0015,	0.0008,	0.0004,	0.0002,
		0.0001,	0.00005
	};
	for (ii=0;ii<26;ii++)
		m_fFER_100[ii]=(float)fFER_100[ii];


	double fFER_0[26]=
	{	1,		1,		1,		0.80,	0.60,	0.55,	0.40,	0.35,
		0.30,	0.25,	0.20,	0.10,	0.07,	0.04,	0.02,	0.008,
		0.004,	0.001,	0.0005,	0.0002,	0.0001,	0.00005,0.00003,0.00002,
		0.00001,0.000005
	};
	for (ii=0;ii<26;ii++)
		m_fFER_0[ii]=(float)fFER_0[ii];
	//..................................//
}

void CMsManager::AddUser()
{
		//移动台管理模块根据移动台数量、类型分布等参数循环产生相应数量的
	//各种移动台模块

	//产生话音移动台模块
	for(int i=0;i<m_iVoiceNumInSys;i++)
	{
		CVoiceMs* pVoiceMs=new CVoiceMs;
		m_VoiceList.AddTail(pVoiceMs);
	}

	//产生Http移动台模块
	for(i=0;i<m_iHttpNum;i++)
	{
		CHttpDataMs* pHttpDataMs=new CHttpDataMs;
		m_HttpDataList.AddTail(pHttpDataMs);
	}

	//产生Ftp移动台模块
	for(i=0;i<m_iFtpNum;i++)
	{
		CFtpDataMs* pFtpDataMs=new CFtpDataMs;
		m_FtpDataList.AddTail(pFtpDataMs);
	}
}

/////////////////////////////////////////////////////////////////////////
//
//	TITLE:	Functions initializing the mobiles' lists
//
//	PURPOSE:Initialize the three mobiles' lists:
//			Voice mobiles' list
//			Http data mobiles' list
//			Ftp data mobiles' list
//
//	ALGORITHMS:
//			In this function, the mobiles' lists will be initialized by
//			the initialization functions. Since these initialization
//			functions are parallel, all of them should be called. 
//			Specificly, when initializing a voice mobile, we should call
//			the two initialization functions: CMobile::MobileInitialization(),
//			and CVoiceMs::VoiceInitialization(). And three in the case
//			of initializing a http of ftp data mobile.
//
//			The function scans each items in the three lists and calls
//			the corresponding initialization functions.
//
//			The function CMobile::MobileInitialization() is called by each
//			mobile. When calling this function, we should give four input
//			arguments: the ID, the channel type, the velocity, and the
//			standard dviation of slow fanding. The ID can be added before
//			initialization. The standard dviation of slow fanding is fixed.
//			And the channel type and the velocity are corresponding. They
//			are all determined stochasticly.
//
//			For example, there are 5 types of channel models, the probabilities
//			of them are 0.3, 0.3, 0.2, 0.1, 0.1. Then we can let the function
//			produce a random pp between 0 and 1. When pp<0.3, the channel
//			type is 1. When 0.3<=pp<0.6, the channel type is 2, and so on.
//
//			So the function does it like this:
//			1.Determine the intervals. In the case of the above example, the
//			intervals should be: (0, 0.3), (0.3, 0.6), (0.6, 0.8), (0.8, 0.9),
//			and (0.9, 1.0). In fact, the function determines the point dividing
//			the intervals. The dividing points are stored in the array called
//			fV[10]. Considering the extendability of the function, I give the
//			array ten units of space and let fV[4] to fV[9] be 1.0.
//			2.Produce a random in uniform distribution between 0 and 1.
//			3.Compare the random with the dividing points, and determine the 
//			channel type and velocity according to the result.
//
//	CALLING FUNCTIONS:
//			CDataMs::DataMsInitialization()
//			CMobile::MobileInitialization()
//			CFtpDataMs::FtpInitialization()
//			CHttpDataMs::HttpInitialization()
//			CVoiceMs::VoiceInitialization()
//	
//	CALLED BY FUNCTIONS:
//			CNetworkDrive::DropInitialization()
//
//	AUTHOR:	Ouyang Hui
//
//	DATE:	01/04/06
//
//	MODIFICTIONS SINCE 01/04/06
//
//////////////////////////////////////////////////////////////////////////
void CMsManager::MsInitialization(CServiceArea* pService)
{
	POSITION pos;
	int ID=0;
	int nType=0;
	float fV[10];
	float fVelocity,pp;

	//determine the interval division points
	fV[0]=m_fFractionOfChannel[0];
	for (int i=1;i<10;i++)
		fV[i]=1.;
	for (i=1;i<m_iChannelNumber;i++)
		fV[i]=fV[i-1]+m_fFractionOfChannel[i];
	
	//initialize the voice mobiles' list
	pos=m_VoiceList.GetHeadPosition();
	CVoiceMs* pVoiceMs=NULL;
	while (pos!=NULL)
	{
		//...... added by cqm, Apr.8 .......//
		int iVoice=Voice; //产生话音业务移动台
		//..................................//
		pVoiceMs=m_VoiceList.GetNext(pos);
		//
		ID++;	//determine the ID

		cout<<"Mobile #"<<ID<<" initialization..."<<endl;

		//determine the channel type and the correspondent velocity
		pp=xUniform(0.,1.);		//produce a random between 0 and 1
		if (pp<fV[0])			//if the random is between 0 and fV[0]
		{fVelocity=3.;nType=1;}
		else if (pp<fV[1])		//if the random is between fV[0] and fV[1]
		{fVelocity=10.;nType=2;}
		else if (pp<fV[2])		//if the random is between fV[1] and fV[2]
		{fVelocity=30.;nType=3;}
		else if (pp<fV[3])		//if the random is between fV[2] and fV[3]
		{fVelocity=120.;nType=4;}
		else					//if the random is between fV[3] and fV[4]
		{fVelocity=0.;nType=5;}

		cout<<"	Channel type:	"<<nType<<endl;

		//call the initializing functions

		//...... modified by cqm, Apr.8 ......//
		pVoiceMs->MobileInitialization(ID,this,pService,
			fVelocity,nType,m_fStdSlowFading,iVoice); //加了一个参数
		//....................................//
		pVoiceMs->VoiceInitialization();
	}

	//initialize the http data mobiles' list
	pos=m_HttpDataList.GetHeadPosition();
	CHttpDataMs* pHttpDataMs=NULL;
	while (pos!=NULL)
	{
		//...... added by cqm, Apr.8 .......//
		int iData=Data; //产生数据业务移动台
		//..................................//
		pHttpDataMs=m_HttpDataList.GetNext(pos);
		ID++;	//determine the ID

		cout<<"Mobile #"<<ID<<" initialization..."<<endl;

		//determine the channel type and the correspondent velocity
		pp=xUniform(0.,1.);		//produce a random between 0 and 1
		if (pp<fV[0])			//if the random is between 0 and fV[0]
		{fVelocity=3.;nType=1;}
		else if (pp<fV[1])		//if the random is between fV[0] and fV[1]
		{fVelocity=10.;nType=2;}
		else if (pp<fV[2])		//if the random is between fV[1] and fV[2]
		{fVelocity=30.;nType=3;}
		else if (pp<fV[3])		//if the random is between fV[2] and fV[3]
		{fVelocity=120.;nType=4;}
		else					//if the random is between fV[3] and fV[4]
		{fVelocity=0.;nType=5;}

		cout<<"	Channel type:	"<<nType<<endl;

		//call the initializing functions
		pHttpDataMs->MobileInitialization(ID,this,pService,
			fVelocity,nType,m_fStdSlowFading,iData);
		pHttpDataMs->DataMsInitialization(
			m_pLinkPrediction);
		pHttpDataMs->HttpInitialization();
	}

	//initialize the ftp mobiles' list
	pos=m_FtpDataList.GetHeadPosition();
	CFtpDataMs* pFtpDataMs=NULL;
	while (pos!=NULL)
	{
		//...... added by cqm, Apr.9 .......//
		int iData=Data; //产生数据业务移动台
		//..................................//
		pFtpDataMs=m_FtpDataList.GetNext(pos);
		ID++;	//determine the ID

		cout<<"Mobile #"<<ID<<" initialization..."<<endl;

		//determine the channel type and the correspondent velocity
		pp=xUniform(0.,1.);		//produce a random between 0 and 1
		if (pp<fV[0])			//if the random is between 0 and fV[0]
		{fVelocity=3.;nType=1;}
		else if (pp<fV[1])		//if the random is between fV[0] and fV[1]
		{fVelocity=10.;nType=2;}
		else if (pp<fV[2])		//if the random is between fV[1] and fV[2]
		{fVelocity=30.;nType=3;}
		else if (pp<fV[3])		//if the random is between fV[2] and fV[3]
		{fVelocity=120.;nType=4;}
		else					//if the random is between fV[3] and fV[4]
		{fVelocity=0.;nType=5;}

		cout<<"	Channel type:	"<<nType<<endl;

		//call the initializing functions
		pFtpDataMs->MobileInitialization(ID,this,pService,
			fVelocity,nType,m_fStdSlowFading,iData);
		pFtpDataMs->DataMsInitialization(
			m_pLinkPrediction);
		pFtpDataMs->FtpInitialization();
	}

	//initialize other parameters
//zdy
//还应加入一些统计packet和时延的属性
//
    m_fTotalBits=0.0;						//总的传输比特量		
    m_fMeanThroughputPerSector=0.0;		//Drop内的平均吞吐量
	m_pServiceArea=pService;
	m_fMeanPER=0.0;

//zdy新加属性初始化
	m_lTotalErrorPacket=0;				//总的差错Packet数
    m_lTotalGoodPacket=0;			//总的正确Packet数		

	
	//cyu于5.14修改	
	m_iDropNumOfVoice=0;				//话音业务掉话用户数
	m_iBadNumOfVoice=0;					//话音业务不满意用户数
	m_iVoiceUserOfCurrentDrop=0;		//本时隙结束通话的话音用户
	m_fDropTimeLimit=(float)5000./m_fSlotTime;	//话音业务掉话时间限
										//定义为5秒钟,此处折换为时隙
	m_fBadRatioOfVoice=0;				//话音用户的不满意率
	m_fDropRatioOfVoice=0;				//话音用户掉话率
}




//////////////////////////////////////////////////////////////////////////////
//
//	PURPOSE:Process the voice mobiles
//
//	AUTHOR:	Cheng Yu
//
//	AUDITOR:Ouyang Hui
//
//	DATE:	01/04/09
//	
//	TEST RECORD:
//
//	MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::VoiceProcess()
{
//	float i;
	int m=0;
	int p=0,q=0;
	POSITION pos;
	pos=m_VoiceList.GetHeadPosition();
	CVoiceMs* pVoiceMs=NULL;
	//...... added by cqm, Apr.9 ......//
	int iVoice=Voice;
	//.................................//

	while(pos!=NULL)
	{
		pVoiceMs=m_VoiceList.GetNext(pos);

		
		//cyu于5.14修改
		//在对每个移动台进行处理时,同时判断服务时长是否到时以及用户是否掉话
		//若服务时长到时,则判断是否为不满意用户,是则累加不满意用户数
		//若掉话,则完成对掉话用户数的累加
		//若已经完成或掉话,则重新调用移动台初始化函数,重新初始化,并增加激活话音用户数。
		
		//...... modified by cqm, Apr.9 ......//
		if(pVoiceMs->IsServiceOver())//去掉另外一个条件,即不考虑掉话
		{
			
			//cyu于5.17修改
			p=pVoiceMs->GetFERIndicator();//单位为帧
			q=pVoiceMs->GetServiceTime(); //单位为帧 
//			if((float(p)/(float(q)/20.)>0.01)&&(q>2000)&&(!pVoiceMs->m_bIsSHOOut))//统计的帧数应该大于1000帧	
//				m_iBadNumOfVoice++;
			//...................................//
		
			
			//只累加包括本时隙结束通话的话音用户,跨drop通话的用户不统计
//			if((q>2000)&&(!pVoiceMs->m_bIsSHOOut))//test
//				m_iVoiceUserOfCurrentDrop++;
			m_iVoiceNumGenerated[pVoiceMs->GetLocationSector().s-1]--;
			
			int ID=pVoiceMs->GetMsID();
			

			int nType=0;
			float fV[10];
			float fVelocity,pp;
			fV[0]=m_fFractionOfChannel[0];
			for (int i=1;i<10;i++)
				fV[i]=1.;
			for (i=1;i<m_iChannelNumber;i++)
				fV[i]=fV[i-1]+m_fFractionOfChannel[i];

			pp=xUniform(0.,1.);
			if (pp<fV[0])
			{fVelocity=3.;nType=1;}
			else if (pp<fV[1])
				{fVelocity=10.;nType=2;}
			else if (pp<fV[2])
				{fVelocity=30.;nType=3;}
			else if (pp<fV[3])
				{fVelocity=120.;nType=4;}
			else
				{fVelocity=0.;nType=5;}
			pVoiceMs->MobileInitialization(ID,this,m_pServiceArea,
				fVelocity,nType,m_fStdSlowFading,iVoice);
			pVoiceMs->Clean();
			pVoiceMs->VoiceInitialization();
			//test by cqm
			pVoiceMs->SetFERIndicator(p);

⌨️ 快捷键说明

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