maoptim.cpp

来自「电力系统稀疏矩阵计算类,用法范例代码,包括三个目录,MALIB(类),MATES」· C++ 代码 · 共 796 行 · 第 1/2 页

CPP
796
字号
                  if ( linkpt->statept->orderpt < new_orderpt )
                     new_orderpt = linkpt->statept->orderpt;
               }
               linkpt = linkpt->linkpt;
            }
            pivot ( orderpt, new_orderpt );
         }
   
         linkpt = orderpt->statept->linkpt;
         while ( linkpt != NULL )
         {
            if ( linkpt->statept->orderpt > orderpt )
            {
               if ( linkpt->statept->stat.reorder )
               {
                  linkpt->statept->anchorpt = orderpt->statept;
                  linkpt->statept->stat.reorder = FALSE;
                  orderpt->statept->stat.fillin_zero = TRUE;
                  workpt->num_zero_fillin++;
               }
            }
            linkpt = linkpt->linkpt;
         }
      }
   }
   
   return;
}

//************************************************************************
// pivot - interchange rows
// 交换两行的orderst排序关系数据,本质为交换顺序  
//************************************************************************
void EmsMatrix::pivot(struct oporderst *zero_orderpt,struct oporderst *fillin_orderpt)
{
   int zero_connection_cnt, fillin_connection_cnt;   
   struct opstatest *zero_statept, *fillin_statept; 

   zero_statept = zero_orderpt->statept;
   fillin_statept = fillin_orderpt->statept;
   zero_connection_cnt = zero_statept->connection_cnt;
   fillin_connection_cnt = fillin_statept->connection_cnt;
   
   zero_statept->orderpt = fillin_orderpt;
   zero_orderpt->statept = fillin_statept;
   fillin_statept->orderpt = zero_orderpt;
   fillin_orderpt->statept = zero_statept;
   
   zero_statept->anchorpt = fillin_statept;
   fillin_statept->connection_cnt = zero_connection_cnt;
   zero_statept->connection_cnt = fillin_connection_cnt;
   
   return;
}

//************************************************************************
// shift_order - shift a set of calculate order rows
//************************************************************************
void EmsMatrix::shift_order( struct oporderst *zero_orderpt, struct oporderst *fillin_orderpt )
{
   struct opstatest *zero_statept, *fillin_statept;
  
   struct oporderst *orderpt, *next_orderpt;  
   
   zero_statept   = zero_orderpt->statept;
   fillin_statept = fillin_orderpt->statept;
   
   orderpt = zero_orderpt;
   while ( orderpt < fillin_orderpt )
   {
      next_orderpt = orderpt + 1;
      orderpt->statept = next_orderpt->statept;
      orderpt->statept->orderpt = orderpt;
      orderpt = next_orderpt;
   }
    
   fillin_orderpt->statept = zero_statept;
   zero_statept->orderpt = fillin_orderpt;
   zero_statept->anchorpt = fillin_statept;
   zero_statept->connection_cnt = fillin_statept->connection_cnt;
   
   return;
}

//************************************************************************
// scheme2 - perform scheme II optimal ordering
// Tinney-scheme2 算法
//  
//************************************************************************
//************************************************************************
// 函数名称:       scheme2 
// 返回值:          无
// 函数功能:       为节点优化编号的主要步骤之一,作用主要有二:一是遍历
//                  并判断与欲删节点相连的所有节点间是否有支路连接,如没有,
//                  则需在此节点间增加新的连接,由函数fillin( )实现;二是
//                  删除最小度节点,使与该节点相连的各节点所连支路数分别减1,
//                  由函数eliminate( )实现。
// 变量说明:       1、base_linkpt->statept  后一条支路的尾节点 
//                  2、linkpt->statept       前一条支路的尾节点
// 注意事项:       链表中各链节众多指针的指向比较复杂,容易混淆,需注意
// 注释信息:       mdn  8.16
//************************************************************************
void EmsMatrix::scheme2( register struct opworkst *workpt )
{
   int i,connection_cnt;          
   struct oporderst *orderpt;      
   struct opstatest *statept;      
   struct oplinkst *linkpt, *base_linkpt, *prev_linkpt;  
   
   //对全部节点按Scheme1的Oreder循环
   for ( i = 1, orderpt = workpt->orderpt; i <= nmastate; i++, orderpt++ )//找到下一欲删节点 mdn 8.11
   {
      statept = orderpt->statept;
      prev_linkpt = NULL;
      base_linkpt = statept->linkpt;
      connection_cnt = 0;
      while ( base_linkpt != NULL ) //对当前节点所连所有支路循环  mdn  8.11
      {
         connection_cnt++;
         
		 base_linkpt->statept->stat.zero_diag = FALSE;
         //首LINK
		 prev_linkpt = base_linkpt;
         //2-LINK
		 linkpt = base_linkpt->linkpt;
         while ( linkpt != NULL )  //处理当前节点所连支路尾节点所连的所有支路,如无连接,则新增连接  mdn  8.11
         {
            if ( workpt->garbagept == NULL )
            {
               workpt->stat.overflow = TRUE;
               break;
            }
            else if ( workpt->garbagept->linkpt == NULL )
            {
               workpt->stat.overflow = TRUE;
               break;
            }
            else
            {
               fillin ( base_linkpt->statept, linkpt->statept, workpt );//见变量说明  mdn  8.11
               fillin ( linkpt->statept, base_linkpt->statept, workpt );
            }
            linkpt = linkpt->linkpt;
         }
         if ( workpt->stat.overflow )
            break;
         eliminate ( base_linkpt->statept, statept, workpt );//删除节点,由最后一条支路向前,逐次使各节点的度减1  mdn  8.11
         base_linkpt = base_linkpt->linkpt; //移到当前节点的前一条支路  mdn  8.11
      }
   
      if ( workpt->stat.overflow )
         break;
   
      if ( prev_linkpt != NULL )
      {
         prev_linkpt->linkpt = workpt->garbagept;
         workpt->garbagept   = statept->linkpt;
         statept->linkpt     = NULL;
      }
      workpt->off_diagonal += connection_cnt;
   }
   
   return;
}

//************************************************************************
// terminate - program termination
//************************************************************************
void EmsMatrix::opterminate ( struct opworkst *workpt )
{
   int i; 
   struct mastatest *mastatept;     
   struct   oporderst   *orderpt;      
   struct   maorderst  *maorderpt;       
   
   if ( ! workpt->stat.overflow )
   {
      //add 2006-02 
     if (maorderft==NULL)
     {
        maorderft =(char *) new struct maorderst[nmastate];
	
	 }
	 else
	 {
        maorder_vt.clear();
	 }
	  memset(maorderft,0,nmastate*sizeof(struct maorderst));
	  maorderpt = (struct maorderst *)maorderft;  
      
	  orderpt = workpt->orderpt;

      for ( i = 1; i <= nmastate; i++,orderpt++,maorderpt++ )
      {
     	 maorderpt->mastate_itm  = orderpt->statept->stateitm;
         mastatept = mastate_vt[maorderpt->mastate_itm - 1];
         mastatept->maorder_itm = i;
		 maorder_vt.push_back(maorderpt);
      }
      workpt->off_diagonalpt = workpt->off_diagonal;
      nmagmtrx = workpt->off_diagonal;
   }
   free( workpt->statept );
   free( workpt->orderpt );
   free( workpt->linkpt );
   
   return;
}

//************************************************************************
// fillin - add matrix connection
// 把jstatept加到istatept后
//************************************************************************
//************************************************************************
// 函数名称:       fillin 
// 返回值:          无
// 函数功能:       消除节点后,在两节点间增加新的连接
// 变量说明:          
// 注意事项:       此程序内语句功能不易描述,现以矩阵运算(P52)所示结构为例说明
//                  设当前欲消去的节点为4,节点4所连的最后一条支路尾节点为5(istatept)
//                  节点4所连的前一条支路尾节点为3(jstatept)
// 注释信息:       mdn  8.16
//************************************************************************
void EmsMatrix::fillin( struct opstatest *istatept, struct opstatest *jstatept, struct opworkst *workpt )
{
   int connection_cnt;        
   char add_connection;        
   struct oplinkst *linkpt;     
   struct oporderst *orderpt, *last_orderpt, *skip_orderpt, *next_orderpt; 
   struct oporderst *iorderpt, *korderpt;     
   struct opstatest *kstatept;     
   
   last_orderpt = workpt->last_orderpt;
   skip_orderpt = workpt->skip_orderpt;
   add_connection = TRUE;
   
   linkpt = istatept->linkpt; //处理当前节点所连最后一条支路尾节点所连的支路 mdn  8.11
   while ( linkpt != NULL ) //遍历节点5所连支路  mdn  8.11
   {
      //行已经在列表中
	  if ( linkpt->statept == jstatept )//节点5与节点3之间由连接,消去4后,不用在3-5间新增连接  mdn  8.11
      {
         add_connection = FALSE;
         break;
      }
      else
         linkpt = linkpt->linkpt;//转入节点5所连下一条支路  mdn  8.11
   }
   //istatept->linkpt.statept=jstatept;
   if ( add_connection ) //需要新增连接  mdn  8.11
   {
      linkpt = workpt->garbagept;
      workpt->garbagept = linkpt->linkpt;
      linkpt->statept   = jstatept; //linkpt->statept指向节点3  mdn  8.11
      linkpt->linkpt    = istatept->linkpt;//在节点5所连支路链表首(内存地址大)增加新链节  mdn  8.11 
      istatept->linkpt  = linkpt;//节点5的linkpt指向该节点支路链表首(内存大处)  mdn  8.11
      istatept->connection_cnt++;//节点5所连支路数加1  mdn  8.11
   
      if ( istatept->stat.fillin_zero )
      {
         while ( linkpt != NULL )
         {
            if ( linkpt->statept->stat.zero_diag )
            {
               if ( linkpt->statept->anchorpt == istatept )
               {
                 if ( linkpt->statept->orderpt <= last_orderpt )
                    last_orderpt = linkpt->statept->orderpt - 1;
               }
            }
            linkpt = linkpt->linkpt;
         }
   
         skip_orderpt = last_orderpt - AS_ORDER_SKIP;
      }
   
      orderpt = istatept->orderpt + 1;//指向节点5  mdn  8.11
      connection_cnt = istatept->connection_cnt;
   
      orderpt += AS_ORDER_SKIP;//指向节点6  mdn  8.11
      while ( orderpt <= skip_orderpt )//小于节点数  mdn  8.11
      {
         if ( connection_cnt <= orderpt->statept->connection_cnt )
            break;
         orderpt += AS_ORDER_SKIP;
      }
      orderpt -= AS_ORDER_SKIP;//orderpt指向最后一个orderst  mdn  8.11
   
      while ( orderpt <= last_orderpt )
      {
         if ( connection_cnt <= orderpt->statept->connection_cnt )
            break;
         orderpt++;
      }
   
      if ( orderpt <= last_orderpt )
      {
         orderpt--;
         if ( istatept != orderpt->statept )
         {
            kstatept = orderpt->statept;
            iorderpt = istatept->orderpt;
            korderpt = kstatept->orderpt;
            istatept->orderpt = korderpt;
            kstatept->orderpt = iorderpt;
            iorderpt->statept = kstatept;
            korderpt->statept = istatept;
         }
      }
       
      //if ( istatept->stat.fillin_zero )  //old code 
      if (( istatept->stat.fillin_zero )&&(orderpt <= last_orderpt))
      {
         next_orderpt = orderpt + 1;
         if ( next_orderpt->statept->anchorpt == istatept )
   	 istatept->connection_cnt = next_orderpt->statept->connection_cnt;
      }
   }
   
   return;
}
//************************************************************************
// eliminate - remove matrix connection
// 删除连结:istatept与jstatept
//************************************************************************
//************************************************************************
// 函数名称:       eliminate 
// 返回值:          无
// 函数功能:       消去当前节点,使该节点所连各支路尾节点的度减1                 
// 变量说明:       
//                     
// 注意事项:       链表中各链节众多指针的指向比较复杂,容易混淆,需注意
// 注释信息:       mdn  8.16
//************************************************************************
void EmsMatrix::eliminate ( struct   opstatest   *istatept, struct opstatest *jstatept, struct opworkst *workpt )
{
   int connection_cnt;          
   struct oplinkst *linkpt, *prev_linkpt;  
   struct oporderst *orderpt, *iorderpt, *korderpt, *jorderpt;     
   struct opstatest *kstatept;     
   
   linkpt = istatept->linkpt;//linkpt指向节点5所连的支路链表首  mdn  8.11
   prev_linkpt = NULL;
   while ( linkpt != NULL )//对节点5所连的支路遍历,直到找到尾节点为4的支路  mdn  8.11
   {
      if ( linkpt->statept == jstatept )//5-4支路,即节点5所连支路的尾节点为4(欲删节点)  mdn  8.11
         break;
      prev_linkpt = linkpt;
      linkpt      = linkpt->linkpt;
   }
   
   if ( linkpt != NULL )//欲删节点  mdn  8.11
   {
       
      if ( prev_linkpt == NULL )
         istatept->linkpt = linkpt->linkpt;
      else
         prev_linkpt->linkpt = linkpt->linkpt;
   
      istatept->connection_cnt--;//节点5所连支路数减1  mdn  8.11
      connection_cnt = istatept->connection_cnt;
      linkpt->linkpt = workpt->garbagept;
      workpt->garbagept = linkpt;
      orderpt  = istatept->orderpt - 1;//节点5的orderpt减1,即顺序前移1(由4变为3)  mdn  8.11
      jorderpt = jstatept->orderpt;//jorderpt指向顺序1  mdn  8.11
       
      if ( istatept->stat.zero_diag )
      {
         if ( istatept->anchorpt->orderpt > jorderpt )
   	 jorderpt = istatept->anchorpt->orderpt;
      }
   
      while ( orderpt > jorderpt )//节点5的顺序大于1  mdn  8.11
      {
         if ( connection_cnt >= orderpt->statept->connection_cnt )//节点5的度(顺序为4)大于等于节点6的度(顺序为3)  mdn  8.11
   	 break;
         orderpt--;//遍历找到一个orderpt其对应节点的度小于节点5(当前节点)的度  mdn  8.11
      }
   
      if ( orderpt > jorderpt )//顺序大于1  mdn  8.11
      {
         orderpt++;
         if ( istatept != orderpt->statept )//消去节点4后,对节点5的顺序(度已更新),进行冒泡  mdn  8.11
         {
            kstatept = orderpt->statept;//k节点度大于节点5的度,kstatept指向节点k  mdn  8.11
            iorderpt = istatept->orderpt;//iorderpt指向节点5  mdn  8.11
            korderpt = kstatept->orderpt;//korderpt指向节点k  mdn  8.11
            istatept->orderpt = korderpt;//节点5指向korderpt  mdn  8.11
            kstatept->orderpt = iorderpt;//节点k指向节点5的orderpt  mdn  8.11
            iorderpt->statept = kstatept;
            korderpt->statept = istatept;
         }
      }
   }
   
   return;
}

⌨️ 快捷键说明

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