Locally Approximate Boundaries in Wireless Sensor Networks

Ching-Yao Wang and Tien-Ruey Hsiang
Dept. of Computer Science and Information Engineering National Taiwan University of Science and Technology

Title: The 10th International Symposium on Pervasive Systems, Algorithms,and Networks, ISPAN 2009, Kaohsiung, Taiwan, December 14-16, 2009

Publisher: IEEE

ISBN: 978-0-7695-3908-9

http://doi.ieeecomputersociety.org/10.1109/I-SPAN.2009.106

 

Sensor nodes located on the boundary of the covered area often cause difficulties in maintaining a wireless sensor network's lifespan. This study proposes a simple method to approximate boundaries in wireless sensor networks. The approach uses only connectivity information of a network while not requiring nodes localize themselves. The proposed method divides a network into clusters and forms partial boundaries, then extends detected partial boundaries until the whole boundary is formed. Using a node's 1- and 2-hop neighbors, every node can decide locally whether itself is located near the boundary. The implementation shows that the approach can efficiently determine boundaries in the coverage of a WSN.

 

Boundary detection may provide a picture of the coverage condition of a sensor network. From boundary information, the number or motion of intruders may be induced, the weakly covered areas can be found, and the distribution of power consumption can be predicted. In this paper, an approach of topological boundary approximation for self-organizing sensor networks is proposed. The approach works in a single cluster WSN, where leaf nodes perform cycle tests. However, it requires more communication to approximate boundaries. In order to reduce the communication overhead, a clustering phase is added to first divide a WSN, then cycle tests are performed on selected nodes to approximate boundaries. Every node uses the connectivity information of its 1-hop and 2-hop neighbors to perform a cycle test in the proposed approach.

The implementation and simulations show that the proposed method successfully approximates boundaries in all cases and verified the estimation on the minimum detectable hole distance. Nodes in the proposed method require no additional communications other than forming 2-hop neighborhoods. Therefore, the developed method makes less impact on the lifespan of a WSN than other approaches. The cycle property of nodes remains the same in mobile WSNs, where sensor nodes are equipped with actuators. However, mobility implies frequent updates of the boundary condition which require complex communications. The boundary approximation in mobile sensor networks using cycle tests is currently under investigation.

Grouping:

boundary

Result:

boundary result

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

TForm1 *Form1;
using namespace std;

TColor *group_color;         
BoundaryDetection BD;
//---------------------------------------------------------------------------
bool sort_id(Two_Hop_Set a,Two_Hop_Set b)
{
    return         a.id     < b.id;     
}
//---------------------------------------------------------------------------
bool sort_hop_count(Two_Hop_Set a,Two_Hop_Set b)
{
    return         a.One_Hop_Count > b.One_Hop_Count;     
}
//---------------------------------------------------------------------------
BoundaryDetection::BoundaryDetection()
{
    node = NULL;
}
//---------------------------------------------------------------------------
void BoundaryDetection::Draw_Node(TImage *image,AnsiString mode, TColor color,int shift_size, int id)
{                                                                                 
    if(mode=="Pen")
        image->Canvas->Pen->Color=color;
    if(mode=="Brush")
    {
        image->Canvas->Brush->Style=bsClear;
        image->Canvas->Brush->Color=color;
    }
    image->Canvas->Ellipse(node[id].coordinate_x+communication_range+shift_size,node[id].coordinate_y+communication_range+shift_size,
                                 node[id].coordinate_x+communication_range-shift_size,node[id].coordinate_y+communication_range-shift_size);
}
//---------------------------------------------------------------------------
void BoundaryDetection::initial(void)
{
    int node_count=0;
    ifstream fin;
    fin.open(Form1->OpenDialog1->FileName.c_str(),ios::in);
    fin>>node_number;
    node=new Node_type[node_number];
    while(!fin.eof() && node_count<node_number)
    {
        node[node_count].Node_ID=node_count;
        fin>>node[node_count].coordinate_x>>node[node_count].coordinate_y;
        Application->ProcessMessages();
        Form1->Image1->Canvas->Brush->Style=bsSolid;
        Draw_Node(Form1->Image1,"Pen",clBlack,2,node_count);
        node[node_count].min_hop_count_to_head=0; 
        node[node_count].isTesting=false;                                 
        node[node_count].status="not test";
        node[node_count].isAddToPath=false;
        TListItem *item=Form1->ListView1->Items->Add();
        item->Caption=IntToStr(node_count);
        item->SubItems->Add(IntToStr(node[node_count].coordinate_x));
        item->SubItems->Add(IntToStr(node[node_count].coordinate_y));
        node_count++;
    }
    Form1->StatusBar1->Panels[0].Items[0]->Text="Node Number: " + IntToStr(node_number);
}
//---------------------------------------------------------------------------
void BoundaryDetection::Find_One_Hop_Neighbor(void)
{
    total_degree=0;
    for(int i=0;i<node_number;i++)
    {
        for(int j=0;j<node_number;j++)
        {
            if(i!=j)
                if(!Out_Of_Range(node[i].coordinate_x,node[i].coordinate_y,node[j].coordinate_x,node[j].coordinate_y,communication_range))
                    node[i].One_Hop_ID.push_back(j); 
        }
        total_degree+=node[i].One_Hop_ID.size();
    }
    average_degree=total_degree/node_number;
    Form1->StatusBar1->Panels[0].Items[1]->Text="Average Degree: " + FloatToStr(average_degree);
}
//---------------------------------------------------------------------------
void BoundaryDetection::Find_Two_Hop_Neighbor(void)
{
    for(int i=0;i<node_number;i++)
    {
        for(int j=0;j<node[i].One_Hop_ID.size();j++)
        {
            for(int k=0;k<node[node[i].One_Hop_ID[j]].One_Hop_ID.size();k++)
            {
                if(node[node[i].One_Hop_ID[j]].One_Hop_ID[k]!=i)
                    node[i].Two_Hop_ID.push_back(node[node[i].One_Hop_ID[j]].One_Hop_ID[k]);                 
            }
        }     
        for(int j=0;j<node[i].One_Hop_ID.size();j++)         
        {
            node[i].Two_Hop_ID.erase( remove(node[i].Two_Hop_ID.begin(),node[i].Two_Hop_ID.end(),
                                             node[i].One_Hop_ID[j]),
                                         node[i].Two_Hop_ID.end()
                                    );
        }
        sort(node[i].Two_Hop_ID.begin(),node[i].Two_Hop_ID.end());     
        node[i].Two_Hop_ID.erase(unique(node[i].Two_Hop_ID.begin(), node[i].Two_Hop_ID.end()), node[i].Two_Hop_ID.end());     
        node[i].to_each_head_hop_count=new int[group_number];
        node[i].to_head_parent=new int[group_number];
        for(int g=0;g<group_number;g++)
        {
            node[i].to_each_head_hop_count[g]=0;
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::FindGroupFlooding(int ParentID ,int HeadID,int GroupID)
{
    int parentHC=node[ParentID].to_each_head_hop_count[GroupID];
    for(int i=0;i<node[ParentID].One_Hop_ID.size();i++)
    {
        childHC=parentHC+1;
        if(node[node[ParentID].One_Hop_ID[i]].to_each_head_hop_count[GroupID] <= childHC)
        {
            if(node[node[ParentID].One_Hop_ID[i]].to_each_head_hop_count[GroupID]!=0)
                ;
            else
            {
                if(node[node[ParentID].One_Hop_ID[i]].Node_ID!=node[ParentID].Node_ID)
                {
                    node[node[ParentID].One_Hop_ID[i]].to_each_head_hop_count[GroupID]=childHC;
                    node[node[ParentID].One_Hop_ID[i]].to_head_parent[GroupID]=ParentID;
                    Application->ProcessMessages();
                    FindGroupFlooding(node[ParentID].One_Hop_ID[i],HeadID,GroupID);
                }
            }
        }
        if(node[node[ParentID].One_Hop_ID[i]].to_each_head_hop_count[GroupID] > childHC)
        {
            if(node[node[ParentID].One_Hop_ID[i]].Node_ID!=node[ParentID].Node_ID)
            {
                node[node[ParentID].One_Hop_ID[i]].to_each_head_hop_count[GroupID]=childHC;
                node[node[ParentID].One_Hop_ID[i]].to_head_parent[GroupID]=ParentID;                                     
                Application->ProcessMessages();
                FindGroupFlooding(node[ParentID].One_Hop_ID[i],HeadID,GroupID);
            }
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Determine_Testing_Node()
{
    if(group_number>1         && multiplemode==2)
    {
        for(int i=0;i<node_number;i++)
        {
            if(node[i].isLeaf==true)
            {
                                     node[i].isTestingNode=true;
                    testing_message_overhead=testing_message_overhead+node[i].One_Hop_ID.size()*2+node[i].Two_Hop_ID.size()*2;
                    total_testing_node++;
            }
        }
    }

    if(group_number>1     && multiplemode==3)
    {
        int min_flag;
        for(int i=0;i<node_number;i++)
        {
            min_flag=0;
            if(node[i].isLeaf==true)
            {
                    for(int j=0;j<node[i].One_Hop_ID.size();j++)
                    {
                        if(node[i].Node_ID < node[node[i].One_Hop_ID.at(j)].Node_ID)
                            min_flag=1;
                    }
                    if(min_flag==0)
                    {
                        node[i].isTestingNode=true;
                        testing_message_overhead=testing_message_overhead+node[i].One_Hop_ID.size()*2+node[i].Two_Hop_ID.size()*2;
                        total_testing_node++;
                    }
            }
        }
    }
    
    if(group_number>1     && multiplemode==1)
    {
        for(int i=0;i<node_number;i++)
        {
            if(node[i].isLeaf==true)
            {
                int flag=0;
                for(int j=0;j<node[i].One_Hop_ID.size();j++)
                {
                    if(node[node[i].One_Hop_ID[j]].Group_ID!=node[i].Group_ID)
                        flag=1;
                }
                if(flag==1)
                {
                    node[i].isTestingNode=true;
                    int two_hop_oh=0;
                    testing_message_overhead=testing_message_overhead+node[i].One_Hop_ID.size()*2+node[i].Two_Hop_ID.size()*2;
                    Draw_Node(Form1->Image1,"Pen",clRed,2,i);
                    total_testing_node++;
                }
                else
                    node[i].isTestingNode=false;
            }
        }
    }

    if(group_number==1 && singlemode==1)
    {
        for(int i=0;i<node_number;i++)
        {
            if(node[i].isLeaf==true)
            {
                    testing_message_overhead=testing_message_overhead+node[i].One_Hop_ID.size()*2+node[i].Two_Hop_ID.size()*2;
                    total_testing_node++;
            }
        }
    }
    if(group_number==1 && singlemode==2)
    {
        int min_flag;
        for(int i=0;i<node_number;i++)
        {
            min_flag=0;
            if(node[i].isLeaf==true)
            {
                    for(int j=0;j<node[i].One_Hop_ID.size();j++)
                    {
                        if(node[i].Node_ID < node[node[i].One_Hop_ID.at(j)].Node_ID)
                            min_flag=1;
                    }
                    if(min_flag==0)
                    {
                        node[i].isTestingNode=true;
                        testing_message_overhead=testing_message_overhead+node[i].One_Hop_ID.size()*2+node[i].Two_Hop_ID.size()*2;
                        total_testing_node++;
                    }

            }
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Grouping()
{
    Find_One_Hop_Neighbor();
    Find_Two_Hop_Neighbor();
    sel_g=new int[group_number];
    flag_gorup=new int[group_number];
    group_color=new TColor[10];
    group_color[0]=RGB(64,0,64);
    group_color[1]=RGB(115,115,0);
    group_color[2]=RGB(255,128,0);
    group_color[3]=RGB(0,0,255);

    //generating head id
    randomize();
    for(int i=0;i<group_number;i++)
    {
        sel_g[i]=random(node_number);
        //sel_g[i]=595;
        group_color[i]=group_color[i];
        flag_gorup[i]=0; 
        Form1->Image2->Canvas->Brush->Style=bsSolid;
        Draw_Node(Form1->Image2,"Pen",clRed,2,sel_g[i]);
        Form1->Edit_Head->Text=Form1->Edit_Head->Text+IntToStr(sel_g[i])+"{"+IntToStr(node[sel_g[i]].coordinate_x)+" , "+IntToStr(node[sel_g[i]].coordinate_y)+"}     ";
    }

    for(int i=0;i<group_number;i++)
    {
        childHC=0;
        FindGroupFlooding(sel_g[i],sel_g[i],i); // FindGroupFlooding(int ParentID , int HeadID , int GroupID)
        flag_gorup[i]=1;
    }
    //grouping
    int min_hc,min_group;
    for(int i=0;i<node_number;i++)
    {
        min_hc=node[i].to_each_head_hop_count[0];
        min_group=0;
        for(int j=1;j<group_number;j++)
        {
            if(min_hc>node[i].to_each_head_hop_count[j])
            {
                min_hc=node[i].to_each_head_hop_count[j];
                min_group=j;
                node[i].Group_ID=j;
            }
        }
    }
    for(int i=0;i<node_number;i++)
    {
        for(int j=0;j<group_number;j++)
        {
            node[i].ParentID=node[i].to_head_parent[node[i].Group_ID];
            node[node[i].to_head_parent[node[i].Group_ID]].ChildrenID.push_back(i);
        }
    }
    for(int i=0;i<node_number;i++)
    {
        TListItem *item=Form1->ListView2->Items->Add();
        item->Caption=IntToStr(i);
        item->SubItems->Add(IntToStr(node[i].coordinate_x));
        item->SubItems->Add(IntToStr(node[i].coordinate_y));
        item->SubItems->Add(IntToStr(node[i].Group_ID));


        Form1->Image2->Canvas->Brush->Style=bsSolid;
        Draw_Node(Form1->Image2,"Pen",group_color[node[i].Group_ID],2,i);

        Form1->Image2->Canvas->Pen->Color=clBlack;
        Form1->Image2->Canvas->MoveTo(node[i].coordinate_x+communication_range,node[i].coordinate_y+communication_range);
        Form1->Image2->Canvas->LineTo(node[node[i].ParentID].coordinate_x+communication_range,node[node[i].ParentID].coordinate_y+communication_range);
        TColor color;
        if(node[i].ChildrenID.size()==0)
        {
            Form1->Image2->Canvas->Brush->Style=bsSolid;
            color=RGB(61,250,5);
            Draw_Node(Form1->Image2,"Brush",color,2,i);
            node[i].isLeaf=true;
        }
        else
        {
            Form1->Image2->Canvas->Brush->Style=bsSolid;
            Draw_Node(Form1->Image2,"Brush",clBlack,2,i);
            node[i].isLeaf=false;
        }
    }
    Determine_Testing_Node();
    // Show Testing Node
    for(int i=0;i<node_number;i++)
    {
        if(node[i].isTestingNode)
        {
            Form1->Image2->Canvas->Brush->Style=bsSolid;
            Draw_Node(Form1->Image2,"Brush",clRed,2,i);
                             }
    }
    for(int i=0;i<group_number;i++)
                 Draw_Node(Form1->Image2,"Pen",clRed,4,sel_g[i]);
}
//---------------------------------------------------------------------------
void BoundaryDetection::FindCycle()
{
    // (2-hop , 1-hop) set sorting
    for(int i=0;i<node_number;i++)
    {
        node[i].sets=new Two_Hop_Set[200];
        for(int j=0;j<node[i].Two_Hop_ID.size();j++)
        {
            int flag=0;
            for(int k=0;k<node[node[i].Two_Hop_ID[j]].One_Hop_ID.size();k++)
            {

                for(int m=0;m<node[i].One_Hop_ID.size();m++)
                {
                    if(node[node[i].Two_Hop_ID[j]].One_Hop_ID[k]==node[i].One_Hop_ID[m])
                    {
                        node[i].sets[0].id=node[i].Two_Hop_ID[j];
                        node[i].sets[0].One_Hop_Set.push_back(node[i].One_Hop_ID[m]);
                        flag=1;
                    }
                }
            }
            if(flag==1)
                    node[i].Tmp_Two_Hop_Set.push_back(node[i].sets[0]);
            node[i].sets[0].One_Hop_Set.clear();

        }
    }
    for(int i=0;i<node_number;i++)
    {
        for(int j=0;j<node[i].Tmp_Two_Hop_Set.size();j++)
        {
            sort(node[i].Tmp_Two_Hop_Set.begin(),node[i].Tmp_Two_Hop_Set.end(),sort_id);
            for(int k=0;k<node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.size();k++)
            {
                sort(node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.begin(),node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.end());     
                node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.erase(unique(node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.begin(), node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.end()), node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.end());     
            }
        } 
        for(int j=0;j<node[i].Tmp_Two_Hop_Set.size();j++)
        {
            node[i].sets[0].id=node[i].Tmp_Two_Hop_Set[j].id;
            node[i].sets[0].One_Hop_Set=node[i].Tmp_Two_Hop_Set[j].One_Hop_Set;
            node[i].sets[0].One_Hop_Count=node[i].Tmp_Two_Hop_Set[j].One_Hop_Set.size();
            node[i].All_Two_Hop_Set.push_back(node[i].sets[0]);
            node[i].sets[0].One_Hop_Set.clear();
        }
        sort(node[i].All_Two_Hop_Set.begin(),node[i].All_Two_Hop_Set.end(),sort_hop_count);

        for(int j=0;j<node[i].All_Two_Hop_Set.size();j++)
        {
            if(node[i].All_Two_Hop_Set[j].One_Hop_Count>1)     
                node[i].Reduce_Two_Hop_Set.push_back(node[i].All_Two_Hop_Set[j]);
        }

    }
             Application->ProcessMessages(); 
    
    for(int i=0;i<node_number;i++)
    {
        if(node[i].Reduce_Two_Hop_Set.size()>0)
        {
            node[i].Min_Two_Hop_Set.push_back(node[i].Reduce_Two_Hop_Set[0]);
            for(int j=1;j<(int)node[i].Reduce_Two_Hop_Set.size();j++)
                if(!Check_Subset(node[i].Reduce_Two_Hop_Set, node[i].Min_Two_Hop_Set, j))
                    node[i].Min_Two_Hop_Set.push_back(node[i].Reduce_Two_Hop_Set[j]);
            for(int j=0;j<(int)node[i].Min_Two_Hop_Set.size();j++)
            {
                for(int k=0;k<node[i].Min_Two_Hop_Set[j].One_Hop_Count;k++)
                {
                    for(int m=0;m<(int)node[i].Min_Two_Hop_Set.size();m++)
                    {
                        if(j!=m)
                        {         
                            vector<int>::iterator it =
                                        find(node[i].Min_Two_Hop_Set[m].One_Hop_Set.begin(), node[i].Min_Two_Hop_Set[m].One_Hop_Set.end(), node[i].Min_Two_Hop_Set[j].One_Hop_Set[k]);
                            if(it != node[i].Min_Two_Hop_Set[m].One_Hop_Set.end())
                            {
                                node[i].Min_Two_Hop_Set[j].Two_Hop_Link.push_back (node[i].Min_Two_Hop_Set[m].id);
                                node[i].Min_Two_Hop_Set[j].Two_Hop_Index.push_back(m);
                            }
                        }
                    }
                }
                sort(node[i].Min_Two_Hop_Set[j].Two_Hop_Link.begin(),node[i].Min_Two_Hop_Set[j].Two_Hop_Link.end()); 
                node[i].Min_Two_Hop_Set[j].Two_Hop_Link.erase(unique(node[i].Min_Two_Hop_Set[j].Two_Hop_Link.begin(), node[i].Min_Two_Hop_Set[j].Two_Hop_Link.end()),
                                         node[i].Min_Two_Hop_Set[j].Two_Hop_Link.end());     

                sort(node[i].Min_Two_Hop_Set[j].Two_Hop_Index.begin(),node[i].Min_Two_Hop_Set[j].Two_Hop_Index.end()); 
                node[i].Min_Two_Hop_Set[j].Two_Hop_Index.erase(unique(node[i].Min_Two_Hop_Set[j].Two_Hop_Index.begin(), node[i].Min_Two_Hop_Set[j].Two_Hop_Index.end()),
                                         node[i].Min_Two_Hop_Set[j].Two_Hop_Index.end());     
            }

            if(group_number>1)
            {
                Determine_Boundary_Node_1(i);
            }
            else if(group_number==1)
            {
                Determine_Boundary_Node_2(i);
                                             }
        }
    }
    Application->ProcessMessages();
    for(int i=0;i<node_number;i++)
    {
        if(node[i].status=="boundary")
            Find_Other_Boundary_Node(i);
    }
    Draw_Node();
    //Prune_Boundary();
    for(int i=0;i<node_number;i++)
    {
        if(node[i].status=="boundary" && node[i].isAddToPath==false)
        {
            node[i].isAddToPath=true;
            Count_Boundary(i,i);
        }
    }
    Count_Ancestor();
    Count_Local_Minimum_Number();
             Application->ProcessMessages();
    vector<int> Boundary_Node_Set;
    for(int i=0;i<node_number;i++)
        if(node[i].status=="boundary")
            Boundary_Node_Set.push_back(i);
    
}
//---------------------------------------------------------------------------
void BoundaryDetection::Determine_Boundary_Node_1(int i)
{
    if( (node[i].Min_Two_Hop_Set.size() <=thresold || node[i].One_Hop_ID.size()<=thresold) && node[i].isTestingNode==true )
    {
        Application->ProcessMessages();
        node[i].status="boundary";

    }
    if(node[i].Min_Two_Hop_Set.size()>thresold && node[i].isTestingNode==true)
    {
        if(node[i].Min_Two_Hop_Set.size()>0)
        {
            if(node[i].Min_Two_Hop_Set[0].Two_Hop_Index.size()>0)
            {
                Graph         G;
                int src=0;
                int des; 
                des=node[i].Min_Two_Hop_Set[0].Two_Hop_Index[0];
                Path path;                             
                Marking visited; 
                G.NodeCount=node[i].Min_Two_Hop_Set.size();
                for(int m=0;m<G.NodeCount;m++)
                    for(int n=0;n<G.NodeCount;n++)
                        G.AdjMatrix[m][n]=0;
                for(int m=0;m<G.NodeCount;m++)
                {
                    visited[m]=false;
                    for(int n=0;n<G.NodeCount;n++)
                        for(int k=0;k<node[i].Min_Two_Hop_Set[m].Two_Hop_Index.size();k++)
                            G.AdjMatrix[m][node[i].Min_Two_Hop_Set[m].Two_Hop_Index[k]]=1;
                }
                SearchAllPath(i,G,path,visited,src,des,1);
                Get_Max_Cycle_Path(i);
                if(node[i].status!="boundary")
                {
                    if(node[i].max_cycle_path.size()>thresold)
                    {
                        Prune_Cycle_Path(i);
                        if(node[i].cycle_path.size()>thresold)
                        {
                            node[i].status="not boundary";
                        }
                        else
                        {
                            node[i].isTesting=true;
                            total_testing_node++;
                            node[i].status="boundary";
                        }
                    }
                    else
                    {
                        node[i].isTesting=true;
                        total_testing_node++;
                        node[i].status="boundary";
                    }
                }
                if(node[i].status=="boundary")
                {
                    node[i].isTesting=true;
                    total_testing_node++;
                    node[i].status="boundary";
                }
            }
            else
            {
                node[i].isTesting=true;
                total_testing_node++;
                node[i].status="boundary";
            }
        }
        else
        {
            node[i].isTesting=true;
            total_testing_node++;
            node[i].status="boundary";
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Determine_Boundary_Node_2(int i)
{
    if( node[i].Min_Two_Hop_Set.size() <=thresold || node[i].One_Hop_ID.size()<=thresold )
    {
        Application->ProcessMessages();
        node[i].status="boundary";
    }
    if(node[i].Min_Two_Hop_Set.size()>thresold )
    {
        if(node[i].Min_Two_Hop_Set.size()>0)
        {
            if(node[i].Min_Two_Hop_Set[0].Two_Hop_Index.size()>0)
            {
                Graph         G;
                int src=0;
                int des; 
                des=node[i].Min_Two_Hop_Set[0].Two_Hop_Index[0];
                Path path;                         
                Marking visited;     
                G.NodeCount=node[i].Min_Two_Hop_Set.size();
                for(int m=0;m<G.NodeCount;m++)
                    for(int n=0;n<G.NodeCount;n++)
                        G.AdjMatrix[m][n]=0;
                for(int m=0;m<G.NodeCount;m++)
                {
                    visited[m]=false;
                    for(int n=0;n<G.NodeCount;n++)
                        for(int k=0;k<node[i].Min_Two_Hop_Set[m].Two_Hop_Index.size();k++)
                            G.AdjMatrix[m][node[i].Min_Two_Hop_Set[m].Two_Hop_Index[k]]=1;
                }
                SearchAllPath(i,G,path,visited,src,des,1);
                Get_Max_Cycle_Path(i);
                if(node[i].status!="boundary")
                {
                    if(node[i].max_cycle_path.size()>thresold)
                    {         
                        Prune_Cycle_Path(i);
                        if(node[i].cycle_path.size()>thresold)
                        {
                            node[i].status="not boundary";
                        }
                        else
                        {
                            node[i].isTesting=true;
                            total_testing_node++;
                            node[i].status="boundary";
                        }
                    }
                    else
                    {
                        node[i].isTesting=true;
                        total_testing_node++;
                        node[i].status="boundary";
                    }
                }
            }
            else
            {
                node[i].isTesting=true;
                total_testing_node++;
                node[i].status="boundary";
            }
        }
        else
        {
            node[i].isTesting=true;
            total_testing_node++;
            node[i].status="boundary";
        }
    }
}
//---------------------------------------------------------------------------
bool BoundaryDetection::Check_Subset(vector<Two_Hop_Set> source, vector<Two_Hop_Set> dist, int index)
{
    int flag=0; 
    for(int i=0;i<(int)dist.size();i++)
        if(includes(dist[i].One_Hop_Set.begin(),dist[i].One_Hop_Set.end(),source[index].One_Hop_Set.begin(),source[index].One_Hop_Set.end()))
            flag=1;
    if(flag==0)
        return false;
    else if(flag==1)
        return true;
}
//---------------------------------------------------------------------------
void BoundaryDetection::PrintPath(int id,Path& path, int length)
{
    AnsiString tt="";
    vector<int> i_path;
    for(int i=0;i<length;i++)
    {
        i_path.push_back(path[i]);
        tt+=IntToStr(path[i])+"         ";
        //Form1->Memo1->Lines->Text=Form1->Memo1->Lines->Text+IntToStr(path[i])+"         ";
    }
    node[id].all_cycle_path.push_back(i_path);
    Form1->Memo4->Lines->Add(IntToStr(id)+"\t"+tt);
}
//---------------------------------------------------------------------------
void BoundaryDetection::SearchAllPath(int id,const Graph& G, Path& path, Marking& visited, int v, int des, int length)
{                                                                                 
    if(visited[v])
        return;
    path[length-1]=v;
    if(v==des)
    {
        //if(length>3)
            PrintPath(id,path,length);
    }
    else
    {
        visited[v]=true;
        for(int i=0;i<G.NodeCount;i++)
            if(G.AdjMatrix[v][i]!=0 && !visited[i])
                SearchAllPath(id,G,path,visited,i,des,length+1);
        visited[v]=false;
    }             
}
//---------------------------------------------------------------------------
void BoundaryDetection::Get_Max_Cycle_Path(int id)
{
    int max_len;
    int max_index=0;
    try
    {
        if(node[id].all_cycle_path[0].size()>0)
        {
            max_len=node[id].all_cycle_path[0].size();
        for(int j=1;j<node[id].all_cycle_path.size();j++)
        {
            if(max_len<node[id].all_cycle_path[j].size())
            {
                max_len=node[id].all_cycle_path[j].size();
                max_index=j;
            }
        }
        for(int j=0;j<node[id].all_cycle_path[max_index].size();j++)
            node[id].max_cycle_path=node[id].all_cycle_path[max_index];
        }
        if(node[id].all_cycle_path[0].size()==0)
            node[id].status="boundary";
    }
    catch(...)
    {
        node[id].status="boundary";
             }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Prune_Cycle_Path(int id)
{
    node[id].cycle_path=node[id].max_cycle_path;

    if(node[id].max_cycle_path.size()<=6)
    {
        vector<int>remove_node;
        for(int i=0;i<node[id].max_cycle_path.size();i++)
        {
            int cmp_index=(i+2)%node[id].max_cycle_path.size();
            if(cmp_index!=1)
            {
                for(int j=0;j<node[id].Min_Two_Hop_Set.size();j++)
                {
                    if(node[id].Min_Two_Hop_Set[j].id==node[id].Min_Two_Hop_Set[node[id].max_cycle_path.at(i)].id)
                    {
                        vector<int>::iterator it=
                                        find(node[id].Min_Two_Hop_Set[j].Two_Hop_Link.begin(),node[id].Min_Two_Hop_Set[j].Two_Hop_Link.end(),
                                        node[id].Min_Two_Hop_Set[node[id].max_cycle_path.at(cmp_index)].id);
                        if(it != node[id].Min_Two_Hop_Set[j].Two_Hop_Link.end())
                        {
                            remove_node.push_back(node[id].max_cycle_path.at(cmp_index));
                        }
                    }
                }
            }
        }
        if(remove_node.size()>0)
        {
            for(int i=0;i<remove_node.size();i++)
            {
                vector<int>::iterator pos= remove(node[id].cycle_path.begin(),node[id].cycle_path.end(),remove_node.at(i));
                node[id].cycle_path.erase(pos,node[id].cycle_path.end());

            }
        }
    }
    node[id].max_cycle_path=node[id].cycle_path;
    if(node[id].max_cycle_path.size()<=6)
    {
        vector<int>remove_node;
        for(int i=0;i<node[id].max_cycle_path.size();i++)
        {
            int cmp_index=(i+2)%node[id].max_cycle_path.size();
            if(cmp_index!=1)
            {
                for(int j=0;j<node[id].Min_Two_Hop_Set.size();j++)
                {
                    if(node[id].Min_Two_Hop_Set[j].id==node[id].Min_Two_Hop_Set[node[id].max_cycle_path.at(i)].id)
                    {
                        vector<int>::iterator it=
                                        find(node[id].Min_Two_Hop_Set[j].Two_Hop_Link.begin(),node[id].Min_Two_Hop_Set[j].Two_Hop_Link.end(),
                                             node[id].Min_Two_Hop_Set[node[id].max_cycle_path.at(cmp_index)].id);
                        if(it != node[id].Min_Two_Hop_Set[j].Two_Hop_Link.end())
                        {
                            remove_node.push_back(node[id].max_cycle_path.at(cmp_index));
                        }
                    }
                }
            }
        }
        if(remove_node.size()>0)
        {
            for(int i=0;i<remove_node.size();i++)
            {
                vector<int>::iterator pos= remove(node[id].cycle_path.begin(),node[id].cycle_path.end(),remove_node.at(i));
                node[id].cycle_path.erase(pos,node[id].cycle_path.end());

            }
        }
    }

}
//---------------------------------------------------------------------------
bool BoundaryDetection::ShowPath(int x,int y)
{ 
    for(int i=0;i<node_number;i++)
    {
        int xx=node[i].coordinate_x+communication_range;
        int yy=node[i].coordinate_y+communication_range;
        if(x==xx && y==yy)
        {
            ShowMessage(node[i].status);
            ShowMessage(i);
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Find_Other_Boundary_Node(int FromID)
{

    for(int i=0;i<node[FromID].One_Hop_ID.size();i++)
    {
        if(node[node[FromID].One_Hop_ID.at(i)].status=="not test")
        {
            Determine_Boundary_Node_2(node[FromID].One_Hop_ID.at(i));
            if(node[node[FromID].One_Hop_ID.at(i)].status=="boundary")
            {
                Find_Other_Boundary_Node(node[FromID].One_Hop_ID.at(i));
            }
                             }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Draw_Node()
{
    for(int i=0;i<node_number;i++)
    {
        if(node[i].status=="not test")
        {
            Form1->Image3->Canvas->Font->Size=3;
            Form1->Image3->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"■");     //other node
        }
        if(node[i].status=="not boundary")
        {
            Form1->Image3->Canvas->Font->Size=5;
            Form1->Image3->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"▲");     //not boundary node
        }
        if(node[i].status=="boundary")
        {
            Form1->Image3->Canvas->Font->Size=5;
            Form1->Image3->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"★");     //boundary node
        }
    }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Count_Boundary(int FromID,int Ancestor)
{
        if(node[FromID].status=="boundary")
        {
            node[FromID].PathRoot=Ancestor;
            for(int i=0;i<node[FromID].One_Hop_ID.size();i++)
            {
                if(node[node[FromID].One_Hop_ID.at(i)].status=="boundary" && node[node[FromID].One_Hop_ID.at(i)].isAddToPath==false)
                {
                    node[node[FromID].One_Hop_ID.at(i)].PathRoot=Ancestor;
                    node[node[FromID].One_Hop_ID.at(i)].isAddToPath=true;
                    Count_Boundary(node[FromID].One_Hop_ID.at(i),Ancestor);
                }
            }
        }
}
//---------------------------------------------------------------------------
void BoundaryDetection::Count_Ancestor()
{

    vector<int> Boundary_Count_tmp;
    for(int i=0;i<node_number;i++)
    {
        if(node[i].status=="boundary")
            total_boundary_node++;
        Boundary_Count_tmp.push_back(node[i].PathRoot);
    }
    sort(Boundary_Count_tmp.begin(),Boundary_Count_tmp.end());         
    Boundary_Count_tmp.erase(unique(Boundary_Count_tmp.begin(), Boundary_Count_tmp.end()), Boundary_Count_tmp.end()); 
    for(int i=0;i<Boundary_Count_tmp.size();i++)
    {
        if(node[Boundary_Count_tmp.at(i)].status=="boundary")
        {
            Boundary_Count.push_back(Boundary_Count_tmp.at(i));
        }
    }

    TColor *boundary_color;
    boundary_color=new TColor[100];
    boundary_color[0]=RGB(64,0,64);
    boundary_color[1]=RGB(115,115,0);
    boundary_color[2]=RGB(255,128,0);
    boundary_color[3]=RGB(0,0,255);
    randomize();
    for(int i=4;i<100;i++)
    {
                 boundary_color[i]=RGB(random(255),random(255),random(255));
             }
    int bc=Boundary_Count.size();
    int *final_boundary=new int[Boundary_Count.size()];
    for(int j=0;j<Boundary_Count.size();j++)
                 final_boundary[j]=0;
    for(int i=0;i<node_number;i++)
    {
        if(node[i].isAddToPath==true)     // boundary node
        {
            for(int j=0;j<Boundary_Count.size();j++)
            {
                if(node[i].PathRoot==Boundary_Count.at(j))
                {
                    Form1->Image4->Canvas->Font->Size=5;
                    Form1->Image4->Canvas->Font->Color=boundary_color[j];
                    Form1->Image4->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"★");     //boundary nod

                    Form1->Image7->Canvas->Font->Size=5;
                    Form1->Image7->Canvas->Font->Color=boundary_color[j];
                    Form1->Image7->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"★");     //boundary nod
                    final_boundary[j]++;
                                                             }
            }
        }
    }
    vector<int> Count_Boundary_Node;
    for(int i=0;i<node_number;i++)
    {
        if(node[i].isAddToPath==true)     // boundary node
        {
            for(int j=0;j<Boundary_Count.size();j++)
            {
                if(node[i].PathRoot==Boundary_Count.at(j))
                {
                    if(final_boundary[j]>3)
                    {

                        Count_Boundary_Node.push_back(final_boundary[j]);
                        Form1->Image8->Canvas->Font->Size=5;
                        Form1->Image8->Canvas->Font->Color=boundary_color[j];
                        Form1->Image8->Canvas->TextOutA(node[i].coordinate_x+communication_range-3,node[i].coordinate_y+communication_range-6,"★");     //boundary node
                                     }
                             }
            }
        }
    }
    sort(Count_Boundary_Node.begin(),Count_Boundary_Node.end());         
    Count_Boundary_Node.erase(unique(Count_Boundary_Node.begin(), Count_Boundary_Node.end()), Count_Boundary_Node.end()); 
    Form1->Memo10->Text=Form1->Memo10->Text+"G="+IntToStr(group_number)+"\tTotal Holes:\t"+ IntToStr(Count_Boundary_Node.size()-1);
    for(int i=0;i<Count_Boundary_Node.size();i++)
    {
        Form1->Memo10->Text=Form1->Memo10->Text+"\t"+IntToStr(Count_Boundary_Node.at(i));
    }
    Form1->Memo10->Lines->Add("");
    Form1->Memo10->Lines->SaveToFile(Form1->OpenDialog2->FileName);
    total_boundary=Boundary_Count.size();
}
//---------------------------------------------------------------------------
void BoundaryDetection::Count_Local_Minimum_Number()
{
    int min_flag;

    for(int i=0;i<node_number;i++)
    {
        min_flag=0;
        if(node[i].status=="boundary")
        {
            for(int j=0;j<node[i].One_Hop_ID.size();j++)
            {
                if(node[node[i].One_Hop_ID.at(j)].status=="boundary")
                    if(node[i].Node_ID > node[node[i].One_Hop_ID.at(j)].Node_ID)
                        min_flag=1;
            }
            if(min_flag==0)
            {
                local_minimum_id_count++;
                min_str=min_str+IntToStr(i)+" ";
                Local_Min_Count.push_back(i);
            }
        }
    }
    for(int k=0;k<Local_Min_Count.size();k++)
    {
        Form1->Image7->Canvas->Font->Size=5;
        Form1->Image7->Canvas->Font->Color=clRed;
        Form1->Image7->Canvas->TextOutA(node[Local_Min_Count.at(k)].coordinate_x+communication_range-3,node[Local_Min_Count.at(k)].coordinate_y+communication_range-6,"★");     //boundary nod
        Form1->Image7->Canvas->TextOutA(node[Local_Min_Count.at(k)].coordinate_x,node[Local_Min_Count.at(k)].coordinate_y,IntToStr(Local_Min_Count.at(k)));     //boundary nod
    }
}
//---------------------------------------------------------------------------

Leave a Reply