284 lines
8.6 KiB
C++
284 lines
8.6 KiB
C++
#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);
|
||
}
|
||
}
|
||
|
||
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();
|
||
|
||
// 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;
|
||
}else
|
||
{
|
||
std::cout<<"can not conver from BranchStruc to LineStru"<<std::endl;
|
||
}
|
||
branch->toID=cb->toID;
|
||
cb->dispose=true;
|
||
// break;
|
||
reduced=true;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|
||
|