Commit 8b64e676 authored by 刘乐's avatar 刘乐

1, 更新

parent 03c5b5a4
#include "CivHydrTest.h"
#include "CivHydrFuncInter.h"
#include <iostream>
#include <string>
CivHydrTest::~CivHydrTest()
{
}
// 优化调度测试
void CivOptSchedulingTest::test(char* uri)
{
std::string condtionMap = "{\"JD0000159\":{\"min\":20,\"max\":48},\"JD0000324\":{\"min\":20,\"max\":48},\"JD0000416\":{\"min\":20,\"max\":48},\"JD0000422\":{\"min\":20,\"max\":48},\"JD0000457\":{\"min\":20,\"max\":48},\"JD0000532\":{\"min\":20,\"max\":48},\"JD0000538\":{\"min\":20,\"max\":48},\"JD0000582\":{\"min\":20,\"max\":48},\"JD0000648\":{\"min\":20,\"max\":48},\"JD0000652\":{\"min\":20,\"max\":48},\"JD0000665\":{\"min\":20,\"max\":48},\"JD0000703\":{\"min\":20,\"max\":48},\"JD0000724\":{\"min\":20,\"max\":48}}";
int time = 9;
char* condition = const_cast<char*>(condtionMap.c_str());
char result[1024 * 512];
bool res = optimalSchedulingSimulation(uri, condition, 9, result);
std::cout << "测试结果" << res << std::endl;
std::cout << result << std::endl;
}
// 水力测试
void CivConHydrTest::test(char* uri)
{
......@@ -40,7 +56,7 @@ void CivUpstreamTrackingTest::test(char* uri)
{
// 追踪节点编号
char sn[64];
strcpy(sn, "5fbaaf9e-dfcf-4e97-9fb1-31d03293f654");
strcpy(sn, "913fdd03-6b29-4a61-9c3b-e2f0bb33cb3c");
char result[1024 * 128];
......@@ -58,7 +74,7 @@ void CivDownStreamTrackingTest::test(char* uri)
{
// 追踪节点编号
char sn[64];
strcpy(sn, "5fbaaf9e-dfcf-4e97-9fb1-31d03293f654");
strcpy(sn, "48ff56e6-b50f-4003-ad5c-95240c114e42");
char result[1024 * 512];
......@@ -76,7 +92,7 @@ void CivWaterSupplyScopeTest::test(char* uri)
{
// 追踪节点编号
char sn[512];
strcpy(sn, "ffd0f63d-b8c3-4354-aea5-aedc52cb8e16");
strcpy(sn, "913fdd03-6b29-4a61-9c3b-e2f0bb33cb3c");
char result[1024 * 32];
......@@ -90,7 +106,7 @@ void CivProjSimulationTest::test(char* uri)
{
// 追踪节点编号
char projCode[512];
strcpy(projCode, "ba01c9a8-f113-4131-b566-5f7f1ce25e5c");
strcpy(projCode, "e9443d7f-d05b-4768-94b7-084a5d0fe3ba");
char time[512];
strcpy(time, "2020-09-24 09:00:00");
......
......@@ -8,6 +8,13 @@ public:
virtual ~CivHydrTest();
};
// 优化调度测试
class CivOptSchedulingTest :public CivHydrTest
{
public:
virtual void test(char* uri);
};
// 水力测试
class CivConHydrTest :public CivHydrTest
{
......
......@@ -135,12 +135,13 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;PANDANALYSIS_DLL;PANDANALYSIS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(OUTDIR)..\include</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>pandaAnalysis.lib;pandaLog.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OUTDIR)..\lib</AdditionalLibraryDirectories>
</Link>
......
......@@ -14,14 +14,42 @@
#include <windows.h>
#include <consoleapi2.h>
#include "JsonParseObject.h"
using namespace std;
double random(int min, int max)
{
double m1 = (double)(rand() % 101) / 101; // 计算 0,1之间的随机小数,得到的值域近似为(0,1)
min++; //将 区间变为(min+1,max),
double m2 = (double)((rand() % (max - min + 1)) + min); //计算 min+1,max 之间的随机整数,得到的值域为[min+1,max]
m2 = m2 - 1; //令值域为[min,max-1]
double dd = (m1 + m2) * 100;
double res = (int)dd;
return res / 100; //返回值域为(min,max),为所求随机浮点
}
// 测试json解析字符出
void testJson()
{
std::string jsonstr = "{\"监测点1\":{\"min\":20,\"max\":30},\"监测点2\":{\"min\":28.5,\"max\":32.4},\"雄楚大道\":{\"min\":23,\"max\":31.9}}";
JsonParseObject parseObj;
parseObj.parse(jsonstr);
map<string, vector<double>> resMap;
parseObj.read(resMap);
parseObj.clear();
}
int main(int argc, char* argv[])
{
double res = random(0, 1);
std::cout<< res <<std::endl;
// testJson();
while (true)
{
const char* uri = "host=192.168.19.100 port=5432 dbname=JinXian user=postgres password=admin";
const char* uri = "host=192.168.19.100 port=5432 dbname=JinXian3 user=postgres password=admin";
char* findUri = const_cast<char*>(uri);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
......@@ -81,6 +109,8 @@ int main(int argc, char* argv[])
break;
case 8: // 8 优化调度测试
context.setHydrTest(new CivOptSchedulingTest());
context.contextTest(findUri);
break;
default:
cout << "输入测试号错误!" << endl;
......
......@@ -17,8 +17,11 @@ double GenAlg::random(int min , int max)
double m1 = (double)(rand() % 101) / 101; // 计算 0,1之间的随机小数,得到的值域近似为(0,1)
min++; //将 区间变为(min+1,max),
double m2 = (double)((rand() % (max - min + 1)) + min); //计算 min+1,max 之间的随机整数,得到的值域为[min+1,max]
m2 = m2 - 1; //令值域为[min,max-1]
return m1 + m2; //返回值域为(min,max),为所求随机浮点
m2 = m2 - 1; //令值域为[min,max-1]
double dd = (m1 + m2) * 100;
double res = (int)dd;
return res /100; //返回值域为(min,max),为所求随机浮点
}
void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLength, double LeftPoint, double RightPoint)
......@@ -33,7 +36,7 @@ void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLength,
mBestFitness = 0.0;
mWorstFitness = 99999999;
mAverageFitness = 0;
mMaxPerturbation = 0.001;
mMaxPerturbation = 1;
mLeftPoint = LeftPoint;
mRightPoint = RightPoint;
......@@ -48,7 +51,7 @@ void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLength,
// 把所有的基因编码初始化为函数区间内的随机数。
for (int j = 0; j < mChromoLength; j++)
{
vecPop[i].vecGenome.push_back(random(0,MAX_RANDOM) * (mRightPoint - mLeftPoint) + mLeftPoint);
vecPop[i].vecGenome.push_back(random(0,1) * (mRightPoint - mLeftPoint) + mLeftPoint);
}
}
}
......@@ -62,7 +65,7 @@ void GenAlg::mutate(vector<double>& chromo)
if (random(0,1) < mMutationRate)
{
// 使该权值增加或者减少一个很小的随机数值
chromo[i] += ((random() - 0.05) * mMaxPerturbation);
chromo[i] += ((random(0,1) - 0.2) * mMaxPerturbation);
// 左右边界
if (chromo[i] < mLeftPoint)
......@@ -79,28 +82,11 @@ void GenAlg::mutate(vector<double>& chromo)
void GenAlg::select(vector<Genome>& genVec)
{
// 产生一个 0 到种群总适应性评分总和之间的随机数. mTotalFitness记录了整个种群的适应性分数总和
double slice = (random(0, 1)) * mTotalFitness;
// 这个基因将承载转盘所选出来的那个个体.
Genome theChosenOne;
// 累计适应性分数的和.
double fitnessSoFar = 0;
// 遍历总种群里面的每一条染色体。
for (int i = 0; i < mPopSize; ++i)
while (genVec.size() < mPopSize)
{
//累计适应性分数.
fitnessSoFar += vecPop[i].fitness;
// 如果累计分数大于随机数,就选择此时的基因.
if (fitnessSoFar >= slice)
{
theChosenOne = vecPop[i];
genVec.push_back(theChosenOne);
continue;
}
Genome genMe = chromoRoulette();
if (genMe.vecGenome.size() > 0)
genVec.push_back(genMe);
}
}
......@@ -114,10 +100,11 @@ Genome GenAlg::chromoRoulette()
// 累计适应性分数的和.
double fitnessSoFar = 0;
// 遍历总种群里面的每一条染色体。
for (int i = 0; i < mPopSize; ++i)
{
//累计适应性分数.
fitnessSoFar += vecPop[i].fitness;
......@@ -144,11 +131,17 @@ void GenAlg::calculateBestWorstAvTot()
// 查找最好适应度值
if (mBestFitness < fitNessTemp)
{
mBestGenoMe = vecPop[i];
mBestFitness = fitNessTemp;
}
// 查找最差适应度值
if (mWorstFitness > fitNessTemp)
{
mWorthGenoMe = vecPop[i];
mWorstFitness = fitNessTemp;
}
}
// 计算平均适应度
......@@ -183,22 +176,28 @@ void GenAlg::epoch(vector<Genome>& vecNewPop)
// 根据个体自适应度进行选择
select(vecNewPop);
}
Genome GenAlg::bestFitness()
{
int maxIndex = -1;
for (int i = 0; i < vecPop.size(); i++)
vector<Genome> son;
crossover(vecNewPop, son);
// 基因变异
size_t sonTotal = son.size();
for (int i = 0; i < sonTotal; i++)
{
if (mBestFitness == vecPop[i].fitness)
maxIndex = i;
mutate(son[i].vecGenome);
}
// 没找到构造一个空的基因型对象
if (maxIndex == -1)
return Genome();
// 更新种群
vecPop.clear();
vecPop = son;
return vecPop[maxIndex];
vecNewPop.clear();
vecNewPop = son;
}
Genome GenAlg::bestFitness()
{
return mBestGenoMe;
}
double GenAlg::averageFitness()
......@@ -223,7 +222,7 @@ void GenAlg::decoding(vector<map<string, float>>& genVals)
size_t genSize = genomeValsVec.size();
map<string, float> genMap;
for (int j = 0; j < genSize; i++)
for (int j = 0; j < genSize; j++)
{
genMap.insert(pair<string,float>(mPumpVec[j], genomeValsVec[j]));
}
......@@ -258,12 +257,16 @@ void GenAlg::crossover(const vector<Genome>& parent, vector<Genome>& son)
int indexLeft = randIndexVec[left];
int indexRight = randIndexVec[right];
Genome genome = crossover(parent[indexLeft], parent[indexRight]);
son.push_back(genome);
Genome genome1 = crossover(parent[indexLeft], parent[indexRight]);
Genome genome2 = crossover(parent[indexRight], parent[indexLeft]);
son.push_back(genome1);
son.push_back(genome2);
left++;
right--;
}
if (left == right)
son.push_back(parent[left]);
}
Genome GenAlg::crossover(const Genome& gen1, const Genome& gen2)
......@@ -277,10 +280,16 @@ Genome GenAlg::crossover(const Genome& gen1, const Genome& gen2)
return geoMe;
size_t genSize = genVec1.size();
double a = 0.15;
for (int i = 0; i < genSize; i++)
{
double newGenVal = genVec1[i] + a * (genVec1[i] - genVec2[i]);
double aa = random(0, 1);
double newGenVal = genVec1[i]*aa +(1- aa) * genVec2[i];
if (newGenVal < mLeftPoint)
newGenVal = mRightPoint;
if (newGenVal > mRightPoint)
newGenVal = mLeftPoint;
geoMe.vecGenome.push_back(newGenVal);
}
......
......@@ -77,16 +77,25 @@ public:
* @param [fitNess] 个体适应度
*/
void updateGenomeFitNess(int index, double fitNess);
void setPumpVec(const vector<string>& pumpVec) { mPumpVec = pumpVec; }
private:
// 产生[a,b)之间的浮点数
double random(int a=0, int b= RAND_MAX);
// 交叉重组,产生新的个体
Genome crossover(const Genome& gen1, const Genome& gen2);
private:
// 这个容器将储存每一个个体的染色体
// 当前种群
vector <Genome> vecPop;
// 下一代种群
vector<Genome> nextPopulation;
// 中间代种群
vector<Genome> midPopulation;
// 种群数量
int mPopSize;
......@@ -99,6 +108,11 @@ private:
// 在所有个体当中最适应的个体的适应性评分
double mBestFitness;
// 记录最有个体基因值
Genome mBestGenoMe;
Genome mWorthGenoMe;
// 所有个体的适应性评分的平均值
double mAverageFitness;
......@@ -109,10 +123,10 @@ private:
Genome mFittestGenome;
// 基因突变的概率,一般介于0.05和0.3之间
double mMutationRate;
double mMutationRate = 0.2;
// 基因交叉的概率一般设为0.7
double mCrossoverRate;
double mCrossoverRate = 0.7;
// 代数的记数器
int mGeneration;
......
......@@ -76,10 +76,10 @@ public:
protected:
// 惩罚因子1
double C1;
double C1 = 0.01;
// 惩罚因子2
double C2;
double C2 = 0.01;
// 设置的监测点的调度最大值
map<string, double> mMaxMonitorVals;
......
......@@ -138,21 +138,25 @@ bool CivHydrCompute::hdyrCompute()
if (errcode > 0)
{
CivSysLog::getInstance()->error("ENopen 失败", "CivHydrCompute", __FUNCTION__);
ENclose();
return false;
}
if (ENopenH() > 0)
{
CivSysLog::getInstance()->error("ENopenH 失败", "CivHydrCompute", __FUNCTION__);
ENclose();
return false;
}
if (ENinitH(0) > 0)
{
CivSysLog::getInstance()->error("ENinitH 失败", "CivHydrCompute", __FUNCTION__);
ENclose();
return false;
}
float dHStep;
ENGetVal(4, &dHStep);
do
......@@ -185,6 +189,7 @@ bool CivHydrCompute::hdyrCompute()
ENcloseH();
ENclose();
return true;
}
......
......@@ -28,6 +28,10 @@ public:
void saveResult(const std::string& uri);
void cacheCodeSn(const std::string& uri);
void setInpFile(const std::string& inpFile) { mInFile = inpFile; }
void setRptFile(const std::string& rptFile) { mRptFile = rptFile; }
void setBinFile(const std::string& binFile) { mBinFile = binFile; }
void getTrackingResult(const std::string& uri,std::string& jsonResult);
void getNodeItemByInterval(int time, NodeResultItems& nodeItem);
......
......@@ -5,21 +5,37 @@
#include "CivTrackingAnalysis.h"
#include "CivProjSimulation.h"
#include "JsonParseObject.h"
#include "CivOptSchedEngine.h"
bool PANDANALYSIS_API hdyrSimulation(char* uri)
{
std::string uriStr = uri;
if (uriStr.empty())
return false;
CivHydrSimulation simulation(uri);
return simulation.hdyrSimulation();
}
bool PANDANALYSIS_API qualitySimulation(char* uri)
{
std::string uriStr = uri;
if (uriStr.empty())
return false;
CivHydrSimulation simulation(uri);
return simulation.qualitySimulation();
}
bool PANDANALYSIS_API trackingSimulation(char* uri, char* sN, int hours, char* result)
{
std::string uriStr = uri;
std::string sNStr = sN;
if (uriStr.empty() || sNStr.empty())
return false;
CivHydrSimulation simulation(uri);
std::string res;
......@@ -33,8 +49,17 @@ bool PANDANALYSIS_API trackingSimulation(char* uri, char* sN, int hours, char* r
bool PANDANALYSIS_API upstreamTracking(char* uri, char* sn, char* result)
{
std::string uriStr = uri;
std::string snStr = sn;
if (uriStr.empty() || snStr.empty())
return false;
CivTrackingAnalysis track(uri);
track.createGraphFrom();
if (!track.createGraphFrom())
{
return false;
}
std::string jsonResult;
if (!track.upstreamTracking(sn, jsonResult))
......@@ -47,6 +72,12 @@ bool PANDANALYSIS_API upstreamTracking(char* uri, char* sn, char* result)
bool PANDANALYSIS_API downstreamTracking(char* uri, char* sn, char* result)
{
std::string uriStr = uri;
std::string snStr = sn;
if (uriStr.empty() || snStr.empty())
return false;
CivTrackingAnalysis track(uri);
track.createGraphFrom();
......@@ -66,6 +97,12 @@ bool PANDANALYSIS_API waterSupplyScopeAnalysis(char* uri, char* sn, char* result
bool PANDANALYSIS_API projSimulation(char* uri, char* projCode, char* time)
{
std::string uriStr = uri;
std::string projCodeStr = projCode;
if (uriStr.empty() || projCodeStr.empty())
return false;
CivProjSimulation projSimulation(uri);
if (!projSimulation.simulationProj(projCode, time))
......@@ -74,24 +111,58 @@ bool PANDANALYSIS_API projSimulation(char* uri, char* projCode, char* time)
return true;
}
bool PANDANALYSIS_API optimalSchedulingSimulation(char* uri, char* condition, char* timeInterval, char* result)
bool PANDANALYSIS_API optimalSchedulingSimulation(char* uri, char* condition, int timeInterval, char* result)
{
// 类型装换
string uriStr = uri;
string conditionStr = condition;
string timeStr = timeInterval;
if (uriStr.empty() || conditionStr.empty())
return false;
// 解析输入的字符串转换位对应容器数据
JsonParseObject jsonObj;
jsonObj.parse(conditionStr);
map<string, string> condiTionMap;
// 解析条件参数,监测点的最带和最小值的映射
map<string, vector<double>> condiTionMap;
jsonObj.read(condiTionMap);
// 清楚
jsonObj.clear();
jsonObj.parse(timeStr);
vector<string> monitorsVec;
map<string, vector<double>>::iterator iter = condiTionMap.begin();
map<string, double> maxMonitorVals;
map<string, double> minMonitorVals;
for (; iter != condiTionMap.end(); iter++)
{
string monitorSz = iter->first;
monitorsVec.push_back(monitorSz);
vector<double> monitorValVec = iter->second;
if (monitorValVec.size() < 2)
continue;
minMonitorVals.insert(pair<string, double>(monitorSz, monitorValVec[0]));
maxMonitorVals.insert(pair<string, double>(monitorSz, monitorValVec[1]));
}
// 优化调度客户端
CivOptSchedEngine schedEngine(uriStr);
schedEngine.setMonitors(monitorsVec);
schedEngine.setMaxMonitorVals(maxMonitorVals);
schedEngine.setMinMonitorVals(minMonitorVals);
schedEngine.setSchedulingPeriod(timeInterval);
if (!schedEngine.optimalScheduling(timeInterval))
return false;
std::string resultStr;
schedEngine.schedulingResultToJson(resultStr);
// 复制
strcpy(result, resultStr.c_str());
return true;
}
\ No newline at end of file
......@@ -68,7 +68,7 @@ extern "C" {
*@param [in] timeInterval:时段,格式:{"time":'1' }
*@param [out] result: 模拟的调度结果
*/
bool PANDANALYSIS_API optimalSchedulingSimulation(char* uri, char* condition, char* timeInterval, char* result);
bool PANDANALYSIS_API optimalSchedulingSimulation(char* uri, char* condition, int timeInterval, char* result);
#if defined(__cplusplus)
}
#endif
......
......@@ -20,6 +20,10 @@ bool CivHydrSimulation::hdyrSimulation()
return false;
mHydrCompute.cacheCodeSn(mUri);
mHydrCompute.setInpFile(inpFileS);
mHydrCompute.setRptFile("test.rpt");
mHydrCompute.setBinFile("test.bin");
if (!mHydrCompute.hdyrCompute())
{
return false;
......@@ -40,6 +44,11 @@ bool CivHydrSimulation::qualitySimulation()
// convertor.maintainTopo();
std::string inpFileS = convertor.convertBaseInp();
mHydrCompute.setInpFile(inpFileS);
mHydrCompute.setRptFile("test.rpt");
mHydrCompute.setBinFile("test.bin");
if (inpFileS.empty() || inpFileS == "")
{
CivSysLog::getInstance()->error("转inp文件失败", "CivSysLog", __FUNCTION__);
......@@ -60,6 +69,10 @@ bool CivHydrSimulation::qualitySimulation()
// 余氯计算
inpFileS = convertor.convertResidualInp();
mHydrCompute.setInpFile(inpFileS);
mHydrCompute.setRptFile("test.rpt");
mHydrCompute.setBinFile("test.bin");
if (inpFileS.empty() || inpFileS == "")
{
CivSysLog::getInstance()->error("转inp文件失败", "CivSysLog", __FUNCTION__);
......@@ -81,6 +94,10 @@ bool CivHydrSimulation::trackingSimulation(char* snNode, int hours,std::string&
CivInpConvertor convertor(mUri);
std::string inpFileS = convertor.convertTrackInp(snNode, std::to_string(hours));
mHydrCompute.setInpFile(inpFileS);
mHydrCompute.setRptFile("test.rpt");
mHydrCompute.setBinFile("test.bin");
if (inpFileS.empty())
return false;
......
......@@ -4,6 +4,7 @@
#include "CivBaseInpBuilder.h"
#include "CivCommonUtils.h"
#include "CivHydrTableHelper.h"
#include "CivSysLog.h"
CivInpConvertor::CivInpConvertor(const std::string& uri)
:mUri(uri)
......@@ -40,7 +41,7 @@ std::string CivInpConvertor::convertPorjInp(const std::string& projCode, const s
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\ptest.inp";
std::string inpFile = "ptest.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
......@@ -58,7 +59,7 @@ std::string CivInpConvertor::convertBaseInp()
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\test.inp";
std::string inpFile = "test.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
......@@ -86,7 +87,7 @@ std::string CivInpConvertor::convertTrackInp(const std::string& sn, const std::s
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\test.inp";
std::string inpFile = "test.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
......@@ -106,10 +107,11 @@ std::string CivInpConvertor::convertAnalysisInp()
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\test.inp";
std::string inpFile = "test.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
CivSysLog::getInstance()->error("ת" + inpFile + "ʧ", "CivInpConvertor", __FUNCTION__);
return "";
}
......@@ -128,7 +130,7 @@ std::string CivInpConvertor::convertResidualInp()
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\test.inp";
std::string inpFile = "test.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
......@@ -152,7 +154,7 @@ std::string CivInpConvertor::convertNotPorjInp(const std::string& simulTime)
director.setBuilder(builder);
director.create();
std::string inpFile = CivCommonUtils::getExePath() + "\\test.inp";
std::string inpFile = "test.inp";
if (!builder->getNewInp(inpFile))
{
delete builder;
......
......@@ -5,11 +5,14 @@
#include "CivPumpHelper.h"
#include "Genome.h"
#include "CivCommonUtils.h"
#include "CivSysLog.h"
#include "CivSchedulingCompute.h"
CivOptSchedEngine::CivOptSchedEngine(const string& uri)
:mUri(uri),mMutRate(0.45),mCrossRate(0.07), popsize(10)
{
// 初始化计算
}
bool CivOptSchedEngine::optimalScheduling(int time)
......@@ -23,31 +26,49 @@ bool CivOptSchedEngine::optimalScheduling(int time)
optScheduling->setMaxMonitorVals(mMaxMonitorVals);
GenAlg genAlg(optScheduling);
genAlg.setPumpVec(mPumpVec);
// 种群初始化
popsize = 10;
popsize = 20;
genAlg.init(popsize, mMutRate, mCrossRate, mGenLength, 0, 1);
// 开始迭代计算
int index = 0;
// 迭代次数
int generation = 20;
int generation = 100;
mSchedulingCompute->clearLastVals();
while (index++ < generation)
{
string infoLog = "第" + to_string(index) + "迭代训练开始";
CivSysLog::getInstance()->info(infoLog, "CivOptSchedEngine", __FUNCTION__);
// 管网平差计算
vector<map<string, float>> monitorsMap;
genAlg.decoding(monitorsMap);
if (index >1)
{
double gg = 0.9;
}
vector<map<string, float>> pumpSpeedMapVec;
genAlg.decoding(pumpSpeedMapVec);
// 计算种群个体的每个
size_t mSize = monitorsMap.size();
size_t mSize = pumpSpeedMapVec.size();
for (int i = 0; i < mSize; i++)
{
mSchedulingCompute->updatePumpSpeed(monitorsMap[i]);
map<string, float> pumpSpeedMap = pumpSpeedMapVec[i];
mSchedulingCompute->updatePumpSpeed(pumpSpeedMap);
if (!mSchedulingCompute->calculate())
continue;
map<string, float>::const_iterator const_iter = pumpSpeedMap.cbegin();
string logStr = "第" + to_string(i) + "个体:";
for (; const_iter != pumpSpeedMap.cend(); const_iter++)
{
logStr.append(const_iter->first + ":" + to_string(const_iter->second)+" ");
}
// 获取计算的监测点的值
map<string, double> monitorCalcMapValues;
mSchedulingCompute->getMonitorsValue(mPeriod, monitorCalcMapValues);
......@@ -58,43 +79,72 @@ bool CivOptSchedEngine::optimalScheduling(int time)
// 计算个体自适度
double fitness = genAlg.fitnessfunction(cost, monitorCalcMapValues);
if (fitness > 1)
fitness = 0;
logStr.append(" 适应度值:" + to_string(fitness));
CivSysLog::getInstance()->info(logStr, "CivOptSchedEngine", __FUNCTION__);
// 更新个体的自适应度
genAlg.updateGenomeFitNess(i, fitness);
mSchedulingCompute->clearLastVals();
}
//
// genAlg.mutate()
// 产生下一代种群
std::vector<Genome> newGenmeVec;
genAlg.epoch(newGenmeVec);
}
// 获取最好的
genAlg.calculateBestWorstAvTot();
Genome genome = genAlg.bestFitness();
vector<double> genVec = genome.vecGenome;
map<string, float> genMap;
for (int i = 0; i < mMonitorsVec.size(); i++)
genMap.insert(pair<string, double>(mMonitorsVec[i], genVec[i]));
//
size_t totalGenVec = genVec.size();
size_t pumpSize = mPumpVec.size();
if (totalGenVec != pumpSize)
{
CivSysLog::getInstance()->error("水泵个数与计算的属性值不匹配", "CivOptSchedEngine", __FUNCTION__);
return false;
}
// 水泵,
string infoStr = "最优水泵组合值:";
for (int i = 0; i < totalGenVec; i++)
{
infoStr.append(mPumpVec[i] +":" + to_string(genVec[i]));
mPumpBestSpeed.insert(pair<string, double>(mPumpVec[i], genVec[i]));
}
CivSysLog::getInstance()->error(infoStr, "CivOptSchedEngine", __FUNCTION__);
mSchedulingCompute->clearLastVals();
// 再做一次水力计算,计算调度后的值
mSchedulingCompute->updatePumpSpeed(genMap);
mSchedulingCompute->calculate();
mSchedulingCompute->updatePumpSpeed(mPumpBestSpeed);
if (!mSchedulingCompute->calculate())
return false;
// 最调度值
// 最调度值
mSchedulingCompute->getMonitorsValue(mPeriod,mAfterSchedulingResults);
// 结束计算
endCompute();
return true;
}
void CivOptSchedEngine::serializeToInpFile(string& inpName)
{
}
void CivOptSchedEngine::schedulingResultToJson(string& json)
{
// 水泵:组合
json.append("{\"水泵状态\":{");
map<string, int>::iterator iter = mPumpBestStatus.begin();
for (;iter!=mPumpBestStatus.end();iter++)
map<string, float>::iterator iter = mPumpBestSpeed.begin();
for (;iter!= mPumpBestSpeed.end();iter++)
{
json.append(iter->first + ":" + to_string(iter->second));
json.append(",");
......@@ -103,36 +153,29 @@ void CivOptSchedEngine::schedulingResultToJson(string& json)
json.append("},");
// 调度组合
json.append("\"监测点:[\"");
int total = mBforeSchedulingResults.size();
for (int i = 0; i < total; i++)
{
map<string, double> beforeResult = mBforeSchedulingResults[i];
map<string, double> afterResult = mAfterSchedulingResults[i];
json.append("\"监测点:\"");
json.append("{");
for (auto iter = beforeResult.begin(); iter != beforeResult.end(); iter++)
{
string monitorName = iter->first;
double beforeMonitorVal = iter->second;
json.append("{");
for (auto iter = mBforeSchedulingResults.begin(); iter != mBforeSchedulingResults.end(); iter++)
{
string monitorName = iter->first;
double beforeMonitorVal = iter->second;
auto afteriter = afterResult.find(monitorName);
if (afteriter == afterResult.end())
continue;
auto afteriter = mAfterSchedulingResults.find(monitorName);
if (afteriter == mAfterSchedulingResults.end())
continue;
double afterMonitorvVal = afteriter->second;
double afterMonitorvVal = afteriter->second;
json.append("\""+monitorName+"\":[");
json.append(to_string(beforeMonitorVal));
json.append(",");
json.append(to_string(afterMonitorvVal));
json.append("],");
}
json = json.substr(0, json.length() - 1);
json.append("},");
json.append("\""+monitorName+"\":[");
json.append(to_string(beforeMonitorVal));
json.append(",");
json.append(to_string(afterMonitorvVal));
json.append("],");
}
json.substr(0, json.length() - 1);
json.append("]}");
json = json.substr(0, json.length() - 1);
json.append("}");
}
void CivOptSchedEngine::updateMonitorsVals(const map<string, double>& monitorVals)
......@@ -146,19 +189,8 @@ bool CivOptSchedEngine::beginCompute()
CivInpConvertor convertor(mUri);
string inpFile = convertor.convertBaseInp();
// 初始化计算
mSchedulingCompute = std::make_shared<CivSchedulingCompute>(CivSchedulingCompute::PumpScheduling);
// 构造水力计算对象
mSchedulingCompute->setMonitors(mMonitorsVec);
mSchedulingCompute->openFile(inpFile);
// 原始管网计算一次水力,保留调度前的水力计算结果
if (!mSchedulingCompute->calculate())
return false;
// 保存原始管网监测点的模拟值
mSchedulingCompute->getMonitorsValue(mPeriod,mBforeSchedulingResults);
// 获取水泵个数,根据水泵个数确定基因编码长度
CivPumpHelper pumpHelper(mUri);
......@@ -169,13 +201,32 @@ bool CivOptSchedEngine::beginCompute()
pumpHelper.getMap("本点号", "code", snToCodeMap);
// 获取本点号集合
vector<string> snVec;
pumpHelper.getPumpSn(snVec);
pumpHelper.getPumpSn(mPumpVec);
pumpHelper.getMonitors(mMonitorsVec);
/*string temp = "{";
for (int i = 0; i < mMonitorsVec.size(); i++)
{
temp.append("\\\"" + mMonitorsVec[i] + "\\\":{\\\"min\\\":20,\\\"max\\\":48},");
}
temp = temp.substr(0, temp.length() - 1);
temp.append("}");*/
// 构造水力计算对象
mSchedulingCompute->setMonitors(mMonitorsVec);
mSchedulingCompute->openFile(inpFile);
// 原始管网计算一次水力,保留调度前的水力计算结果
if (!mSchedulingCompute->calculate())
return false;
// 保存原始管网监测点的模拟值
mSchedulingCompute->getMonitorsValue(mPeriod, mBforeSchedulingResults);
}
void CivOptSchedEngine::endCompute()
{
mmSchedulingCompute->close();
mSchedulingCompute->close();
}
void CivOptSchedEngine::setMonitors(const vector<string>& monitor)
......
#pragma once
#include <string>
#include<memory>
#include <vector>
#include <map>
#include "CivSchedulingCompute.h"
using namespace std;
class CivSchedulingCompute;
/**
优化调度客户端
*/
......@@ -32,13 +32,27 @@ public:
*/
void setSchedulingPeriod(int time) { mPeriod = time; }
protected:
void setMinMonitorVals(const map<string, double>& monitorVals)
{ mMinMonitorVals = monitorVals; }
void setMaxMonitorVals(const map<string, double>& monitorVals)
{ mMaxMonitorVals = monitorVals; }
/**
*@brief 将计算结果转换为json字符串
*@param [out] json 输出结果的字符串
*/
void schedulingResultToJson(string& json);
/**
* @brief 序列化到inp文件
* @param [inpName] inp文件名
*/
void serializeToInpFile(string& inpName);
protected:
/**
*@brief 调度之前的一些初始化操作
*/
......@@ -54,10 +68,10 @@ private:
map<int, string> mStatusBit;
// 选出的最优组合
map<string, double> mPumpBestSpeed;
map<string, float> mPumpBestSpeed;
// 监测点编码
vector<string>& mMonitorsVec;
vector<string> mMonitorsVec;
// 实时计算的当前监测点的值
map<string,double> mCurrentMonitorVals;
......@@ -69,6 +83,9 @@ private:
map<string, double> mBforeSchedulingResults;
map<string, double> mAfterSchedulingResults;
// 水泵编号,索引位代表
vector<string> mPumpVec;
// 数据连接地址
string mUri;
......@@ -87,9 +104,11 @@ private:
//基因编码长度
int mGenLength;
std::shared_ptr< CivSchedulingCompute> mSchedulingCompute;
// 针对浮点数编码
double mLeftPoint;
double mRightPoint;
std::shared_ptr<CivSchedulingCompute> mSchedulingCompute;
};
......@@ -6,8 +6,8 @@
CivProjSimulation::CivProjSimulation(const std::string& uri):mUri(uri)
{
mRptFile = CivCommonUtils::getExePath() + "\\test.rpt";
mBinFile = CivCommonUtils::getExePath() + "\\test.bin";
mRptFile = "ptest.rpt";
mBinFile = "ptest.bin";
}
CivProjSimulation::~CivProjSimulation()
......
......@@ -38,67 +38,100 @@ bool CivSchedulingCompute::openFile(const string& inpFILE)
return false;
}
if (ENinitH(EN_SAVE) > 0)
{
CivSysLog::getInstance()->error("ENinitH 失败", "CivHydrCompute", __FUNCTION__);
ENclose();
return false;
}
return true;
}
bool CivSchedulingCompute::saveInpFile(char* inpFile)
{
int code = ENsaveinpfile(inpFile);
if (code > 0)
return false;
return true;
}
bool CivSchedulingCompute::calculate()
{
short hydCode = 1;
long t(0), tstep(0);
int iTime(0);
if (ENinitH(EN_SAVE) > 0)
{
CivSysLog::getInstance()->error("ENinitH 失败", "CivHydrCompute", __FUNCTION__);
ENclose();
return false;
}
float dHStep;
ENGetVal(4, &dHStep);
do
int nLinkCount;
ENgetcount(EN_LINKCOUNT, &nLinkCount);
for (int i = 1; i <= nLinkCount; i++)
{
int nLinkCount;
ENgetcount(EN_LINKCOUNT, &nLinkCount);
for (int i = 1; i <= nLinkCount; i++)
{
// 获取管段类型
int linkType;
ENgetlinktype(i, &linkType);
// 获取管段类型
int linkType;
ENgetlinktype(i, &linkType);
if (linkType != EN_PUMP || linkType != EN_PBV)
continue;
switch (linkType)
{
case EN_PUMP:
{
char id[128] = "";
ENgetlinkid(i, id);
switch (mChdulingType)
map<string, float>::iterator iter = mPumpSpeed.find(id);
if (iter != mPumpSpeed.end())
{
case PumpScheduling& EN_PUMP:
{
if (linkType != EN_PUMP)
continue;
char id[128] = "";
ENgetlinkid(i, id);
map<string,float>::iterator iter = mPumpSpeed.find(id);
if (iter == mPumpSpeed.end())
continue;
// 更新水泵的转速
ENsetlinkvalue(i, EN_STATUS, iter->second );
}
break;
case PBVScheduling& EN_PBV:
{
if (linkType != EN_PBV)
continue;
ENsetlinkvalue(i, EN_STATUS, iter->second);
}
break;
default:
break;
}
}
break;
case EN_PIPE:
case EN_PBV:
default:
break;
}
//if (linkType != EN_PUMP || linkType != EN_PBV)
// continue;
//switch (mChdulingType)
//{
//case PumpScheduling& EN_PUMP:
//{
// if (linkType != EN_PUMP)
// continue;
// char id[128] = "";
// ENgetlinkid(i, id);
// map<string,float>::iterator iter = mPumpSpeed.find(id);
// if (iter == mPumpSpeed.end())
// continue;
// // 更新水泵的转速
// ENsetlinkvalue(i, EN_STATUS, iter->second );
//}
// break;
//case PBVScheduling& EN_PBV:
//{
// if (linkType != EN_PBV)
// continue;
//}
// break;
//default:
// break;
//}
}
do
{
if (ENrunH(&t) > 100) // errcode > 100 是错误
{
......@@ -147,11 +180,15 @@ void CivSchedulingCompute::setMonitors(const vector<string>& monitor)
void CivSchedulingCompute::saveResult(int time)
{
// 计算节点
int nNodeCount;
ENgetcount(EN_NODECOUNT, &nNodeCount);
map<string, double> pressureMap;
mMonitorsValue.push_back(pressureMap);
for (int i = 1; i <= nNodeCount; i++)
{
char szNo[256];
......@@ -159,21 +196,23 @@ void CivSchedulingCompute::saveResult(int time)
// 判断是不是监测点
auto iter = std::find(mMonitors.begin(), mMonitors.end(), szNo);
if (iter == mMonitors.end())
continue;
if (iter != mMonitors.end())
{
float pressure;
ENgetnodevalue(i, EN_PRESSURE, &pressure); // 压力
float pressure;
ENgetnodevalue(i, EN_PRESSURE, &pressure); // 压力
pressureMap.insert(pair<string, double>(szNo, pressure));
mMonitorsValue[time].insert(pair<string, double>(szNo, pressure));
}
}
mMonitorsValue[time] = pressureMap;
}
void CivSchedulingCompute::getPumpEnergy(int time)
{
int nLinkCount;
ENgetcount(EN_LINKCOUNT, &nLinkCount);
map<string, float> energyMap;
mPumpEnergy.push_back(energyMap);
for (int i = 0; i < nLinkCount; i++)
{
// 获取管段类型
......@@ -189,7 +228,7 @@ void CivSchedulingCompute::getPumpEnergy(int time)
ENgetlinkvalue(i, EN_ENERGY, &energy);
// 存储每个时刻的消耗的能量
mPumpEnergy[time][szNo] = energy;
mPumpEnergy[time].insert(pair<string,float>(szNo, energy));
}
}
......@@ -209,6 +248,12 @@ float CivSchedulingCompute::totalEnergy(int index)
return totalEnergy;
}
void CivSchedulingCompute::clearLastVals()
{
mPumpEnergy.clear();
mMonitorsValue.clear();
}
void CivSchedulingCompute::updatePBVSettings(const string& sn, double pressure)
{
......
......@@ -29,6 +29,9 @@ public:
// 水力计算
bool calculate();
// 保存为inp文件
bool saveInpFile(char* inpFile);
// 结束计算,关闭文件句柄
void close();
......@@ -48,6 +51,9 @@ public:
// 获取每个时刻消耗的总能量
float totalEnergy(int index);
// 清除上一轮的值(很重要)
void clearLastVals();
private:
// 保存计算的值
void saveResult(int time);
......
......@@ -21,11 +21,23 @@ bool CivTrackingAnalysis::createGraphFrom()
CivInpConvertor convertor(mUri);
std::string inpFile = convertor.convertAnalysisInp();
if (inpFile.empty())
{
CivSysLog::getInstance()->info("构造图,转inp文件失败", "CivTrackingAnalysis", __FUNCTION__);
return false;
}
CivHydrCompute dyCompute;
dyCompute.setInpFile(inpFile);
dyCompute.setRptFile("test.rpt");
dyCompute.setBinFile("test.bin");
if (!dyCompute.hdyrCompute())
{
CivSysLog::getInstance()->info("构造图,水力计算失败", "CivTrackingAnalysis", __FUNCTION__);
return false;
}
NodeResultItems nodeItems;
LinkResultItems linkItems;
......@@ -124,7 +136,11 @@ bool CivTrackingAnalysis::transformJson(
// 管段
size_t pipesTotal = pipes.size();
if (pipesTotal <= 0)
{
CivSysLog::getInstance()->error("追踪管段数为0", "CivTrackingAnalysis", __FUNCTION__);
return false;
}
jsonResult.append("[");
......
......@@ -114,4 +114,22 @@ void CivPumpHelper::getPumpStations(vector<PumpStation>& stations)
station.pumps = iter->second;
stations.push_back(station);
}
}
void CivPumpHelper::getMonitors(vector<string>& monitors)
{
string sql = "select node.\"本点号\" from \"节点\" as node, \"压力监测点\" as ja where node.\"code\" = ja.\"节点id\"";
if (!mConn->execSql(sql))
return;
vector<map<string, string>> tempMapVec;
mConn->queryResult(tempMapVec);
for (int i = 0; i < tempMapVec.size(); i++)
{
map<string, string> tempMap = tempMapVec[i];
string szNo = tempMap.find("本点号")->second;
monitors.push_back(szNo);
}
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ public:
// 获取泵站
void getPumpStations(vector<PumpStation>& stations);
void getMonitors(vector<string>& monitors);
private:
CivConnection* mConn = nullptr;
......
#include "JsonParseObject.h"
#include "cJSON.h"
JsonParseObject::JsonParseObject()
{
......@@ -9,7 +8,6 @@ JsonParseObject::JsonParseObject()
JsonParseObject::~JsonParseObject()
{
cJSON_Delete(mResultJson);
}
bool JsonParseObject::getKeys(vector<string>& keys)
......@@ -29,6 +27,37 @@ void JsonParseObject::read(map<string, string>& resMap)
}
void JsonParseObject::read(map<string, vector<double>>& resMap)
{
if (!mResultJson)
return;
cJSON* parent = mResultJson->child;
if (!parent)
return;
while (parent)
{
string key = parent->string;
cJSON* child = parent->child;
if (child && child->next)
{
vector<double> minMaxValVec;
double minVal = child->valuedouble;
double maxVal = child->next->valuedouble;
minMaxValVec.push_back(minVal);
minMaxValVec.push_back(maxVal);
resMap.insert(pair<string, vector<double>>(key, minMaxValVec));
printf("key:%s, min: %f ,max: %f \n", key, minVal, maxVal);
}
parent = parent->next;
}
}
void JsonParseObject::clear()
{
cJSON_Delete(mResultJson);
......
......@@ -2,15 +2,14 @@
#include <string>
#include <vector>
#include <map>
#include "pandaLog.h"
using namespace std;
class cJSON;
/**
json解析对象
json解析对象
*/
class PANDALOG_API JsonParseObject
{
......@@ -24,6 +23,8 @@ public:
void read(map<string, string>& resMap);
void read(map<string, vector<double>>& resMap);
// 主动销毁已读取的数据
void clear();
private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment