You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
495 lines
11 KiB
495 lines
11 KiB
10 months ago
|
#include "stdafx.h"
|
||
|
#include "BranchTree.h"
|
||
|
#include<cmath>
|
||
|
#include<vector>
|
||
|
#include<queue>
|
||
|
#include<map>
|
||
|
#include<iostream>
|
||
|
#include<fstream>
|
||
|
#include<sstream>
|
||
|
using namespace std;
|
||
|
|
||
|
|
||
|
struct DSU{
|
||
|
int f[N];
|
||
|
void init(int cnt){
|
||
|
for(int i=1;i<=cnt;i++)f[i]=i;
|
||
|
}
|
||
|
int getrt(int x){
|
||
|
if(x!=f[x])return f[x]=getrt(f[x]);
|
||
|
return x;
|
||
|
}
|
||
|
inline void merge(int x,int y){
|
||
|
if(x!=f[x])x=getrt(x);
|
||
|
if(y!=f[y])y=getrt(y);
|
||
|
f[x]=y;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
struct Node{
|
||
|
int xs,turncnt;
|
||
|
double dis;
|
||
|
bool operator <(Node B)const{
|
||
|
//if(turncnt!=B.turncnt)return turncnt>B.turncnt;
|
||
|
return dis>B.dis;
|
||
|
}
|
||
|
Node(){
|
||
|
xs=0;dis=0;turncnt=0;
|
||
|
}
|
||
|
Node(int xs1,int turnc,double dis1){
|
||
|
xs=xs1;dis=dis1;turncnt=turnc;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//��������·�������ݽṹ��ÿ�����͵����������䵽һ��
|
||
|
struct Astar{
|
||
|
ClipSet * pclipSet; //ָ������
|
||
|
BranchTree *pbranchTree; //ָ����֧��
|
||
|
P points[MAXPointNum]; //������Ϣ�����������㣬��֧���Ͷ˵�
|
||
|
P start,goal,start_dir,goal_dir; //�����յ��Լ�����
|
||
|
int S,T; //�������յ��ı���
|
||
|
map<int, vector<int> >edge;
|
||
|
//�洢ÿ���㸽������ײ�������㣬�����ظ�����kdtree��bvh
|
||
|
map<P,pair<int,int> > nearClip; //��Ϊ�˵㴦���ֲܷ棬���Ա��Ƕ˵����ӵ�����������
|
||
|
|
||
|
int searchNum; //�������������ڵ���
|
||
|
int pre[MAXPointNum],vis[MAXPointNum]; //pre�洢һ��������һ���㣬vis�洢һ�����Ƿ��ʹ�
|
||
|
int st[MAXPointNum],block[MAXPointNum]; //st����ʱջ��block���ǵĵ㲻�ܱ�ͨ��
|
||
|
int pnum; //����������
|
||
|
int tnum; //�������
|
||
|
Path path; //·������
|
||
|
double bend_r,l; //�����뾶���ܳ���
|
||
|
Node dis[MAXPointNum]; //�洢������Ϣ
|
||
|
priority_queue<Node>pq; //���ȶ���
|
||
|
double preBranchPointPos[MAXPointNum]; //��ǰһ������1���ͣ�ͬ����������֧�㣬�洢������λ��
|
||
|
|
||
|
Astar(){
|
||
|
pnum=0;l=bend_r=0;tnum=0;
|
||
|
pclipSet=&clipSet;
|
||
|
}
|
||
|
|
||
|
void addBranchTree(BranchTree *pbranchTree){
|
||
|
this->pbranchTree=pbranchTree;
|
||
|
}
|
||
|
|
||
|
//��ʼ��
|
||
|
inline void init(){
|
||
|
pnum+=2;
|
||
|
}
|
||
|
|
||
|
//����һ��������
|
||
|
inline void add_clip(P &p,P &d){
|
||
|
pnum++;tnum++;
|
||
|
points[pnum]=p;
|
||
|
points[pnum].ref=pnum;
|
||
|
|
||
|
P dir=p-d;
|
||
|
points[pnum].dx=dir.x;
|
||
|
points[pnum].dy=dir.y;
|
||
|
points[pnum].dz=dir.z;
|
||
|
block[pnum]=0;
|
||
|
}
|
||
|
inline void add_clip(Clip& cp){
|
||
|
pnum++;tnum++;
|
||
|
points[pnum]=cp.coord;
|
||
|
block[pnum]=0;
|
||
|
}
|
||
|
|
||
|
//����һ����֧��
|
||
|
inline void add_branchPoint(BranchPoint& bp){
|
||
|
tnum=max(tnum,clipSet.clipnum+2);
|
||
|
tnum++;
|
||
|
points[tnum]=bp.coord;
|
||
|
block[tnum]=0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
inline double cost(P &p1,P &p2){
|
||
|
if(bvh.iscollect(p1,p2))return 1e9;
|
||
|
//return distan(p1,p2);
|
||
|
return angelAndLength(p1,p2);
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
inline Path search_pair(P &start,P &goal,P &start_dir,P &goal_dir,double dia){
|
||
|
this->start=start;
|
||
|
this->goal=goal;
|
||
|
this->start_dir=start_dir;
|
||
|
this->goal_dir=goal_dir;
|
||
|
path.dia=dia;
|
||
|
pnum-=2;
|
||
|
path.points.clear();
|
||
|
path.wirelist.clear();
|
||
|
path.dia=dia;
|
||
|
search();
|
||
|
return path;
|
||
|
}
|
||
|
inline Path search_pair(P &start,P &goal,double dia){
|
||
|
this->start=start;
|
||
|
this->goal=goal;
|
||
|
path.dia=dia;
|
||
|
|
||
|
pnum-=2;
|
||
|
path.points.clear();
|
||
|
path.wirelist.clear();
|
||
|
path.dia=dia;
|
||
|
search();
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
|
||
|
inline Path search_pair(Bund & bd){
|
||
|
this->start=bd.start;
|
||
|
this->goal=bd.goal;
|
||
|
pnum-=2;
|
||
|
path.points.clear();
|
||
|
path.inOut.clear();
|
||
|
path.wirelist=bd.wirenamelist;
|
||
|
path.dia=bd.dia;
|
||
|
tnum=max(tnum,clipSet.clipnum+2);
|
||
|
search();
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
inline void searchForPreProcess(){
|
||
|
while(!pq.empty())pq.pop();
|
||
|
points[++pnum]=start;
|
||
|
points[++pnum]=goal;
|
||
|
S=pnum-1;T=pnum;
|
||
|
|
||
|
for(int i=1;i<=2*tnum+2;i++)vis[i]=0,dis[i]=Node(i,1000,1e9),pre[i]=0;
|
||
|
|
||
|
|
||
|
dis[S*2]=Node(S*2,0,0);
|
||
|
|
||
|
assert(pre[2*S]==0);
|
||
|
|
||
|
pq.push(dis[S*2]);
|
||
|
vector<pair<int,int> > tempvec=basicEdge.getEXTNextPoint(points[T],pnum,1);
|
||
|
vector<pair<int,int> >pointsConnectedToGoal;
|
||
|
for(int i=0;i<tempvec.size();i++){
|
||
|
int xs=tempvec[i].first;
|
||
|
if(!bvh.iscollect(points[xs],points[T]))
|
||
|
pointsConnectedToGoal.push_back(tempvec[i]);
|
||
|
}
|
||
|
bool testflag=true;
|
||
|
while(!pq.empty()){
|
||
|
Node node=pq.top();
|
||
|
//cout<<pq.top().xs<<endl;
|
||
|
|
||
|
pq.pop();
|
||
|
while(vis[node.xs]&&!pq.empty())node=pq.top(),pq.pop();
|
||
|
|
||
|
vis[node.xs]=1;
|
||
|
|
||
|
|
||
|
|
||
|
int xs=node.xs;
|
||
|
int inOut=xs%2;
|
||
|
xs/=2;
|
||
|
|
||
|
pair<int,int> currentNode=make_pair(xs,inOut);
|
||
|
|
||
|
if(xs==T)break;
|
||
|
|
||
|
vector<pair<int,int> > vec;
|
||
|
if(xs!=S)vec=basicEdge.getNextPoint(xs,inOut,pnum);
|
||
|
else if(xs==S&&nearClip[points[xs]]!=make_pair(0,0))vec.push_back(nearClip[points[S]]);
|
||
|
else {
|
||
|
vec=basicEdge.getEXTNextPoint(points[S],pnum,0);
|
||
|
//cout<<vec.size()<<endl;
|
||
|
}
|
||
|
|
||
|
if(nearClip[points[T]]==make_pair(0,0)){
|
||
|
for(int i=0;i<pointsConnectedToGoal.size();i++){
|
||
|
if(pointsConnectedToGoal[i]==currentNode)
|
||
|
vec.push_back(make_pair(T,0));
|
||
|
}
|
||
|
}
|
||
|
else if(nearClip[points[T]]==currentNode)vec.push_back(make_pair(T,0));
|
||
|
|
||
|
for(int i=0;i<vec.size();i++){
|
||
|
int v=vec[i].first;
|
||
|
int mode=vec[i].second;
|
||
|
if(v<pnum-1)
|
||
|
{
|
||
|
//if(!(pclipSet->transitable(v,0,path.dia)))continue;
|
||
|
//if(block[v])continue;
|
||
|
;
|
||
|
|
||
|
}
|
||
|
//cout<<v<<endl;
|
||
|
if(v==xs)cout<<"v==xs "<<v<<endl;
|
||
|
/*
|
||
|
if(points[xs]==points[v]){
|
||
|
cout<<xs<<" "<<v<<endl;
|
||
|
cout<<points[xs].x<<" "<<points[xs].y<<" "<<points[xs].z<<endl;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
if(points[xs]==points[v])continue;
|
||
|
assert(xs!=v);
|
||
|
assert(points[xs]!=points[v]);
|
||
|
assert(v!=pnum-1);
|
||
|
//assert(pnum==2833);
|
||
|
assert(pre[2*(pnum-1)]==0);
|
||
|
assert(pre[2*(pnum-1)+1]==0);
|
||
|
|
||
|
double cst=distan(points[xs],points[v],inOut,mode);
|
||
|
if(points[xs].type==1||points[xs].type==2){
|
||
|
int bid=points[xs].ref;
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
cst=pb->computeWeight(points[v],mode,0);
|
||
|
}
|
||
|
if(points[v].type==1||points[v].type==2){
|
||
|
int bid=points[v].ref;
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
cst=pb->computeWeight(points[xs],inOut,1);
|
||
|
}
|
||
|
cst+=+dis[xs*2+inOut].dis;
|
||
|
|
||
|
if(dis[2*v+mode]<Node(2*v+mode,0,cst)){
|
||
|
dis[2*v+mode]=Node(2*v+mode,0,cst);
|
||
|
assert(v!=pnum-1);
|
||
|
pre[2*v+mode]=xs*2+inOut;
|
||
|
pq.push(dis[2*v+mode]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
int top=0;
|
||
|
int tag=T*2;
|
||
|
while(pre[tag]){
|
||
|
st[++top]=tag;
|
||
|
tag=pre[tag];
|
||
|
if(testflag)cout<<"nodeid "<<tag<<endl;
|
||
|
}
|
||
|
if(top){
|
||
|
st[++top]=S*2;
|
||
|
}
|
||
|
for(int i=top;i>0;i--){
|
||
|
int id=st[i];
|
||
|
if(top>2){
|
||
|
if(id/2!=S&&id/2!=T){
|
||
|
if(i==top-1)nearClip[points[S]]=make_pair(id/2,id%2);
|
||
|
if(i==2)nearClip[points[T]]=make_pair(id/2,id%2);
|
||
|
}
|
||
|
}
|
||
|
//if(i!=top&&i!=1)pclipSet->addwire(id,dia);
|
||
|
path.points.push_back(points[id/2]);
|
||
|
if(i!=top&&i!=1&&id/2<pnum)path.inOut.push_back(id%2);
|
||
|
else path.inOut.push_back(-1-id%2);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
inline void search(){
|
||
|
searchNum++;
|
||
|
cout<<"searchNum "<<searchNum<<endl;
|
||
|
|
||
|
while(!pq.empty())pq.pop();
|
||
|
points[++pnum]=start;
|
||
|
points[++pnum]=goal;
|
||
|
S=pnum-1;T=pnum;
|
||
|
|
||
|
for(int i=1;i<=2*tnum+2;i++)vis[i]=0,dis[i]=Node(i,1000,1e9),pre[i]=0;
|
||
|
|
||
|
|
||
|
dis[S*2]=Node(S*2,0,0);
|
||
|
|
||
|
assert(pre[2*S]==0);
|
||
|
|
||
|
pq.push(dis[S*2]);
|
||
|
vector<pair<int,int> > tempvec=basicEdge.getEXTNextPoint(points[T],pnum,1);
|
||
|
vector<pair<int,int> >pointsConnectedToGoal;
|
||
|
for(int i=0;i<tempvec.size();i++){
|
||
|
int xs=tempvec[i].first;
|
||
|
if(!bvh.iscollect(points[xs],points[T]))
|
||
|
pointsConnectedToGoal.push_back(tempvec[i]);
|
||
|
}
|
||
|
bool testflag=true;
|
||
|
int whilenum=0;
|
||
|
while(!pq.empty()){
|
||
|
Node node=pq.top();
|
||
|
//cout<<pq.top().xs<<endl;
|
||
|
whilenum++;
|
||
|
if(searchNum==105)cout<<"whilenum "<<whilenum<<endl;
|
||
|
|
||
|
pq.pop();
|
||
|
while(vis[node.xs]&&!pq.empty())node=pq.top(),pq.pop();
|
||
|
|
||
|
vis[node.xs]=1;
|
||
|
|
||
|
|
||
|
|
||
|
int xs=node.xs;
|
||
|
int inOut=xs%2;
|
||
|
xs/=2;
|
||
|
|
||
|
pair<int,int> currentNode=make_pair(xs,inOut);
|
||
|
|
||
|
if(xs==T)break;
|
||
|
|
||
|
vector<pair<int,int> > vec;
|
||
|
if(xs!=S)vec=basicEdge.getNextPoint(xs,inOut,pnum);
|
||
|
else if(xs==S&&nearClip[points[xs]]!=make_pair(0,0))vec.push_back(nearClip[points[S]]);
|
||
|
else {
|
||
|
vec=basicEdge.getEXTNextPoint(points[S],pnum,0);
|
||
|
//cout<<vec.size()<<endl;
|
||
|
}
|
||
|
|
||
|
if(nearClip[points[T]]==make_pair(0,0)){
|
||
|
for(int i=0;i<pointsConnectedToGoal.size();i++){
|
||
|
if(pointsConnectedToGoal[i]==currentNode)
|
||
|
vec.push_back(make_pair(T,0));
|
||
|
}
|
||
|
}
|
||
|
else if(nearClip[points[T]]==currentNode)vec.push_back(make_pair(T,0));
|
||
|
|
||
|
for(int i=0;i<vec.size();i++){
|
||
|
int v=vec[i].first;
|
||
|
int mode=vec[i].second;
|
||
|
if(v<pnum-1)
|
||
|
{
|
||
|
//if(!(pclipSet->transitable(v,0,path.dia)))continue;
|
||
|
//if(block[v])continue;
|
||
|
;
|
||
|
|
||
|
}
|
||
|
//cout<<v<<endl;
|
||
|
if(v==xs)cout<<"v==xs "<<v<<" "<<points[v].type<<endl;
|
||
|
|
||
|
if(vis[v*2+mode])continue;
|
||
|
/*
|
||
|
if(points[xs]==points[v]){
|
||
|
cout<<xs<<" "<<v<<endl;
|
||
|
cout<<points[xs].x<<" "<<points[xs].y<<" "<<points[xs].z<<endl;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
if(points[xs]==points[v])continue;
|
||
|
assert(xs!=v);
|
||
|
assert(points[xs]!=points[v]);
|
||
|
assert(v!=pnum-1);
|
||
|
//assert(pnum==2833);
|
||
|
assert(pre[2*(pnum-1)]==0);
|
||
|
assert(pre[2*(pnum-1)+1]==0);
|
||
|
|
||
|
double cst=distan(points[xs],points[v],inOut,mode);
|
||
|
|
||
|
bool updatePreBranchPoint=false;
|
||
|
bool updateNextBranchPoint=false;
|
||
|
double tempPos1=0,tempPos2=0;
|
||
|
if(points[xs].type==1||points[xs].type==2){
|
||
|
int bid=points[xs].ref;
|
||
|
if(inOut==0){
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
cst=(pb->Dis)/2;
|
||
|
}
|
||
|
else {
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
cst=pb->computeWeight(points[v],mode,0);
|
||
|
updatePreBranchPoint=true;
|
||
|
tempPos1=pb->t;
|
||
|
}
|
||
|
}
|
||
|
if(points[v].type==1||points[v].type==2){
|
||
|
int bid=points[v].ref;
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
if(mode==1){
|
||
|
|
||
|
cst=(pb->Dis)/2;
|
||
|
}
|
||
|
else {
|
||
|
cst=pb->computeWeight(points[xs],inOut,1);
|
||
|
updateNextBranchPoint=true;
|
||
|
tempPos2=pb->t;
|
||
|
}
|
||
|
}
|
||
|
cst+=dis[xs*2+inOut].dis;
|
||
|
|
||
|
if(dis[2*v+mode]<Node(2*v+mode,0,cst)){
|
||
|
if(updatePreBranchPoint){
|
||
|
this->preBranchPointPos[2*v+mode]=tempPos1;
|
||
|
}
|
||
|
if(updateNextBranchPoint){
|
||
|
int bid=points[v].ref;
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
pb->recordPos(0);
|
||
|
}
|
||
|
|
||
|
dis[2*v+mode]=Node(2*v+mode,0,cst);
|
||
|
assert(v!=pnum-1);
|
||
|
pre[2*v+mode]=xs*2+inOut;
|
||
|
pq.push(dis[2*v+mode]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
int top=0;
|
||
|
int tag=T*2;
|
||
|
while(pre[tag]){
|
||
|
st[++top]=tag;
|
||
|
tag=pre[tag];
|
||
|
if(testflag){
|
||
|
cout<<"nodeid "<<tag<<" ";
|
||
|
if(tag<(pnum-1)*2)
|
||
|
cout<<basicChannel.clipType(tag/2)<<endl;
|
||
|
else cout<<-1<<endl;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if(top){
|
||
|
st[++top]=S*2;
|
||
|
}
|
||
|
vector<double> prePos;
|
||
|
for(int i=top;i>0;i--){
|
||
|
int id=st[i];
|
||
|
if(top>2){
|
||
|
if(id/2!=S&&id/2!=T){
|
||
|
if(i==top-1)nearClip[points[S]]=make_pair(id/2,id%2);
|
||
|
if(i==2)nearClip[points[T]]=make_pair(id/2,id%2);
|
||
|
}
|
||
|
}
|
||
|
//if(i!=top&&i!=1)pclipSet->addwire(id,dia);
|
||
|
path.points.push_back(points[id/2]);
|
||
|
if(i!=top&&i!=1&&id/2<pnum)path.inOut.push_back(id%2);
|
||
|
else {
|
||
|
path.inOut.push_back(-1-id%2);
|
||
|
}
|
||
|
prePos.push_back(preBranchPointPos[id]);
|
||
|
}
|
||
|
for(int i=0;i<path.points.size();i++){
|
||
|
P &p=path.points[i];
|
||
|
if(p.type==1||p.type==2){
|
||
|
int mode=-1-path.inOut[i];
|
||
|
int bid=p.ref;
|
||
|
BranchPoint *pb=branchPointSet.getBranchPointPointer(bid);
|
||
|
pb->mode=mode;
|
||
|
if(mode==1){
|
||
|
pb->t=prePos[i+1];
|
||
|
pb->recordPos(1);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
}astar;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|