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 + -
显示快捷键?