多区域选路算法研究

时间:2021-10-15 11:12:10





#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
/* Dijkstra算法 */
#define MAX_VERTICES 10 /* maximum number of vertices */
#define FALSE 0
#define TRUE 1
#define INT_MAX 10000 //定义无穷大为1000
#define MAX_POINTS 31
#define MAX_CONTENTS 90
#define MAX_ARRAY 100


/*==============================================================================*/
/* 结构体的定义    */
/*==============================================================================*/


int NumOfRate=0 ;
int flag = 0 ; //设置标志为,0标志为阻塞,1标志为没有阻塞


int prev[MAX_POINTS] ;
int Points[MAX_POINTS] = {00,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39} ; //记录所使用的节点代号
double Weights[MAX_CONTENTS][MAX_CONTENTS] ={0}; //记录带宽
double BandWidth[MAX_CONTENTS][MAX_CONTENTS] = {0}; //备用带宽
int Array[MAX_ARRAY] ; //用来承载所经过的节点


int PointsNum = 0 ; //用来指示走过的节点的数量


typedef struct Area{ //定义区域路径结构体
int key ;
double Map[MAX_VERTICES][MAX_VERTICES];
}Area ;






typedef struct K_back{
int Path[MAX_POINTS + 1] ;


int PathOne[MAX_POINTS + 2] ; //记录路径1,末位保存该从哪位开始读
int PathTwo[MAX_POINTS + 2] ; //记录路径2


double LengthOne ;
double LengthTwo ;


double CostOne ;
double CostTwo ;


int NumOfPath ;

}K_back ;




/*==================================================================================*/
/* 路径图的导入 */
/*==================================================================================*/


K_back KBack={ {0},0,{0},0 } ;


//权值按跳数算
Area AreaBound ={0,{{0,1,1000,1,1000,1000,1000,1000,1000,1000},
{1,0,1,1000,1000,1000,1000,1000,1000,1000},
{1000,1,0,1,1000,1000,1000,1000,1000,1000},
{1,1000,1,0,1000,1000,1000,1000,1000,1000},
{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
{1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
{1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000}}
 } ; //边界节点路径图
//Area AreaBound ={ {{0,3,1},{3,0,1},{1,1,0}} } ; //测试用边界节点路径图
Area AreaOne  ={1, {
{0 ,1 ,1000 ,1000 ,1 ,1000 ,1 ,1000 ,1000 ,1000},
{1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1 ,0 ,1000 ,1 ,1 ,1 ,1000},
{1000 ,1000 ,1000 ,1000 ,1000 ,0 ,1 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1000 ,1 ,1 ,0 ,1000 ,1000 ,1000},
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,0 ,1000 ,1 },
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,1000 ,0 ,1 },
{1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1 ,1 ,0 }
}
}; //区域1路径图
Area AreaTwo  ={2,  {
{0 ,1 ,1000 ,1000 ,1 ,1000 ,1 ,1000 ,1000 ,1000},
{1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1 ,0 ,1000 ,1 ,1 ,1 ,1000},
{1000 ,1000 ,1000 ,1000 ,1000 ,0 ,1 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1000 ,1 ,1 ,0 ,1000 ,1000 ,1000},
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,0 ,1000 ,1 },
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,1000 ,0 ,1 },
{1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1 ,1 ,0 }
}
}; //区域2路径图
//Area AreaThree={  {{0,1,1,1000},{1,0,1000,1},{1,1000,0,1},{1000,1,1,0}} }  ; //区域3路径图
Area AreaThree  ={3,   {
{0 ,1 ,1000 ,1000 ,1 ,1000 ,1 ,1000 ,1000 ,1000},
{1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000},
{1000 ,1000 ,1 ,0 ,1 ,1000 ,1000 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1 ,0 ,1000 ,1 ,1 ,1 ,1000},
{1000 ,1000 ,1000 ,1000 ,1000 ,0 ,1 ,1000 ,1000 ,1000},
{1 ,1000 ,1000 ,1000 ,1 ,1 ,0 ,1000 ,1000 ,1000},
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,0 ,1000 ,1 },
{1000 ,1000 ,1000 ,1000 ,1 ,1000 ,1000 ,1000 ,0 ,1 },
{1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1000 ,1 ,1 ,0 }
}
 } ;




/*===============================路径图的备份=======================================*/
Area BackupBound = AreaBound ;
Area BackupOne = AreaOne ;
Area BackupTwo = AreaTwo ;
Area BackupThree = AreaThree ;


/*==============================================================================*/
/* 子函数    */
/*==============================================================================*/
int  ReturnPath(int v,int w) ;
double  shortestpath(int v,int s,Area area1) ;
int choose(double distance[],int n, short int found[]) ;
void k_shortest(int v,int w,Area area1) ;
void KillFirstPath(int v,int w) ;
void copypath(int Path[MAX_POINTS + 1],int PathCopy[MAX_POINTS + 2],int num) ;
void readpath(int Path[MAX_POINTS + 2],int AreaNum) ;
double ComputeCost(int Path1[MAX_POINTS + 2],double weights,int AreaNum) ;
void PathSearch(int v,int w,double weights,Area area1,int AreaNum) ;


double SetPathWeights(int Path1[MAX_POINTS + 2],int Path2[MAX_POINTS + 2],double weights) ;
int SetWeights(int Path1[MAX_POINTS + 2],double weights,int AreaNum) ;


void SetCost(int Path1[MAX_POINTS + 2]) ;
double MinWeights(int Path1[MAX_POINTS + 2],int AreaNum) ;
void CheckWeights(Area area1,int weights) ;
void FinalSearch(int v,int w,int weights) ;
Area CheckArea(int s) ;
int InsidePlace(int v) ;
int CheckAreaNum(int v) ;
int GetAreaNum(int v) ; //获得其所在区域边界路由的标号


int RandomNum() ; //产生符合命名规则的随机数
int RandomWeights() ; //产生随机的带宽需求,颗粒度为5
/*===============================================================================*/
int RandomWeights()
{
int k ; //最大话务量为50
k = rand()%10 + 1 ;
k = k* 5 ;
return k ;
}


/*===============================================================================*/
int RandomNum()
{
int k ;
k = (rand())%(MAX_POINTS) ;
k = Points[k] ;
return k ;
}


/*===============================================================================*/
int GetAreaNum(int v){
int temp = v/10 ;
return temp ;
}
/*===============================================================================*/
int CheckAreaNum(int v)
{
int temp1 ;
temp1 = v/10 ;
int temp2 =0 ;
if(v % 10 == 0){
return temp2 ;


}
else{
return temp1 ;
}
}
/*===============================================================================*/
Area CheckArea(int s)
{
int i ;
i = s/10 ;
switch(i){
case 0:return AreaBound ;
case 1:return AreaOne ;
case 2:return AreaTwo ;
case 3:return AreaThree ;
}
}
/*===============================================================================*/
int InsidePlace(int v)
{
int temp = v%10 ;
return temp ;
}
/*===============================================================================*/
void FinalSearch(int v,int w,int weights)
{
printf("%d=>%d  话务量为:%d ",v,w,weights) ;




Area AreaCheck1 = CheckArea(v) ;
Area AreaCheck2 = CheckArea(w) ;

int AreaNum1 = CheckAreaNum(v) ;
int AreaNum2 = CheckAreaNum(w) ;


int v1 = InsidePlace(v) ;
int w1 = InsidePlace(w) ;


if(AreaNum1 == AreaNum2 && AreaNum1 != 0){ //证明是同域间路由



PathSearch(v1,w1,weights,AreaCheck1,AreaNum1) ;


else if(AreaNum1 == w/10 && AreaNum1 !=0 && w%10 == 0){
PathSearch(v1,w1,weights,AreaCheck1,AreaNum1) ;
}




else if(AreaNum1 ==0 && AreaNum2 == 0){ //AreaNum1,AreaNum2为边界路由

PathSearch(GetAreaNum(v),GetAreaNum(w),weights,AreaBound,AreaNum1) ; //在寻找边界路由路径


}
else if(AreaNum1 == 0 && AreaNum2 !=0){ //AreaNum1为边界路由,AreaNum2为区域路由

PathSearch(GetAreaNum(v),GetAreaNum(w),weights,AreaBound,AreaNum1) ;
printf("=>") ;
PathSearch(0,w1,weights,AreaCheck2,AreaNum2) ;

}
else if(AreaNum1 != 0 && AreaNum2 ==0){ //AreaNum1为区域路由,AreaNum2为边界路由



PathSearch(v1,0,weights,AreaCheck1,AreaNum1) ;
printf("=>") ;
PathSearch(GetAreaNum(v),GetAreaNum(w),weights,AreaBound,AreaNum2) ;

}
else if(AreaNum1 !=0 && AreaNum2 != 0){ //AreaNum1和AreaNum2为区域路由


PathSearch(v1,0,weights,AreaCheck1,AreaNum1) ;
printf("=>") ;
PathSearch(GetAreaNum(v),GetAreaNum(w),weights,AreaBound,0) ;
printf("=>") ;
PathSearch(0,w1,weights,AreaCheck2,AreaNum2) ;

}


if(flag == 1){
NumOfRate++ ;
flag = 0 ;
}
else{
}


printf("\n") ;






}


/*===============================================================================*/
void CheckWeights(Area area1,int weights)
{
int i=0;
int j=0;
for(i=0;i<MAX_CONTENTS;i++){
for(j=0;j<MAX_CONTENTS;j++){
if(Weights[i][j] < weights){
area1.Map[i][j] = 1000 ;
area1.Map[j][i] = 1000 ;
}
}

}




}
/*===============================================================================*/
int SetWeights(int Path1[MAX_POINTS + 2],double weights,int AreaNum)
{
int num = Path1[MAX_POINTS + 1] ;
int temp = num ;
int key =0;


if(AreaNum == 0){
for(num;num>0;num--){
if(Weights[Path1[num]*10][Path1[num - 1]*10] - weights < 0){
key = 1 ;
}


}
num = temp ;
if(key == 1){
  // printf("路径不通!!!\n") ;
return 0 ;
}
else{


for(num;num>0;num--){
Weights[Path1[num]*10][Path1[num - 1]*10] -= weights ;
Weights[Path1[num - 1]*10][Path1[num]*10] -= weights ;

}
return 1 ;
}


}


else {
for(num;num>0;num--){
if(Weights[Path1[num] + AreaNum*10][Path1[num - 1] + AreaNum*10] - weights < 0){
key = 1 ;
}


}
num = temp ;
if(key == 1){
  // printf("路径不通!!!\n") ;
return 0 ;
}
else{


for(num;num>0;num--){
Weights[Path1[num] + AreaNum*10][Path1[num - 1]+ AreaNum*10] -= weights ;
Weights[Path1[num - 1]+ AreaNum*10][Path1[num]+ AreaNum*10] -= weights ;

}
return 1 ;
}
}


}


/*===============================================================================*/
double MinWeights(int Path1[MAX_POINTS + 2],int AreaNum)
{

int num = Path1[MAX_POINTS + 1] ;
double MinWeights = 100 ;
if(AreaNum == 0){
for(num ;num>0;num--){
if(Weights[Path1[num]*10 ][Path1[num -1]*10] < MinWeights){
MinWeights = Weights[Path1[num]*10][Path1[num - 1]*10 ] ;
}


}
}
else{
for(num ;num>0;num--){
if(Weights[Path1[num] + AreaNum*10 ][Path1[num -1]+ AreaNum*10] < MinWeights){
MinWeights = Weights[Path1[num] + AreaNum*10 ][Path1[num - 1] + AreaNum*10 ] ;
}


}
}







return MinWeights ;
}






/*===============================================================================*/
void PathSearch(int v,int w,double weights,Area area1,int AreaNum)
{



/* if(AreaNum != 0){
printf("%d->%d  ", v + AreaNum*10,w + AreaNum*10) ;
}
else{
printf("%d->%d  ", v * 10,w*10) ;
}*/
k_shortest(v,w,area1) ;////////////////////////////////////////////////////////////////////////////////////////////


int choose = 0 ; //记录选择哪对路径]



//计算链路耗费,以便取得哪对路径
double Cost1 = ComputeCost(KBack.PathOne,weights,AreaNum) ;
double Cost2 = ComputeCost(KBack.PathTwo,weights,AreaNum) ;



if(Cost1 >= 1000 && Cost2 >= 1000){
flag = 1 ;
printf("已经阻塞!!!\n") ;
}


else if(Cost1 <= Cost2){


SetWeights(KBack.PathOne,weights,AreaNum) ;
readpath(KBack.PathOne,AreaNum) ;
}
else if(KBack.NumOfPath ==2){
SetWeights(KBack.PathTwo,weights,AreaNum) ;
readpath(KBack.PathTwo,AreaNum) ;



}
else{
SetWeights(KBack.PathOne,weights,AreaNum) ;
readpath(KBack.PathOne,AreaNum) ;
}




}


/*==============================================================================================*/
double ComputeCost(int Path1[MAX_POINTS + 2],double weights,int AreaNum)
{


double Cost = 0 ;
int num1 = Path1[MAX_POINTS + 1] ;
int temp = num1 ;



double MinWeights1 = MinWeights(Path1,AreaNum) ;

if(MinWeights1 < weights ){
Cost = 1000 ;

}
else { 
if(AreaNum == 0){
for(num1;num1>0;num1--){
Cost += 1*(weights/(10 +Weights[Path1[num1]*10][Path1[num1 - 1]*10]) ) +0;
}
// Cost = Cost  *temp/100 ;
Cost = temp/100 ;
}
else{
for(num1;num1>0;num1--){
Cost += 1*(weights /(10 + Weights[Path1[num1]+AreaNum*10][Path1[num1 - 1]+AreaNum*10])) + 0 ;
}
// Cost = Cost *temp/100 ;
Cost = temp/100 ;
}


//  Cost = num1 ;


}
// }

// return Cost ;

return Cost ;



}








/*==============================================================================================*/
void readpath(int Path[MAX_POINTS + 2],int AreaNum)
{
int num = Path[MAX_POINTS + 1] ;


if(AreaNum != 0){
for(num ; num>0 ;num--){
printf("%d->",Path[num] + AreaNum*10) ;
}
printf("%d",Path[num] + AreaNum*10) ;
}
else{
for(num ; num>0 ;num--){
printf("%d->",Path[num]*10) ;
}
printf("%d",Path[num]*10) ;
}




}






/*==============================================================================================*/
void copypath(int Path[MAX_POINTS+1],int PathCopy[MAX_POINTS+2],int num)
{
int i=0 ;
for(i=0 ;i<MAX_POINTS + 1;i++){
PathCopy[i] = Path[i] ;
}

PathCopy[MAX_POINTS + 1] = num ;
/*=================================*/
/*下面将Path置0   */
/*=================================*/
for(i=0 ;i<MAX_POINTS + 1;i++){
Path[i] = 0 ;
}
}




/*==============================================================================================*/
void k_shortest(int v,int w,Area area1)
{


Area areatemp = area1 ;


KBack.NumOfPath = 0 ;
/*=================================================================================================*/
//生成路径对(主路径与备用路径部分)
KBack.LengthOne = shortestpath( v, w, area1) ;




int j = ReturnPath(v,w) ;
copypath(KBack.Path,KBack.PathOne,j) ; //记录下最短路径
for(j;j>0;j--){
area1.Map[KBack.PathOne[j]][KBack.PathOne[j-1]] = 1000 ;
area1.Map[KBack.PathOne[j-1]][KBack.PathOne[j]] = 1000 ;
}


KBack.LengthTwo = shortestpath(v,w,area1) ;





int k = ReturnPath(v,w) ;
copypath(KBack.Path,KBack.PathTwo,k) ;    //记录下第二短路径
for(k;k>0;k--){
area1.Map[KBack.PathTwo[k]][KBack.PathTwo[k-1]] = 1000 ;
area1.Map[KBack.PathTwo[k-1]][KBack.PathTwo[k]] = 1000 ;
}


if(KBack.LengthTwo < 1000){
KBack.NumOfPath =1 ;
}
if(KBack.LengthTwo < 1000){
KBack.NumOfPath =2 ;
}




area1 = areatemp ;


//由于定义了area1所以在此函数里面对AreaXXX的修改其实是对area1的修改,所以无需还原 

}


/*==============================================================================================*/


int ReturnPath(int v,int w)
{
int i;
int j = 1 ;
for(i=0;i<MAX_POINTS+1;i++){
KBack.Path[i] = -1;
}
i = w ;
KBack.Path[0] = w ;
while(prev[i] != v){
KBack.Path[j] = prev[i] ;
j++ ;
i = prev[i] ;
}
KBack.Path[j] = v ;


int temp = j ;


for(j;j>0;j--){
Array[PointsNum++] = KBack.Path[j];
}
Array[PointsNum++] = KBack.Path[0] ;


return temp ;
}







/*===============================================================================================*/
/* Dijkstra函数 */
/*===============================================================================================*/
double  shortestpath(int v,int s,Area area1)
{
double distance[MAX_VERTICES] ; //distance[w]表示从源点v出发,且只经过S中的顶点,并最终达到w的最短路径的长度
short int found[MAX_VERTICES] ; //若顶点i不在S中,则found[i]=FALSE,在S中,则found[i]=TRUE
int n = MAX_VERTICES ;
int i,w ;
int u ;

for(i=0 ;i<MAX_POINTS;i++){
prev[i] = v
}
for(i=0;i<n;i++){
found[i] = FALSE ;
distance[i] = area1.Map[v][i] ;
}
found[v] = TRUE ;
distance[v] = 0 ;
    for(i=0;i<n-2;i++){
u = choose(distance,n,found) ;
found[u] = TRUE ;
for(w=0;w<n;w++){
if(!found[w]){
if(distance[u] + area1.Map[u][w] < distance[w]){
distance[w] = distance[u] + area1.Map[u][w] ;
prev[w] = u ;
}
}
}
}
return distance[s] ;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int choose(double distance[],int n, short int found[])
{
int i ;
double min ;
int minpos ;
min = INT_MAX ;
minpos = -1 ;
for(i=0;i<n;i++){
if(distance[i] < min && !found[i]){
min = distance[i] ;
minpos = i ;
}


}
return minpos ;
}
/*=============================================================================================*/
/* 主函数   */
/*=============================================================================================*/
void main()
{
/*----------------------------------------------------------------------------------------------------*/
printf("=========================================\n") ;
int i,j ;


for(i=0 ;i<MAX_CONTENTS;i++){
for(j=0;j<MAX_CONTENTS;j++){
Weights[i][j] = 100 ; //定义带宽 100
BandWidth[i][j] = 100 ;
}
}
for(i=0 ;i<4;i++){
for(j=0;j<4;j++){
Weights[i*10][j*10] = 500 ;
Weights[j*10][i*10] = 500 ;
}
}
// Weights[0][10] = 500 ;
// Weights[10][0] = 500 ;




for(i=0;i<MAX_ARRAY;i++){ //初始化Array
Array[i] = -1 ;
}


for(i=0 ;i<50;i++){

FinalSearch(RandomNum(),RandomNum(),RandomWeights()) ;

}


printf("The Num Of Rate is %d\n",NumOfRate) ;
/*-----------------------------------------------------------------------------------------------------*/


/* PathSearch(0,4,20,AreaOne,1) ;
PathSearch(0,4,90,AreaOne,1) ;
PathSearch(0,4,60,AreaOne,1) ; */


/* PathSearch(0,4,20,AreaOne,1) ;
PathSearch(0,4,20,AreaOne,1) ;
PathSearch(0,4,20,AreaOne,1) ;
PathSearch(0,4,20,AreaOne,1) ;
PathSearch(0,4,20,AreaOne,1) ;*/


/* FinalSearch(29,30,10) ;
FinalSearch(20,30,10) ;
FinalSearch(29,39,10) ;
FinalSearch(29,26,10) ;
FinalSearch(20,39,10) ;*/






// FinalSearch(20,30,10) ;




/* FinalSearch(11,19,10) ;
FinalSearch(11,19,90) ;
FinalSearch(11,19,20) ;*/


// FinalSearch(16,20,10) ;
// FinalSearch(29,28,10) ;
// printf("Weights = %.1f\n",Weights[19][18]) ;


// FinalSearch(25,30,10) ;
// FinalSearch(20,25,10) ;
// PathSearch(9,0,20,AreaOne,2) ;
/* FinalSearch(19,31,10) ;
FinalSearch(16,20,5) ;
FinalSearch(32,10,45) ;
FinalSearch(37,10,25) ;
FinalSearch(19,34,10) ;
FinalSearch(16,28,10) ;
FinalSearch(36,20,40) ;
FinalSearch(38,36,25) ;
FinalSearch(39,22,15) ;
FinalSearch(33,11,35) ;
FinalSearch(24,35,40) ;
FinalSearch(19,18,45) ;
FinalSearch(25,20,40) ;
FinalSearch(12,37,25) ;
FinalSearch(12,24,15) ;


FinalSearch(19,31,10) ;
FinalSearch(16,20,5) ;
FinalSearch(32,10,45) ;
FinalSearch(37,10,25) ;
FinalSearch(19,34,10) ;
FinalSearch(16,28,10) ;
FinalSearch(36,20,40) ;
FinalSearch(38,36,25) ;
FinalSearch(39,22,15) ;
FinalSearch(33,11,35) ;
FinalSearch(24,35,40) ;
FinalSearch(19,18,45) ;
FinalSearch(25,20,40) ;
FinalSearch(12,37,25) ;
FinalSearch(12,24,15) ;


FinalSearch(19,31,10) ;
FinalSearch(16,20,5) ;
FinalSearch(32,10,45) ;
FinalSearch(37,10,25) ;
FinalSearch(19,34,10) ;
FinalSearch(16,28,10) ;
FinalSearch(36,20,40) ;
FinalSearch(38,36,25) ;
FinalSearch(39,22,15) ;
FinalSearch(33,11,35) ;
FinalSearch(24,35,40) ;
FinalSearch(19,18,45) ;
FinalSearch(25,20,40) ;
FinalSearch(12,37,25) ;
FinalSearch(12,24,15) ;


FinalSearch(19,31,10) ;
FinalSearch(16,20,5) ;
FinalSearch(32,10,45) ;
FinalSearch(37,10,25) ;
FinalSearch(19,34,10) ;
FinalSearch(16,28,10) ;
FinalSearch(36,20,40) ;
FinalSearch(38,36,25) ;
FinalSearch(39,22,15) ;
FinalSearch(33,11,35) ;
FinalSearch(24,35,40) ;
FinalSearch(19,18,45) ;
FinalSearch(25,20,40) ;
FinalSearch(12,37,25) ;
FinalSearch(12,24,15) ;





// PathSearch(9,0,20,AreaOne,1) ;
// PathSearch(0,4,20) ;


printf("\n") ;
   // k_shortest(0,4,area1) ;*/


}