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