随着敲下明天要交的报告的最后一个句号,本学期的在校学习任务就算正式结束了。
已经快三周没有好好休息了吧,期末考完之后关于ACM的东西也没学几天,还错过了各种想参加练手的比赛。。。。本以为“电力系统潮流上机计算”这种需要上机编程的东西对我来说应该很简单,结果被各种神奇的公式卡住了。但编程方面毕竟还有些优势,最后班里的同学都是参照着我提供的数据把程序调对的,小小地自豪一下。比别人提前3天提交论文,FFT刚看了两行就得知学校要举办美赛数学建模预选赛简直坑爹,还有一个队友不在学校,于是和另一个队友两人爆肝4天总算是搞出了些东西,希望能被选上吧。这是我第一次参加建模大赛,学习了不少姿势,也算是对正式比赛的一个不错的演练,哪天写篇博文总结下。
今天继续爆脑一天研究数电课设,数电学得还行吧,但我设计的电路就是运行不出期望的结果,最后发现是 Multisim 破解不完全导致所有的“非门”电路都不能正常工作……明明用的和别人是同一个版本啊……
后天就要离开帝都回家了,明天休息下吧,回去又要开始新的学习了。。。。
最后贴一下自己的“电力系统潮流上机计算”代码吧,写得很水,仅作纪念。
/*
程序说明:电力系统潮流计算程序,只能处理如下输入格式的数据
先PQ节点,再PV节点,最后平衡节点。
平衡节点的电压相角请使用弧度制
输入样例见最后
*/
#include
#include
#include
#include
#include
using namespace std;
#define N_Node 9 //节点数
#define N_Line 9
#define NodeLoadPath "node.txt" //节点数据路径
#define LineLoadPath "line.txt" //支路数据路径
#define YMatrixPath "Ymatrix.txt" //节点导纳矩阵路径
#define JMatrixPath "Jmatrix.txt" //迭代过程中雅克比矩阵路径
#define PI acos(-1.0) //圆周率
const double STD=0.0001; //目标迭代精度
#define Upmax(a,b) ((a)=(a)>(b)?(a):(b)) //最大值更新
/*
typr==0,平衡节点,first,second,分别代表电压,相角
type==1,PQ节点,first,second,分别代表有功,无功
type==2,PV节点,first,second,分别代表有功,电压
*/
struct Node //节点信息
{
int id,type; //序号,节点类型
double first,second;
void Get (FILE *fp) //节点读入成员函数,传入参数为文件指针
{
fscanf(fp,"%d%d%lf%lf",&id,&type,&first,&second);
}
void Out () //节点输出函数
{
printf("%d %d %lf %lf\n",id,type,first,second);
}
}NodeData[N_Node];
/*
R为电阻,X为电感
type==1,线路支路,C为对地电容
type==2,变压器支路,忽略励磁支路,C为变比
*/
struct Line //支路信息
{
int id,type; //序号,节点类型
int start,end; //链接的头尾节点
double R,X,C; //输入支路的3个参量
void Get (FILE *fp) //
{
fscanf(fp,"%d%d%d%d",&id,&type,&start,&end);
fscanf(fp,"%lf%lf%lf",&R,&X,&C);
}
void Out ()
{
printf("%d %d %d %d ",id,type,start,end);
printf("%lf %lf %lf\n",R,X,C);
}
}LineData[N_Line];
class fushu //自定义复数类
{//定义复数 re+j im
public:
double gre,bim;
fushu () //构造函数
{gre=0,bim=0;}
~fushu () {} //析构函数
void Out ()
{
printf("%8lf+J%8lf\n",gre,bim);
}
//以下通过重载运算符的方式定义复数运算规则
fushu operator + (const fushu a) const
{//加法
struct fushu ans;
ans.gre=gre+a.gre;
ans.bim=bim+a.bim;
return ans;
}
fushu operator - (const fushu a) const
{//减法
struct fushu ans;
ans.gre=gre-a.gre;
ans.bim=bim-a.bim;
return ans;
}
fushu operator * (const double x) const
{//复数乘以实数
struct fushu ans;
ans.gre=gre*x;
ans.bim=bim*x;
return ans;
}
fushu operator * (const fushu x) const
{//两个复数相乘
struct fushu ans;
ans.gre=gre*x.gre-bim*x.bim;
ans.bim=gre*x.bim+bim*x.gre;
return ans;
}
fushu operator ^ (const fushu x) const
{//两个复数各自取共轭,然后相乘
double tbim=-bim,xbim=-x.bim;
struct fushu ans;
ans.gre=gre*x.gre-tbim*xbim;
ans.bim=gre*xbim+tbim*x.gre;
return ans;
}
};
fushu yData[N_Node][N_Node]; //节点导纳矩阵
struct Node_Ans
{//节点的解
int id,type;
fushu u; //电压的实部虚部
double r,alpha; //电压的幅值和相角 (角度制)
double Pin,Qin; //节点的注入功率
double B; //节点的对地导纳
void Out ()
{
printf("%d %d %lf %lf %lf %lf %lf %lf %lf\n",id,type,u.gre,u.bim,r,alpha,Pin,Qin,B);
}
}NodeAns[N_Node];
double CAS[N_Line][N_Line]; //连接支路的端点在该支路的对地导纳
double e[N_Node],f[N_Node]; //节点电压 e+jf
double delta[2*(N_Node-1)]; //功率及电压不平衡量
fushu flow [N_Node][N_Node]; //节点间功率流动
fushu fee[N_Line]; //网损
/*
对于PQ节点,先分别计算 H,N,J,L
对于PV节点,先分别计算 H,N,R,S
其中 R与J,L与S 保存在一起
最后将上述矩阵整合到一起 JMatrix
*/
double H[N_Node-1][N_Node-1],N[N_Node-1][N_Node-1];
double J[N_Node-1][N_Node-1],L[N_Node-1][N_Node-1];
double JMatrix[2*(N_Node-1)][2*(N_Node-1)]; //雅克比矩阵
/*
计算电压的幅值和相角
传入参数为:电压的实部虚部 a+jb,用于保存结果的r,alpha
其中alpha 为角度
*/
void Cal_Vol (double a,double b,double &r,double &alpha)
{
r=sqrt(a*a+b*b);
alpha=atan(b/a);
alpha/=PI;
alpha*=180;
}
bool Input () //读入节点和支路的函数,成功返回true,失败返回false
{
FILE *fp; //以下为读入节点信息
fp=fopen(NodeLoadPath,"r");
if (fp==NULL)
{
printf("Node open fail!");
return false;
}
int i;
for (i=0;iSTD) //精度不满足要求
return false;
return true;
}
void SolveEquation (unsigned int Dimension,double FactorMatrix[16][16], double ConstVector[])
{//解方程函数
unsigned int i,j,k;
//消元过程
for(i=0;i 0; i-- ) //Dimension-2:最后一个变量可直接获得,从n-1个变量求起
{
for(j = Dimension-1; j > i-1 ; j-- )
{
if( FactorMatrix[i-1][j] != 0 )
ConstVector[i-1] = ConstVector[i-1] - FactorMatrix[i-1][j] * ConstVector[j]; //a[i][k]=0时可以不算
}
}
return;
}
/*计算节点的解*/
void Caculate_Node_Ans ()
{
int i,j;
for (i=0;i30)
{
printf("迭代不收敛,程序已退出\n");
return 0;
}
printf("迭代收敛,达到目标精度 %lf 共进行了 %d 次迭代\n",STD,cnt-1);
Caculate_Node_Ans (); //计算各节点的电压,注入功率
Caculate_Flow (); //计算线路的功率流动及网损
if (Output_Ans ()) //向文件输出结果
printf("运算完毕,请查看相关结果文件\n");
else
printf("向文件输出结果失败!\n");
return 0;
}
/*
node.txt
1 1 -1.25 -0.5
2 1 0.000000 0.000000
3 1 -0.9 -0.3
4 1 0.000000 0.000000
5 1 -1.000000 -0.35
6 1 0.000000 0.000000
7 2 1.63 1.025
8 2 0.85 1.025
9 0 1.04 0.000000
line.txt
1 1 1 2 0.01 0.085000001 0.088
2 1 1 6 0.032000002 0.160999998 0.152999997
3 1 2 3 0.017000001 0.092 0.079000004
4 2 2 9 0 0.057999998 1
5 1 3 4 0.039000001 0.170000002 0.179000005
6 1 4 5 0.012 0.101000004 0.104999997
7 2 4 8 0 0.059 1
8 1 5 6 0.018999999 0.071999997 0.075000003
9 2 6 7 0 0.063000001 1
*/