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

📄 wangluochonggou.cpp

📁 配电网重构是一个多目标、多时段、多组合、多约束的非线性优化问题。该问题的复杂性
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include<stdlib.h>
#include <iostream.h>
#include<time.h>
#include<math.h>
#include <memory.h>

#define POPSIZE 500
#define maximization 1
#define minimization 2
#define cmax 10000
#define cmin 0
#define length1 10
#define length2 10
#define chromlength 12 //染色体长度
#define K 1		// 交叉系数

#define N 9
#define PI 3.1415926
#define E 0.00001

int functionmode=minimization;
int popsize,L;        //种群大小
int maxgeneration; //最大遗传代数
int Mmax;	// 最优个体最小保存代数
int OptCnt; // 直接遗传个体数

double pm;          //变异率
double pc;          //交叉率


struct individual
{
	char chrom[chromlength+1];
	double value;         
	double fitness;      //适应度
	short mCnt;	// 直接遗传代数
};

struct ROAD {
	short head;
	short tail;
	float r;
	float x;
};

struct NodePQ {
	float p;
	float q;
};

int generation;      //遗传代数
int best_index;
int worst_index;
struct individual bestindividual; //最佳个体
struct individual worstindividual; //最差个体
struct individual currentbest;
struct individual population[POPSIZE];

double gNodeV[16]  = { 0.0 }; // 节点电压值
short gNodeVIndex[9] = {0}; // 节点下标



float gRoadRX[16][2] = {0.1262976f, 0.2427984f, // 支路阻抗
						0.0947232f, 0.1820988f,
						0.272802816f, 0.524444544f,
						0.315744f, 0.606996f,
						0.149031168f, 0.286502112f,
						0.13261248f, 0.25493832f,
						0.1262976f, 0.2427984f,
						0.123771648f, 0.237942432f,
						0.26522496f, 0.50987664f,
						0.199550208f, 0.383621472f,
						0.099775104f, 0.191810736f,
						0.1894464f, 0.3641976f,
						0.123771648f, 0.237942432f,
						0.112404864f, 0.216090576f,
						0.1911312f, 0.3641976f,
						0.159276f, 0.303498f };

float gNodePQ[16][2] = {1.0f, 1.0f, // 节点有功、无功
						2.1f, 0.92f,
						1.75f, 0.87f,
						1.25f, 0.65f,
						1.1f, 0.52f,
						1.0f, 1.0f,
						1.28f, 0.76f,
						2.95f, 1.56f,
						1.3f, 0.78f,
						1.45f, 0.59f,
						0.94f, 0.56f,
						1.0f, 1.0f,
						1.42f, 0.68f,
						1.98f, 0.79f,
						1.45f, 0.67f,
						1.08f, 0.45f };

short gRoadNode[16][2] = { 1, 2,  // 支路节点信息
							2, 3,  
							3, 4,  
							4, 15,  
							2, 5,  
							6, 7,  
							8, 7,  
							8, 9,  
							10, 8,  
							5, 10,  
							7, 11,  
							12, 13,  
							14, 13,  
							15, 14,  
							16, 13,  
							11, 16 };		


short gChromRoad[12] = {4, 9, 8, 6, 10, 15, 14, 1, 2, 3, 13, 12}; // 染色体与实际支路对应关系
double v[N] = {0.0};

//函数声明                                       
void generateinitialpopulation(); // 种群初始化               
void generatenextpopulation();//生成下一代
void evaluatepopulation();//评价个体,求最佳个体
long decodechromosome(char *,int,int);//给染色体解码
void calculateobjectvalue();//计算函数值
void calculatefitnessvalue();//计算适应度
void findbestandworstindividual();//求最佳个体和最差个体
void performevolution();//演示评价结果
void selectoperator();//比例选择算法
void crossoveroperator();//交叉算法
void mutationoperator();//变异操作
void input();//数据输入
void outputtextreport();//数据输出

int agaus(double a[], double b[], int n);

double PowerFlow(int iNode, int iBalc, ROAD *pRoad, NodePQ *pNodePQ, bool vOutputVoltage = false)
{
	int M=2*(iNode-1);
	int flag1[N]; // PV节点标志
	
	double g[N][N]; // 电导
	double b[N][N]; // 电纳
	double dvv[N]; // 电压微分
	double angle[N]; // 相角
	double p[N],dp[N]; // 有功及其微分
	double q[N],dq[N]; // 无功及其微分
	double e[N]; // 节点电压实部
	double f[N]; // 节点电压虚部

	double *jcbb = new double[M];
	double *jcb = new double[M*M];

	
	int i,j,i1,j1,n,m,t,k1,balc,node/*,flag,npv*/;
	double rr,xx,bb,k,com1,com2,sump=0.0,sumq=0.0;
	double lossp=0.0, lossq=0.0;

	node = iNode; // 节点数
	balc = iBalc - 1; // 平衡节点

	for(i=0;i<node;i++){
		flag1[i]=0;
		dp[i]=0.0;
		dq[i]=0.0;
		dvv[i]=0.0;
	}
	
	for(i=0;i<node;i++) {
		for(j=0;j<node;j++){
			g[i][j]=0.0;
			b[i][j]=0.0;	
		}
	}

	for(n = 0; n < node-1; n++){  
		i = pRoad[n].head;
		j = pRoad[n].tail;
		rr = pRoad[n].r;
		xx = pRoad[n].x;
//		printf("%d\t%d\t%.3f\t%.3f\n", pRoad[n].head, pRoad[n].tail, pRoad[n].r, pRoad[n].x);
		bb = 0;
		k = 1;
		
		g[i-1][j-1]+=-(rr/(rr*rr+xx*xx)/k);
		b[i-1][j-1]+=-(-xx/(rr*rr+xx*xx)/k);
		g[j-1][i-1]+=-(rr/(rr*rr+xx*xx)/k);
		b[j-1][i-1]+=-(-xx/(rr*rr+xx*xx)/k);
		g[i-1][i-1]+=rr/((rr*rr+xx*xx)*k*k);
		g[j-1][j-1]+=rr/(rr*rr+xx*xx);
		b[i-1][i-1]+=bb+(-xx/((rr*rr+xx*xx)*k*k));
		b[j-1][j-1]+=bb+(-xx/(rr*rr+xx*xx));
	}

	for(i=0;i<node;i++){
		angle[i] = 0;
		v[i] = 1;
		p[i] = pNodePQ[i].p;
		q[i] = pNodePQ[i].q;
//		printf("P:%.3f\t Q:%.3f\n", pNodePQ[i].p, pNodePQ[i].q);
		e[i]=v[i]*cos(angle[i]*PI/180);
		f[i]=v[i]*sin(angle[i]*PI/180);
	}

//	flag1[1]=1;


//	printf("共有n=%d条支路\n",n);
//	printf("节点导纳矩阵如下:\n");
	
//	for(i=0;i<node;i++){
//		for(j=0;j<node;j++)
//			printf("%lf+j%lf   ", g[i][j],b[i][j]);
//		printf("\n\n");}
//
//	printf("初始值如下:\n");
//	printf("节点号 电压     相角      有功       无功        e         f\n");
//	for(i=0;i<node;i++)
//		printf("%d   %lf  %lf  %lf  %lf  %lf  %lf\n", (i+1), v[i], angle[i], p[i], q[i], e[i], f[i]);
	
	for(t=0;t<50;t++){
//		printf("\n第%d次迭代开始:\n", t);
		for(i=0;i<node;i++){
			if(i==balc)    /*如果是平衡节点*/
				continue;
			else{                                    
				com1=0.0, com2=0.0;
				for(j=0;j<node;j++){
					com1+=g[i][j]*e[j]-b[i][j]*f[j];
					com2+=g[i][j]*f[j]+b[i][j]*e[j];
				}
				if(flag1[i]!=1){                         /*如果是PQ节点*/
					dp[i]=p[i]-e[i]*com1-f[i]*com2;
					dq[i]=q[i]-f[i]*com1+e[i]*com2;
				}
				else{
					dp[i]=p[i]-e[i]*com1-f[i]*com2;
					dvv[i]=v[i]*v[i]-(e[i]*e[i]+f[i]*f[i]);
				}
			}
		}
		
		for(i=0,j=0;i<node;i++){                    
			if(i==balc) continue;
			else if(flag1[i]!=1){
				jcbb[j++]=dp[i];
				jcbb[j++]=dq[i];
//				printf("\ndp[%d]=%lf\ndq[%d]=%lf",(i+1),dp[i],(i+1),dq[i]);
			}
			else{
				jcbb[j++]=dp[i];
				jcbb[j++]=dvv[i];
//				printf("\ndp[%d]=%lf\ndvv[%d]=%lf",(i+1),dp[i],(i+1),dvv[i]);
			}
		}
//		printf("\n");
		
		for(i=0;i<node;i++) {
			if(fabs(dp[i])>=E||fabs(dq[i])>=E||fabs(dvv[i])>=E)
				break;
		}
		if(i>=node)
			break;		
		
		
		for(i=0,i1=0;i<node;i++){
			if(i==balc)
				continue;
			i1++;
			n=2*i1;
			for(j=0,j1=0;j<node;j++){
				if(j==balc) continue;
				j1++;
				m=j1*2;
				if(i!=j){					
					jcb[(n-2)*M+m-2]=-(g[i][j]*e[i]+b[i][j]*f[i]);
					jcb[(n-2)*M+m-1]=b[i][j]*e[i]-g[i][j]*f[i];
					if(flag1[i]!=1){
						jcb[(n-1)*M+m-2]=jcb[(n-2)*M+m-1];
						jcb[(n-1)*M+m-1]=-jcb[(n-2)*M+m-2];
					}
					else
						jcb[(n-1)*M+m-2]=jcb[(n-1)*M+m-1]=0.0;
				}
				else{
					com1=0.0, com2=0.0;
					for(k1=0;k1<node;k1++){
						com1+=g[i][k1]*e[k1]-b[i][k1]*f[k1];
						com2+=g[i][k1]*f[k1]+b[i][k1]*e[k1];
					}
					jcb[(n-2)*M+m-2]=-com1-g[i][i]*e[i]-b[i][i]*f[i];
					jcb[(n-2)*M+m-1]=-com2+b[i][i]*e[i]-g[i][i]*f[i];
					if(flag1[i]!=1){
						jcb[(n-1)*M+m-2]=com2+b[i][i]*e[i]-g[i][i]*f[i];
						jcb[(n-1)*M+m-1]=-com1+g[i][i]*e[i]+b[i][i]*f[i];
					}
					else{
						jcb[(n-1)*M+m-2]=-2*e[i];
						jcb[(n-1)*M+m-1]=-2*f[i];
					}
				}
			}
		}
			
//		printf("\n第%d次输出-J矩阵如下:\n", t);
		for(i=0;i<2*(node-1);i++){
			for(j=0;j<2*(node-1);j++){
				jcb[i*M+j]*=-1.0;
//				printf("%lf   ", jcb[i*M+j]);
			}
//			printf("\n\n");
		}
			
		/*算线形方程组*/
		if (agaus(&jcb[0],&jcbb[0],2*(node-1))!=0) {
			for (i=0,j=0;i<2*(node-1);i++) {
				if(j==balc) 
					j++;
				
				if(i%2==0){
					e[j]+=jcbb[i];
//					printf("de[%d]=%lf e[%d]=%lf\n", (j+1),jcbb[i],(j+1),e[j]);
				}
				else{
					f[j]+=jcbb[i];
//					printf("df[%d]=%lf f[%d]=%lf\n",(j+1),jcbb[i],(j+1),f[j]);
					j++;
				}
			}
		}

	}
	
//	printf("共经过了%d次迭代\n", t);
	
	/*求平衡节点P,Q*/
	i=balc;
	com1=0.0, com2=0.0;
	for(j=0;j<node;j++){
		com1+=g[i][j]*e[j]-b[i][j]*f[j];
		com2+=g[i][j]*f[j]+b[i][j]*e[j];
	}
	p[i]=e[i]*com1+f[i]*com2;
	q[i]=f[i]*com1-e[i]*com2;
	
	/*求其他各节点P,Q*/
	for(i=0;i<node;i++){
		if(i==balc) continue;
		else{
			com1=0.0, com2=0.0;
			for(j=0;j<node;j++){
				com1+=g[i][j]*e[j]-b[i][j]*f[j];
				com2+=g[i][j]*f[j]+b[i][j]*e[j];
			}
			p[i]=e[i]*com1+f[i]*com2;
			q[i]=f[i]*com1-e[i]*com2;
		}
	}
	
//	printf("最终结果为:\n");
//	printf("节点号 电压     相角      有功       无功        e         f\n");
	for(i=0;i<node;i++){
		v[i]=sqrt(e[i]*e[i]+f[i]*f[i]);
		angle[i]=atan(f[i]/e[i])*180/PI;
		sump+=p[i];
		sumq+=q[i];
//		printf("%d   %lf  %lf  %lf  %lf  %lf  %lf\n", (i+1), v[i], angle[i], p[i], q[i], e[i], f[i]);
	}
	
	for(i=0;i<node;i++){
		lossp+=p[i];
		lossq+=q[i];
	}
	
//	printf("系统总有功损耗为:%lf\n系统总无功损耗为:%lf\n", lossp, lossq);

	return lossp;
}

float GetPc(short mCnt)
{
	float temp = 1.0f * mCnt / Mmax;
	if( temp <= 0.5 )
		return 0.5;
	else if ( temp < 0.9 )
		return temp*K;
	else
		return 0.9f;
}

float GetPm(short mCnt)
{
	float temp = 0.5f * (float)exp(10*(1.0f*mCnt/Mmax-1));
	if( temp <= 0.01)
		return 0.01f;
	else
		return temp;
}

void generateinitialpopulation( ) //种群初始化
{
	int i,j;

	srand( (unsigned)time(NULL) );

	for (i=0;i<popsize; i++)
	{
		for(j = 0; j < chromlength; j++)
			population[i].chrom[j] = '1';

		population[i].chrom[rand()%4]='0';		// 选折第一段断开的支路 4 条支路
		population[i].chrom[rand()%3+4]='0';	// 选折第二段断开的支路 3 条支路
		population[i].chrom[rand()%5+7]='0';	// 选折第三段断开的支路 5 条支路
		population[i].chrom[chromlength]='\0';
	}
	

}

void generatenextpopulation() //生成下一代
{
	selectoperator();//选择运算
	crossoveroperator();//交叉运算
	mutationoperator();//变异运算
	for( int i = OptCnt; i < popsize; i++ )
		population[i].mCnt = 0;
}

void evaluatepopulation()   //评价个体,求最佳个体
{
	calculateobjectvalue();//计算函数值
	calculatefitnessvalue();//计算适应度
}



void calculateobjectvalue() //计算函数值
{
	int i, j, iRoad, head;
	ROAD pRoad[8];
	NodePQ pNodePQ[9];

	short roadNum = 0; // 支路号
	short nodeNum = 0; // 节点号
	double lossP = 0.0;

	for (j = 0; j < popsize; j++) {
		lossP = 0.0;
		
		// 计算第一个平衡节点
		memset(pRoad,0,sizeof(pRoad)); // 初始化缓存
		memset(pNodePQ,0,sizeof(pNodePQ));

		pRoad[0].head = 1;// 电源节点 1 所在支路,固定的支路 
		pRoad[0].tail = 2;
		gNodeVIndex[0] = 0;
		pRoad[0].r = gRoadRX[0][0];
		pRoad[0].x = gRoadRX[0][1]; 
		gNodeVIndex[1] = 1;
		
		pNodePQ[0].p = gNodePQ[0][0]; // 固定支路对应的节点
		pNodePQ[0].q = gNodePQ[0][1];
		pNodePQ[1].p = gNodePQ[1][0];
		pNodePQ[1].q = gNodePQ[1][1];

		iRoad = 1;
		head = 2;
		
		for (i = 0; i < 4; i++) { // 第一段线路 正向 4 条支路
			if (population[j].chrom[i] != '1')
				break;

			pRoad[iRoad].head = head;
			pRoad[iRoad].tail = head+1;

			roadNum = gChromRoad[i]; // 染色体 i 对应的支路
			pRoad[iRoad].r = gRoadRX[roadNum][0];
			pRoad[iRoad].x = gRoadRX[roadNum][1]; 

			nodeNum = gRoadNode[roadNum][1] - 1; // 支路 roadNum 正向 末端节点
			gNodeVIndex[head] = nodeNum;
			pNodePQ[head].p = gNodePQ[nodeNum][0]; // 节点 P、Q

⌨️ 快捷键说明

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