📄 hnn.cpp
字号:
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include "HNN.h"
HNN::HNN(int n, int m, int** machine/* = NULL */, int** protime/* = NULL */)
:cost(HUGENUM),E(0),runMin(0),runSec(0),runMSec(0)
{
this->n = n;
this->m = m;
N = n*m;
int i, j;
//分配参数空间
this->machine = new int*[n];
this->protime = new int*[n];
for (i = 0; i < n; i++)
{
this->machine[i] = new int[m];
this->protime[i] = new int[m];
}
this->th = new double*[N+1];
for (i = 0; i < N+1; i++)
{
this->th[i] = new double[N+1];
}
v = new double*[N];
u = new double*[N];
I = new double*[N];
M = new double*[N];
for (i = 0; i < N; i++)
{
v[i] = new double[N+1];
u[i] = new double[N+1];
I[i] = new double[N+1];
M[i] = new double[N+1];
}
chart = new GanttChart(n, m, machine, protime);
//初始化参数
if (machine!=NULL)
{
setMachine(machine);
}
if (protime!=NULL)
{
setTime(protime);
}
for(i = 0; i < N+1; i++)
{
for(j = 0; j < N+1; j++)
{
th[i][j] = 0;
}
}
for(i = 0; i < N+1; i++)
{
th[i][i] = 1;
}
srand(time(0));
cout.open("result.txt");
}
HNN::~HNN()
{
int i;
//释放分配的资源
for (i = 0; i < n; i++)
{
delete []machine[i];
delete []protime[i];
}
delete []machine;
delete []protime;
for (i = 0; i < N+1; i++)
{
delete []th[i];
}
delete []th;
for (i = 0; i < N; i++)
{
delete []v[i];
delete []u[i];
delete []I[i];
delete []M[i];
}
delete []v;
delete []u;
delete []I;
delete []M;
delete chart;
}
void HNN::setPara(double a, double b, double c, double d1, double d2, double d3, double dt, double tc, double r, double u0)
{
A = a;
B = b;
C = c;
D1 = d1;
D2 = d2;
D3 = d3;
this->dt = dt;
this->c = tc;
this->R = r;
this->u0 = u0;
}
void HNN::setMachine(int** machine)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
this->machine[i][j] = machine[i][j];
}
}
chart->setMachine(machine);
}
void HNN::setTime(int** protime)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
this->protime[i][j] = protime[i][j];
}
}
chart->setProTime(protime);
}
void HNN::initI()
{
int i, j, k;
for(i = 0; i < N; i++)
{
for(j = 0; j < N+1; j++)
{
I[i][j] = B*m*n+D1*m*th[j][0];
}
}
for(i = 0; i < n; i++)
{
for(j = 1; j < m; j++)
{
I[i*m+machine[i][j]-1][0] = -0.1;
}
}
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
for(k = j; k < m; k++)
{
I[i*m+machine[i][j]-1][i*m+machine[i][k]] = -0.1;
}
}
}
}
void HNN::initNeros()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
//u[i][j] = rand()%1000/1000.0;
u[i][j] = 0.1-0.2*(double)rand()/(double)RAND_MAX;
v[i][j] = 0.1-0.2*(double)rand()/(double)RAND_MAX;
//u[i][j] = 0;
//v[i][j] = 0;
}
}
}
void HNN::solveMotionEqu()
{
//累计w*v,得神经运动方程项M
countM();
//用Runge-Kutta法求解运动方程
rungeKutta1();
//rungeKutta4();
}
void HNN::countM()
{
//分配求解运动方程的中间变量
int i, j, t1, t2, t3;
double *vh;
double *vl;
double **vd1;
double **vd2;
double vall;
vh = new double[N];
vl = new double[N+1];
vd1 = new double*[N];
vd2 = new double*[N];
for (i = 0; i < N; i++)
{
vd1[i] = new double[N+1];
vd2[i] = new double[N+1];
}
//计算中间变量,并得到M[][]
vall = 0;
for(i = 0; i < N; i++)
{
vh[i] = 0;
for(j = 0; j < N+1; j++)
{
vh[i] += v[i][j];
vall += v[i][j];
}
}
for(i = 0; i < N+1; i++)
{
vl[i] = 0;
for(j = 0; j < N; j++)
{
vl[i] += v[j][0]*th[i][0];
}
}
for(i = 0; i < N; i++)
{
for(j = 0; j < N+1; j++)
{
vd1[i][j] = 0;
for(t1 = 0; t1 < n; t1++)
{
for(t2 = 0; t2 < m; t2++)
{
for(t3 = 0; t3 < m; t3++)
{
vd1[i][j] += v[t3+t1*m][j]*th[i][t2+t1*m];
}
vd1[i][j] -= v[t2+t1*m][j]*th[i][t2+t1*m];
}
}
}
}
for(i = 0; i < N; i++)
{
for(j = 0; j < N+1; j++)
{
vd2[i][j] = 0;
for(t1 = 0; t1 < m; t1++)
{
for(t2 = 0; t2 < n; t2++)
{
for(t3 = 0; t3 < n; t3++)
{
vd2[i][j] += v[t1+t3*m][j]*th[i][t1+t2*m];
}
vd2[i][j] -= v[t1+t2*m][j]*th[i][t1+t2*m];
}
}
}
}
for(i = 0; i < N; i++)
{
M[i][0] = -A*(vh[i]-v[i][0])-B*vall-D1*vl[0]-D2*vd1[i][0]-D3*vd2[i][0]+I[i][0];
for(j = 1; j < N+1; j++)
{
M[i][j] = -A*(vh[i]-v[i][j])-B*vall-C*v[j-1][i+1]*(1-th[i][j-1])*(1-th[j][i+1])
-D1*vl[j]-D2*vd1[i][j]-D3*vd2[i][j]+I[i][j];
}
}
//释放中间变量
delete []vh;
delete []vl;
for (i = 0; i < N; i++)
{
delete []vd1[i];
delete []vd2[i];
}
delete []vd1;
delete []vd2;
}
void HNN::rungeKutta4()
{
double k1, k2, k3, k4;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
k1 = (M[i][j]-u[i][j]/R)/c;
k2 = (M[i][j]-u[i][j]/R)/c-dt/2*k1;
k3 = (M[i][j]-u[i][j]/R)/c-dt/2*k2;
k4 = (M[i][j]-u[i][j]/R)/c-dt*k3;
u[i][j] = u[i][j]+dt/6*(k1+2*k2+2*k3+k4);
}
}
}
void HNN::rungeKutta1()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
u[i][j] = (1-dt/c/R)*u[i][j]+dt/c*M[i][j];
}
}
}
void HNN::neroOutputs()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
v[i][j] = 0.5*(1+tanh(u[i][j]/u0));
if (v[i][j] > 0.9) v[i][j] = 1;
else if (v[i][j] < 0.1) v[i][j] = 0;
}
}
}
void HNN::countE()
{
double a = 0;
double b = 0;
double c = 0;
double d1 = 0;
double d2 = 0;
double d3 = 0;
double x = m < n ? m : n;
int i, j, k, k1, k2, k3;
for (k = 0; k < N; k++)
{
for (i = 0; i< N+1; i++)
{
for (j = 0; j < N+1; j++)
{
a += v[k][i]*v[k][j];
}
a -= v[k][i]*v[k][i];
}
}
for (k = 0; k < N; k++)
{
for (i = 0; i< N+1; i++)
{
b += v[k][i];
}
}
b = (b-N)*(b-N);
for (i = 1; i< N+1; i++)
{
for (k = 0; k < N; k++)
{
c += v[k][i]*v[i-1][k+1];
}
c -= v[i-1][i]*v[i-1][i];
}
/*
for (k = 0; k < N; k++)
{
d1 += v[k][1];
}
d1 = (d1-x)*(d1-x);
for (i = 0; i < N+1; i++)
{
for (k1 = 0; k1 < n; k1++)
{
for (k2 = 0; k2 < m; k2++)
{
for (k3 = 0; k3 < m; k3++)
{
d2 += v[k2+k1*m][i]*v[k3+k1*m][i];
}
d2 -= v[k2+k1*m][i]*v[k2+k1*m][i];
}
}
for (k1 = 0; k1 < m; k1++)
{
for (k2 = 0; k2 < n; k2++)
{
for (k3 = 0; k3 < n; k3++)
{
d3 += v[k1+k2*m][i]*v[k1+k3*m][i];
}
d3 -= v[k1+k2*m][i]*v[k1+k2*m][i];
}
}
}
*/
// E = A/2*a + B/2*b + C/2*c + D1/2*d1 + D2/2*d2 + D3/2*d3;
E = A/2*a + B/2*b + C/2*c;
}
bool HNN::run()
{
//初始化神经网络
cout.close();
cout.open("result.txt");
cout<<"Initial state:"<<endl;
initI();
printI();
initNeros();
printNeroInputs();
printNeroOutputs();
cout<<"\n\nStart to run..."<<endl;
//运行神经网络
double starttime = GetTickCount();
for(int t = 0; t <1000; t++)
{
cout<<"\nTime "<<t+1<<":"<<endl;
//解神经元运动方程: c*du/dt = -u/r+M
solveMotionEqu();
printNeroInputs();
//计算神经元输出
neroOutputs();
printNeroOutputs();
//判断神经网络是否已经收敛
double pE = E;
countE();
cout<<"E: "<<E<<endl;
if (fabs(E-pE)<0.00001) break;
}
cout.flush();
double endtime = GetTickCount();
double runtime = (endtime - starttime)/1000.0;
formatTime(runtime);
//判断所得调度结果是否为合法
if (abs(E)>0.0001) return false;
//处理所得调度结果
chart->setMatrix(v);
chart->constructGantt();
cost = chart->getMaxTime();
return chart->isValid();
}
void HNN::drawNeroOutputs(GanttHis* his)
{
chart->drawNeroOutputs(his);
/*
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
cout<<v[i][j]<<" ";
}
cout<<endl;
}
*/
}
void HNN::drawGantt(GanttHis* his,int start)
{
chart->drawGantt(his, start);
}
int HNN::getCost()
{
return cost;
}
void HNN::formatTime(double t)
{
runMin = (int)t/60;
double Sec = t - (int)(t/60)*60;
runSec = (int)Sec;
runMSec = (int)((Sec-runSec)*10000);
}
CString HNN::getRunTime()
{
CString a;
if (runMin == 0 && runSec == 0 && runMSec == 0)
{
return "0 秒";
}
if (runMin > 0)
{
a.Format("%d分",runMin);
}
if (runSec > 0)
{
CString b;
b.Format("%d", runSec);
a += b;
}
else
{
a += "0";
}
if (runMSec > 0)
{
CString b;
b.Format(".%d", runMSec);
a += b;
}
a += "秒";
return a;
}
void HNN::printNeroOutputs()
{
cout<<"v:"<<endl;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
cout<<v[i][j]<<" ";
}
cout<<endl;
}
}
void HNN::printNeroInputs()
{
cout<<"u:"<<endl;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
cout<<u[i][j]<<" ";
}
cout<<endl;
}
}
void HNN::printI()
{
cout<<"I:"<<endl;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N+1; j++)
{
cout<<I[i][j]<<" ";
}
cout<<endl;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -