optimize.c

来自「一整套电梯控制器源程序」· C语言 代码 · 共 971 行 · 第 1/3 页

C
971
字号
#include "global.h"

/*uchar GetNextStopLIdx(uchar cEIdx, uchar cStartFloorIdx, uchar bStartDirect, uchar *bDirect);*/
uint CalTimeToDest(uchar cEIdx, uchar cStartFloor, uchar cEndFloor);
uint GetEleToFloorTime(uchar cEIdx, uchar cLIdx, uchar updown_flg);
uchar IsExistInsel(uchar cEIdx);

void WashOut_DistributeInSel(uchar *pWashOutFlg);
void WashOut_2FloorMoveEle(uchar *pWashOutFlg);
void WashOut_NotStopEle(uchar *pWashOutFlg);
void WashOut_VetoEle(uchar *pWashOutFlg);
uchar WashOut_LongTimeEle(uchar cLIdx, uchar updown_flg, uchar *pWashOutFlg);
void WashOut_HeavyBearEle(uchar *pWashOutFlg);
void WashOut_NoSameDirectionEle(uchar *pWashOutFlg);
void WashOut_NoInSelStopEle(uchar cLIdx, uchar updown_flg, uchar *pWashOutFlg);
void WashOut_MoreStopCntEle(uchar *pWashOutFlg);
uchar WashOut_LargerIndexEle(uchar *pWashOutFlg);
void UpdateDistribution(uchar cLIdx, uchar updown_flg, uchar cBestEleNo);
void UpdateStaticStopDistribution(uchar cLIdx, uchar cBestEleNo);


//对所有群控电梯进行选优处理
//说明:只要不是所有电梯都被"一票否决",经过选优处理后,一定会选出一个最佳方案
void OptimizeArrange(uchar cLIdx, uchar updown_flg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar cBestEIdx = INVALID_ELEINDEX;	//最优的电梯索引(注:INVALID_ELEINDEX代表无效索引)
	uchar  bWashOutFlg[ENum_MAX];			//淘汰标记
	uchar i=0;
	uchar ret=0;								//时间计算正确与否

	//淘汰标记清零
	for(i=0; i<ENum_MAX; i++){
		bWashOutFlg[i]	= 0;
	}

	//淘汰"2层以内运动中的电梯"
	WashOut_2FloorMoveEle(bWashOutFlg);

// if(cLIdx==8){
//		mE_InputData.mDianTi[0].TongXun.bZhiShi=m_InterData[0].b2FloorMove;
// }
	//淘汰"该层不可停的电梯"
	WashOut_NotStopEle(bWashOutFlg);

	//淘汰"已被一票否决的电梯"
	WashOut_VetoEle(bWashOutFlg);

	//淘汰"到达该层所需时间较长的电梯"
	ret = WashOut_LongTimeEle(cLIdx, updown_flg, bWashOutFlg);

	//淘汰"承载较重的电梯"
	WashOut_HeavyBearEle(bWashOutFlg);

	//淘汰"非顺向的电梯"
	WashOut_NoSameDirectionEle(bWashOutFlg);

	//若合格的电梯中有一部内选恰好为外呼,且方向一致,淘汰其余电梯
	WashOut_NoInSelStopEle(cLIdx, updown_flg, bWashOutFlg);

	//淘汰"停靠层站数较多的电梯"
	WashOut_MoreStopCntEle(bWashOutFlg);

	//淘汰"电梯优先级号较大的电梯",得到最优电梯序号
	cBestEIdx = WashOut_LargerIndexEle(bWashOutFlg);

//2004.07.21 LHM staticstop
	if((cBestEIdx!=0xFF) && (ret==1)){	//最优电梯索引有效,时间计算有效
			UpdateDistribution(cLIdx, updown_flg, cBestEIdx);
	}else{
//		P1_4=0;
	}

}

void WashOut_DistributeInSel(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		//对于当前所讨论的外呼,该电梯是否已被分配了内选
		if(pWashOutFlg[i]==0)
			if(IsExistInsel(i)==1) 
				pWashOutFlg[i] = 1;
	}
}

void WashOut_2FloorMoveEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		//对于当前所讨论的外呼,该电梯是否"处于两层以内,并且处于运动中"
		if(pWashOutFlg[i]==0)
			if(m_InterData[i].b2FloorMove==1) 
				pWashOutFlg[i] = 1;
	}

}

void WashOut_NotStopEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		//对于当前所讨论的外呼,该电梯是否"在外呼层可停"
		if(pWashOutFlg[i]==0)
			if(m_InterData[i].bFloorCanStop==0) 
				pWashOutFlg[i] = 1;
	}
}

void WashOut_VetoEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		//电梯是否"一票否决"
		if(pWashOutFlg[i]==0)
			if(m_InterData[i].bVeto==1)
				pWashOutFlg[i] = 1;
	}
}

// 返回0异常,返回1正常
uchar WashOut_LongTimeEle(uchar cLIdx, uchar updown_flg, uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uint  time_min = 0xFFFF;	//初始时,设置最短时间足够大
	uchar i=0;
	uchar j=0;
	uint  time=0;

	for(i=0; i<m_cENum; i++){
		if(pWashOutFlg[i] == 0){

			//电梯到第cLIdx所用时间(若超时,追加超时时间)
//			uint time = 0;
			time = GetEleToFloorTime(i, cLIdx, updown_flg)/* + m_cOvertime[i]*/;
			//Added by LHM 2004.07.19 计算异常时,不取本次的计算结果
			if(time==0xFFFF){
				return 0;
			}
			if(time<time_min){	//新短时间									
				if(((time_min-time)>TIMEINTERVAL_MIN)){//若比最短时间"短很多",更新最短时间,且确保淘汰前面的电梯;
					time_min = time;
					//确保淘汰前面的电梯
					for(j=0; j<i; j++){
						if(pWashOutFlg[j] == 0)
							pWashOutFlg[j] = 1;
					}
				}
				else{								  //若比最短时间"短不太多",仅更新最短时间;
					time_min = time;
				}
			}
		    else{				//较长时间
				//若比最短时间"长太多",则淘汰;
				if(( (time-time_min)> TIMEINTERVAL_MIN))
					pWashOutFlg[i] = 1;
			}
		}
	}

	return 1;
}

void WashOut_HeavyBearEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar bear_min = Weight_Heavy;	//初始时,设置负载足够大
	uchar i=0;
	uchar j=0;

	for(i=0; i<m_cENum; i++){
		if(pWashOutFlg[i] == 0){
			//取得电梯承载状态
			uchar cBear = m_InterData[i].cWeight;
			if(cBear<bear_min){				//出现新最小负载
				//更新最小负载
				bear_min = cBear;
				//确保淘汰前面的电梯
				for(j=0; j<i; j++){
					if(pWashOutFlg[j] == 0)
						pWashOutFlg[j] = 1;
				}
			}else if(cBear == bear_min){	//负载与前次相同
				//do nothing 
			}else{							//出现更大负载或错误信号
				//设置淘汰标记
				pWashOutFlg[i] = 1;
			}
		}
	}

}

void WashOut_NoSameDirectionEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;
	
	uchar cExistSameFlg = 0;	//"尚未淘汰的电梯中,存在顺向电梯"的标记
	for(i=0; i<m_cENum; i++){
		if(pWashOutFlg[i]==0)
			if(m_InterData[i].bSameDirection==1){ 
				cExistSameFlg = 1;
				break;
			}
	}

	if(cExistSameFlg == 1){	//存在
		for(i=0; i<m_cENum; i++){
			if(pWashOutFlg[i]==0)
				if(m_InterData[i].bSameDirection==0){ //淘汰非顺向的电梯
					//设置淘汰标记
					pWashOutFlg[i] = 1;
				}
		}
	}else{					//不存在
		//do nothing 
	}
}

//若尚未淘汰的电梯中有一部内选恰好为外呼,且方向一致,淘汰其余电梯
void WashOut_NoInSelStopEle(uchar cLIdx, uchar updown_flg, uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;
	uchar  bExist = 0;	//"某梯在cLIdx层存在内选,尚未淘汰"标记
	E_DianTi *pEleData = 0;
	E_FangXiang *pFangXiang = 0;
	
	for(i=0; i<m_cENum; i++){
		pEleData = &(m_pE_InputData->mDianTi[i]);
		pFangXiang = &(pEleData->FangXiang);
		if(pWashOutFlg[i] == 0){	//尚未淘汰
//			if((pEleData->bNeiXuan[cLIdx]==1)){	//存在内选
			if((GetArrayData(pEleData->bNeiXuan, cLIdx)==1)){	//存在内选
				if((updown_flg==1)&&(pFangXiang->bShang==1)&&(pFangXiang->bXia==0))		//方向一致(上)
					bExist = 1;
				else if((updown_flg==0)&&(pFangXiang->bShang==0)&&(pFangXiang->bXia==1))//方向一致(下)
					bExist = 1;
			}
		}
	}
	
	if( bExist == 1){	//存在
		for(i=0; i<m_cENum; i++){
			pEleData = &(m_pE_InputData->mDianTi[i]);
			pFangXiang = &(pEleData->FangXiang);
			if(pWashOutFlg[i] == 0){
//				if(pEleData->bNeiXuan[cLIdx] != 1){
				if(GetArrayData(pEleData->bNeiXuan, cLIdx) != 1){
					pWashOutFlg[i] = 1;
				}else{
					if((updown_flg==1)&&(pFangXiang->bShang==1)&&(pFangXiang->bXia==0)){	//方向一致(上)
						pWashOutFlg[i] = 0;//do nothing
					}
					else if((updown_flg==0)&&(pFangXiang->bShang==0)&&(pFangXiang->bXia==1)){//方向一致(下)
						pWashOutFlg[i] = 0;//do nothing
					}
					else{
						pWashOutFlg[i] = 1;
					}

				}
			}
		}
	}
/*	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;
	uchar  bExist = 0;

	for(i=0; i<m_cENum; i++){
		E_DianTi *pEleData = &(m_pE_InputData->mDianTi[i]);
		if(pWashOutFlg[i] == 0){
			if(pEleData->bNeiXuanKeTing[cLIdx] == 1)
				bExist = 1;
		}
	}
	
	if( bExist == 1){
		for(i=0; i<m_cENum; i++){
			E_DianTi *pEleData = &(m_pE_InputData->mDianTi[i]);
			if(pWashOutFlg[i] == 0){
				if(pEleData->bNeiXuanKeTing[cLIdx] != 1)
					pWashOutFlg[i] = 1;
			}
		}
	}*/
}

void WashOut_MoreStopCntEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar cStopCnt_min = 0xFF;	//初始时,设置可停站数足够大
	uchar cStopCnt=0;			//电梯可停站数
	uchar i=0;
	uchar j=0;

	for(i=0; i<m_cENum; i++){
		if(pWashOutFlg[i] == 0){
			//取得电梯可停站数
			cStopCnt = m_InterData[i].cStopCount;
			if(cStopCnt<cStopCnt_min){			//出现新最小
				//更新最小
				cStopCnt_min = cStopCnt;
				//确保淘汰前面的电梯
				for(j=0; j<i; j++){
					if(pWashOutFlg[j] == 0)
						pWashOutFlg[j] = 1;
				}
			}else if(cStopCnt == cStopCnt_min){	//与前次相同
				//do nothing 
			}else{								//出现更大
				//设置淘汰标记
				pWashOutFlg[i] = 1;
			}
		}

⌨️ 快捷键说明

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