cimforreduceloss/testHasttable/elementreduction.cpp

306 lines
9.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "elementreduction.h"
#include <iostream>
#include <QFile>
#include <QTextStream>
#include "element/commontype.h"
ElementReduction::ElementReduction(const QList<BranchStruc *> &branchList):branchList(branchList)
{
}
ElementReduction::~ElementReduction()
{
}
void ElementReduction::calibration(const QString &id,QHash<QString,BranchStruc *> &idToBranch,QHash<QString,QVector<BranchStruc *> > &linkage)
{
QString to=idToBranch[id]->toID;
if(linkage[to].length()==1)
{
idToBranch[id]->fromID.swap(idToBranch[id]->toID);
}
// LineStru *line=static_cast<LineStru *>(idToBranch[id]);
// if(0==static_cast<int>(line->length))
// {
// std::cout<<"is zeros"<<line->id.toStdString()<<std::endl;
// line->length=10;
// line->line->length=10;
// }
}
void ElementReduction::doIt(const QString& rootID)
{
QHash<QString,QVector<BranchStruc *> > linkage;//后面经过merge以后这个表就不能用了
//先记录元件之间的连接关系
QHash<QString,BranchStruc *> idToBranch;
foreach(BranchStruc* v,this->branchList)
{
idToBranch[v->id]=v;
linkage[v->fromID].push_back(v);
linkage[v->toID].push_back(v);
// std::cout<<v->fromID.toStdString()<<" "<<v->id.toStdString()<<" "<<v->toID.toStdString()<<std::endl;
}
QDomDocument root;
// QDomElement element=root.createElement(this->branchList.at(2)->id);
QDomElement element=root.createElement(rootID);
this->calibration(rootID,idToBranch,linkage);
std::cout<<"start "<<rootID.toStdString()<<std::endl;
root.appendChild(element);
this->buildTreeTo(element,root,linkage,idToBranch);
// this->visited.remove(this->branchList.at(2)->id);
// this->buildTreeFrom(element,root,linkage,idToBranch);
this->merge(element,idToBranch);
this->reduceSection();
//因为有线路合并,线路长度变了,所以要重新计算参数
foreach(BranchStruc* v,this->branchList)
{
LineStru *line=static_cast<LineStru*>(v);
if(line!=NULL)
{
line->line->re_extract();
}
}
// QFile file("1.xml");
// if(file.open(QFile::WriteOnly))
// {
// QTextStream writer(&file);
// root.save(writer,4);
// file.close();
// }
//看看是不是每个都访问到了
foreach(BranchStruc* v,this->branchList)
{
if(!this->visited.contains(v->id))
{
std::cout<<"unvisited "<<v->id.toStdString()<<std::endl;
}
}
//合并
//从新给连接关系编号
}
void ElementReduction::merge(QDomElement &element,QHash<QString,BranchStruc *>& idToBranch)
{
// return;
QString parentID=idToBranch[element.tagName()]->id;
QStringList sep=parentID.split('-');
QString toID;
if(sep.length()>1)
{
toID=sep.at(1)+sep.at(0);
}
else
{
toID=sep.at(0)+"_"+sep.at(0);
}
idToBranch[element.tagName()]->toID=toID;
element.setAttribute("toID",toID);
//顺便编号
//采用广度优先
bool merged=true;
while(merged)
{
merged=false;
QDomNodeList list=element.childNodes();
int length=list.length();
for(int i=0;i<length;i++)
{
QDomNode nod=list.at(i);
QDomElement &node=(QDomElement &)nod;
QString id;
id=node.nodeName();
BranchStruc *branch=idToBranch[id];
branch->fromID=toID;
node.setAttribute("fromID",toID);
if(branch->isZeroBranch)
{
branch->dispose=true;
while(node.childNodes().length()>0)
{
// std::cout<<"append "<<node.firstChild().nodeName().toStdString()<<" to "<<element.tagName().toStdString()<<std::endl;
element.appendChild(node.removeChild(node.firstChild()));
}
element.removeChild(node);
merged=true;
break;
}
}
}
QDomNodeList list=element.childNodes();
for(int i=0;i<list.length();i++)
{
QDomNode nod=list.at(i);
QDomElement &node=(QDomElement &)nod;
this->merge((QDomElement &)node,idToBranch);
}
}
void ElementReduction::buildTreeTo(QDomElement &element,QDomDocument &root,QHash<QString,QVector<BranchStruc *> >& linkage,QHash<QString,BranchStruc *>& idToBranch)
{
QString id=element.tagName();
if(this->visited.contains(id))
{
// std::cout<<"visited "<<branch->id.toStdString()<<std::endl;
return;
}
this->visited[id]=0;
BranchStruc * branch=idToBranch[id];
QString nextTo;
nextTo=branch->toID;
QVector<BranchStruc *> nextVec;
nextVec=linkage[nextTo];
// std::cout<<nextVec.length()<<" of "<<element.tagName().toStdString()<<std::endl;
foreach(BranchStruc *n,nextVec)
{
if(this->visited.contains(n->id))
{
continue;
}
// std::cout<<element.tagName().toStdString()<<"to can connect to "<<n->id.toStdString()<<std::endl;
// std::cout<<"add "<<n->id.toStdString()<<std::endl;
QDomElement newEle=root.createElement(n->id);
// std::cout<<"create "<<n->id.toStdString()<<std::endl;
element.appendChild(newEle);
this->buildTreeTo(newEle,root,linkage,idToBranch);
}
}
void ElementReduction::buildTreeFrom(QDomElement &element,QDomDocument &root,QHash<QString,QVector<BranchStruc *> >& linkage,QHash<QString,BranchStruc *>& idToBranch)
{
QString id=element.tagName();
if(this->visited.contains(id))
{
std::cout<<"visited "<<id.toStdString()<<std::endl;
return;
}
this->visited[id]=0;
BranchStruc * branch=idToBranch[id];
QString nextFrom=branch->fromID;
QVector<BranchStruc *> nextFromVec;
nextFromVec=linkage[nextFrom];
foreach(BranchStruc *n,nextFromVec)
{
if(this->visited.contains(n->id))
{
continue;
}
std::cout<<element.tagName().toStdString()<<"from can connect to "<<n->id.toStdString()<<std::endl;
// std::cout<<"add "<<n->id.toStdString()<<std::endl;
QDomElement newEle=root.createElement(n->id);
// std::cout<<"create "<<n->id.toStdString()<<std::endl;
element.appendChild(newEle);
this->buildTreeFrom(newEle,root,linkage,idToBranch);
}
}
void ElementReduction::reduceSection()
{
const QList<BranchStruc *> &branchList=this->branchList;
QHash<QString,QVector<BranchStruc *> > linkage;
foreach(BranchStruc* v,branchList)
{
linkage[v->fromID].push_back(v);
linkage[v->toID].push_back(v);
// std::cout<<v->fromID.toStdString()<<" "<<v->id.toStdString()<<" "<<v->toID.toStdString()<<std::endl;
}
bool reduced=true;
while(reduced)
{
reduced=false;
foreach(BranchStruc *branch,branchList)
{
if(branch->dispose || branch->type=="TF"||branch->type=="DG")
{
continue;
}
// std::cout<<"length "<<branch->length<<" id "<<branch->id.toStdString()<<std::endl;
QString toID=branch->toID;
//先找一下没有dispose的
QVector<BranchStruc *> noDispose;
// if(linkage[toID].length()==1)//自己就是末端了
// {
// branch->dispose=true;
// continue;
// }
// std::cout<<"a "<<linkage[toID].length()<<" "<<toID.toStdString()<<std::endl;
bool ignore=false;
foreach(BranchStruc *childBranch,linkage[toID])
{
if(childBranch==branch)
{
continue;
}
if(!childBranch->dispose && (childBranch->type=="TF"||childBranch->type=="DG" ) )
{
ignore=true;//只要下面接了TF就不删掉
break;
}
if(!childBranch->dispose)
{
noDispose.push_back(childBranch);
}
}
if(ignore)
{
continue;
}
// std::cout<<noDispose.length()<<std::endl;
if(noDispose.length()==0)//自己就是末端了
{
branch->dispose=true;
continue;
}
if(noDispose.length()==1)
{
BranchStruc *cb=noDispose.first();
// std::cout<<branch->id.toStdString() <<"m with"<<cb->id.toStdString()<< ",add length"<<cb->length<<std::endl;
branch->length+=cb->length;
LineStru *lineBranch=static_cast<LineStru *>(branch);
if(lineBranch)
{
lineBranch->line->length=branch->length;
lineBranch->line->ac->setLength(branch->length);//TODO:线路的这个长度还是要统一一下,否则很容易出错。
}else
{
std::cout<<"can not conver from BranchStruc to LineStru"<<std::endl;
}
branch->toID=cb->toID;
cb->dispose=true;
// break;
reduced=true;
}
}
}
}