算法导论problem 24-5 Gabow's algorithm for single source shortest path

来源:互联网 发布:网络购物系统 编辑:程序博客网 时间:2024/06/05 08:29

源码:有部分测试用没删除。

/* target : Gabow's scaling algorithm for single-source shortest paths 
 * description : running time O(E*lgW):this programme is a fast realization of
 * single-source shortest path algorithm
 * the weight of edge must greater than 0,and with in the scope 000001 ~ 111111,must be the unsigned integer 
 */
 #include <stdio.h>
 #include <malloc.h>


 #define Edge_num   10
 #define Vertex_num 5
 #define Bit_number 6
 #define temp_weight preserve 


 #define oooooo 63
 #define oooooz 62 
 #define oooozz 60 
 #define ooozzz 56
 #define oozzzz 48 
 #define ozzzzz 32


 #define intmax -1
 #define white  0
 #define red    1
 #define black  2


struct Vertex{
int d;             //indicate the corrent distance form start point to this vertex
int identify;   //present the id of vertex


int color;   //behalf one property of vertex
struct Edge_list *edges;  //all adjacency edge list 
struct Vertex *p;


//int topo_order;   used for topological sort,here we comment it
int d_new;      //preserve for 
};


struct Edge{
struct Vertex *s;
struct Vertex *d;
    int weight;




    int preserve;
};


struct Vertex_list{
struct Vertex *cv;
struct Vertex_list *next;
struct Vertex_list *prev;
};


struct Edge_list{
struct Edge *ce;
struct Edge_list *next;
};


struct Graph{
int Edge_n,Vertex_n;
struct Vertex_list *All_V;
struct Edge_list *All_E;
};


#define for_each_vertex_listV(G,pos) \
for(pos=G->All_V;pos!=NULL;pos=pos->next) 


#define for_each_edge_listE(G,pos) \
for(pos=G->All_E;pos!=NULL;pos=pos->next)


#define NEW_EDGE_LIST(name)\
struct Edge_list *name = (struct Edge_list *)malloc(sizeof(struct Edge_list))
#define NEW_VERTEX_LIST_P \
(struct Vertex_list *)malloc(sizeof(struct Vertex_list))


#define NEW_VERTEX_P\
(struct Vertex*)malloc(sizeof(struct Vertex))


inline void init_vertex_(struct Vertex *v,int a,int b,int c,struct Edge_list *d,struct Vertex *e,int f){
v->d=a;
v->identify=b;
v->color=c;
v->edges=d;
v->p=e;
v->d_new=f;
}
#define init_vertex(v,a,b,c,d,e,f) do{\
(v)->d=(a);          \
(v)->identify=(b);   \
(v)->color=(c);      \
(v)->edges=(d);      \
(v)->p=(e);          \
(v)->d_new=(f);      \
}while(0)


inline void init_edge_(struct Edge *e,struct Vertex *a,struct Vertex *b,int c,int d){
e->s=a;
e->d=b;
e->weight=c;
e->preserve=d;
}
#define init_edge(e,a,b,c,d) do{\
(e)->s=(a); \
(e)->d=(b); \
(e)->weight=(c);\
(e)->preserve=(d);\
}while(0)


#define init_edge_list(el,a,b) do{\
(el)->ce=(a); \
(el)->next=(b);\
}while(0)
void IPH_FULL_SSSP(struct Graph *G);
void IPH_SELevel_SSSP(struct Graph *G);
void IPH_DFS(struct Vertex_list *ddv[Edge_num],struct Vertex_list *y,int distance);


int main()
{
int a1[Vertex_num];
struct Graph IPH_G;
IPH_G.Edge_n=Edge_num;
IPH_G.Vertex_n=Vertex_num;


struct Vertex      IPH_V[Vertex_num];
struct Vertex_list IPH_VL[Vertex_num];
struct Edge        IPH_E[Edge_num];

//vertex initialization part 
int i=0;
for(i=0;i<Vertex_num;i++)
IPH_VL[i].cv=&IPH_V[i];
IPH_VL[0].next=&IPH_VL[1];
IPH_VL[0].prev=NULL;
IPH_VL[1].next=&IPH_VL[2];
IPH_VL[1].prev=&IPH_VL[0];
IPH_VL[2].next=&IPH_VL[3];
IPH_VL[2].prev=&IPH_VL[1];
IPH_VL[3].next=&IPH_VL[4];
IPH_VL[3].prev=&IPH_VL[2];
IPH_VL[4].next=NULL;
IPH_VL[4].prev=&IPH_VL[3];
//IPH_G.ALL_V=&IPH_VL[0];


//vertex initialization part
init_edge_(&IPH_E[0],&IPH_V[0],&IPH_V[1],10,-1);
init_edge_(&IPH_E[1],&IPH_V[1],&IPH_V[2],1 ,-1);
init_edge_(&IPH_E[2],&IPH_V[3],&IPH_V[2],6 ,-1);
init_edge_(&IPH_E[3],&IPH_V[2],&IPH_V[3],4 ,-1);
init_edge_(&IPH_E[4],&IPH_V[4],&IPH_V[2],9 ,-1);
init_edge_(&IPH_E[5],&IPH_V[3],&IPH_V[0],7 ,-1);
init_edge_(&IPH_E[6],&IPH_V[4],&IPH_V[3],2 ,-1);
init_edge_(&IPH_E[7],&IPH_V[4],&IPH_V[1],3 ,-1);
init_edge_(&IPH_E[8],&IPH_V[1],&IPH_V[4],2 ,-1);
init_edge_(&IPH_E[9],&IPH_V[0],&IPH_V[4],5 ,-1);
NEW_EDGE_LIST(el0);
NEW_EDGE_LIST(el1);
NEW_EDGE_LIST(el2);
NEW_EDGE_LIST(el3);
NEW_EDGE_LIST(el4);
NEW_EDGE_LIST(el5);
NEW_EDGE_LIST(el6);
    NEW_EDGE_LIST(el7);
NEW_EDGE_LIST(el8);
NEW_EDGE_LIST(el9);
init_edge_list(el0,&IPH_E[0],el9); //all edge_list of vertex 0 el0->el9->NULL
init_edge_list(el1,&IPH_E[1],el8); //all edge_list of vertex 1 el1->el8->NULL
init_edge_list(el2,&IPH_E[2],el5); //all edge_list of vertex 3 el2->el5->NULL
init_edge_list(el3,&IPH_E[3],NULL);//all edge_list of vertex 2 el3->NULL
init_edge_list(el4,&IPH_E[4],el6); //all edge_list of vertex 4 el4->el6->el7 
init_edge_list(el5,&IPH_E[5],NULL);
init_edge_list(el6,&IPH_E[6],el7);
init_edge_list(el7,&IPH_E[7],NULL);
init_edge_list(el8,&IPH_E[8],NULL);
init_edge_list(el9,&IPH_E[9],NULL);


NEW_EDGE_LIST(alle0);
NEW_EDGE_LIST(alle1);
NEW_EDGE_LIST(alle2);
NEW_EDGE_LIST(alle3);
NEW_EDGE_LIST(alle4);
NEW_EDGE_LIST(alle5);
NEW_EDGE_LIST(alle6);
NEW_EDGE_LIST(alle7);
NEW_EDGE_LIST(alle8);
NEW_EDGE_LIST(alle9);
init_edge_list(alle0,&IPH_E[0],alle1);
init_edge_list(alle1,&IPH_E[1],alle2);
init_edge_list(alle2,&IPH_E[2],alle3);
init_edge_list(alle3,&IPH_E[3],alle4);
init_edge_list(alle4,&IPH_E[4],alle5);
init_edge_list(alle5,&IPH_E[5],alle6);
init_edge_list(alle6,&IPH_E[6],alle7);
init_edge_list(alle7,&IPH_E[7],alle8);
init_edge_list(alle8,&IPH_E[8],alle9);
init_edge_list(alle9,&IPH_E[9],NULL );


//问题:对节点的初始赋值为-1 可能会引起问题
init_vertex_(&IPH_V[0],0,0,white,el0 ,NULL,-1);
init_vertex_(&IPH_V[1],0,1,white,el1 ,NULL,-1);
init_vertex_(&IPH_V[2],0,2,white,el3 ,NULL,-1);
init_vertex_(&IPH_V[3],0,3,white,el2 ,NULL,-1);
init_vertex_(&IPH_V[4],0,4,white,el4 ,NULL,-1);


IPH_G.All_V=&IPH_VL[0];
IPH_G.All_E=alle0;
IPH_FULL_SSSP(&IPH_G);


struct Vertex_list *temp;
for_each_vertex_listV((&IPH_G),temp){
printf("vertex %d 's d=%d parent is %d\n",temp->cv->identify,temp->cv->d,(temp->cv->p==NULL)? 0:temp->cv->p->identify);
}
return 0;
}




/*this function fist delete vertex from ddv 
* then access each adjacent edge of vertex y->cv 
* then move its adjacent vertex to suitable position in ddv
*/
//问题1:当y 等于初始节点时,可能会出现的bug
//问题2:
void IPH_DFS(struct Vertex_list *ddv[Edge_num],struct Vertex_list *y,int distance)
{
puts("IPH_DFS was called");
//fisrt we delete a vertex_list from ddv[distance]
y->cv->color==black;
ddv[distance]=ddv[distance]->next;
if(ddv[distance]!=NULL)
ddv[distance]->prev=NULL;


//then we iterater each vertex_list in the ddv[distance]
struct Edge_list *temp;
struct Vertex_list *temp1;
struct Vertex_list *tempV;
for(temp=y->cv->edges;temp!=NULL;temp=temp->next){//for each adjacent edge of vertex y->cv
if(temp->ce->d->color!=black){// make sure all the interviewed vertex is not be changed 
puts("all_we_start");
if(temp->ce->d->d_new==-1){// when this vertex temp->d is fisrt accessed 
  puts("newly interviewd vertex");
temp1=NEW_VERTEX_LIST_P;
temp1->cv=temp->ce->d;
temp1->cv->d_new=distance + temp->ce->temp_weight;
temp1->next=ddv[temp1->cv->d_new];
temp1->prev=NULL;
temp1->cv->p = temp->ce->s;  //change its parent point to current y->cv
if(ddv[temp1->cv->d_new]!=NULL){
ddv[temp1->cv->d_new]->prev=temp1;
}
ddv[temp1->cv->d_new]=temp1;
}


if(temp->ce->d->d_new > distance + temp->ce->temp_weight){// when we can relax the edge
temp->ce->d->p = temp->ce->s;
//find the tempV form former distance temp->d->d_new list
puts("relaxing vertex");
tempV=ddv[temp->ce->d->d_new];
while(tempV->cv!=temp->ce->d)
tempV=tempV->next;
if(tempV==NULL)
puts("an error ocurred we cannot find a existed veretx_list elem");


//cut the tempV from the list
if(tempV->prev!=NULL){
tempV->prev->next=tempV->next;
}else{
if(ddv[temp->ce->d->d_new]!=tempV)
puts("an error ocurred ");
ddv[temp->ce->d->d_new]=tempV->next;
}
if(tempV->next!=NULL)
tempV->next->prev=tempV->prev;


//add the tempV to its calculated new distance list
tempV->cv->d_new=distance + temp->ce->temp_weight;  //change its d_new  to new value 
tempV->prev=NULL;
tempV->next=ddv[tempV->cv->d_new];
if(ddv[tempV->cv->d_new]!=NULL)
ddv[tempV->cv->d_new]->prev=tempV;
ddv[tempV->cv->d_new]=tempV;
}
}
}


}




void IPH_SELevel_SSSP(struct Graph *G){
puts("IPH_SELevel_SSSP was called");
/*process single E-level single source shortest path 
* started form G->ALL_V->cv
* Edge weight according to e->temp_weight
* method: construct a array store all the vertex which distance to start vertex form 0 ~ E
*/
struct Vertex_list *distance_divided_vertex[Edge_num+1];
int i=0;
for(i=0;i<=Edge_num;i++){
distance_divided_vertex[i]=NULL;
}
distance_divided_vertex[0]=NEW_VERTEX_LIST_P;
distance_divided_vertex[0]->cv=G->All_V->cv;
distance_divided_vertex[0]->prev=NULL;
distance_divided_vertex[0]->next=NULL;


struct Vertex_list *temp=G->All_V;
for(i=0;i<=Edge_num;i++){
temp=distance_divided_vertex[i];
printf("now is distance %d\n",i);
while(temp!=NULL){
temp->cv->d_new=i;
IPH_DFS(distance_divided_vertex,temp,i);
temp=distance_divided_vertex[i];
}
}




}


void IPH_FULL_SSSP(struct Graph *G){
int compare_array[Bit_number]={ozzzzz,oozzzz,ooozzz,oooozz,oooooz,oooooo};
int a,b,c;
struct Vertex_list *temp;
struct Edge_list   *temp1;
int i=0;
for(i=0;i<Bit_number;i++){
printf("i=%d\n",i);
for_each_edge_listE(G,temp1){
a=temp1->ce->s->d;
b=temp1->ce->d->d;
c=(temp1->ce->weight&compare_array[i])>>(5-i);
printf("a=%d,b=%d,c=%d\n",a,b,c);
temp1->ce->temp_weight=c + 2*(a - b);
printf("edge start form %d to %d weight = %d temp_weight=%d\n",temp1->ce->s->identify
  ,temp1->ce->d->identify
  ,temp1->ce->weight
  ,temp1->ce->temp_weight);
}
//start to process single E-level single source shortest path 
IPH_SELevel_SSSP(G);


for_each_vertex_listV(G,temp){
printf("previous temp->cv->d=%d,temp->cv->d_new=%d\n",temp->cv->d,temp->cv->d_new);
temp->cv->d=2*temp->cv->d + temp->cv->d_new;
temp->cv->d_new=-1;
temp->cv->color=white;
printf("vertex %d's distance=%d,previous_distance=%d\n",temp->cv->identify
 ,temp->cv->d
 ,temp->cv->d_new);
}


}
}






1 0
原创粉丝点击