/// <summary>
 /// 质心算法
 /// </summary>
 /// <param name="nodeList"></param>
 /// <param name="j">质心算法中取j跳范围内的信标节点帮助计算</param>
 public static void CenterOfMass_algorithm(NodeList nodeList, int j)
 {
     List<Node> generalNodeList = nodeList.GetAllGeneralNode();
     foreach (GeneralNode gn in generalNodeList)
     {
         //循环,进行定位
         List<Node> AssistLocateNodeList = new List<Node>();
         //将信标节点加入到协助定位的节点列表中
         foreach (int nodeId in gn.HopCountTable.Keys)
         {
             if (nodeList.GetNodeById(nodeId).IsBeaconNode && gn.HopCountTable[nodeId] <= j)
             {
                 AssistLocateNodeList.Add(nodeList.GetNodeById(nodeId));
             }
         }
         if (AssistLocateNodeList.Count >= 1)
         {
             double sumEstimatedX = 0d;
             double sumEstimatedY = 0d;
             foreach (BeaconNode bn in AssistLocateNodeList)
             {
                 sumEstimatedX += bn.RealX;
                 sumEstimatedY += bn.RealY;
             }
             gn.IsLocatable = true;
             gn.IsAlreadyLocated = true;
             gn.EstimatedX = sumEstimatedX / AssistLocateNodeList.Count;
             gn.EstimatedY = sumEstimatedY / AssistLocateNodeList.Count;
         }
     }
 }
 static void Main(string[] args)
 {
     for (int i = 0; i < 20; i++)
     {
         NodeList nodeList = new NodeList(20, 80, 15, 100, 100);
         AlgorithmFunction.AlgorithmPreparation(nodeList, 15);
         ////质心算法
         //AlgorithmFunction.CenterOfMass_algorithm(nodeList, 1);
         //DataExport.DataExportToExcel(nodeList, @"d:/COM.xls");
         ////DV-Hop算法
         List<Node> generalNodeList = nodeList.GetAllGeneralNode();
         foreach (GeneralNode gn in generalNodeList)
         {
             gn.EstimatedX = gn.EstimatedY = 0d;
             gn.IsLocatable = gn.IsAlreadyLocated = false;
         }
         AlgorithmFunction.DV_Hop_algorithm(nodeList);
         DataExport.DataExportToExcel(nodeList, @"d:/DV-Hop.xls");
         //Revised DV-Hop算法
         foreach (GeneralNode gn in generalNodeList)
         {
             gn.EstimatedX = gn.EstimatedY = 0d;
             gn.IsLocatable = gn.IsAlreadyLocated = false;
         }
         AlgorithmFunction.Revised_DV_Hop_algorithm(nodeList, 5);
         DataExport.DataExportToExcel(nodeList, @"d:/Revised-DV-Hop.xls");
     }
     Console.WriteLine("==========Done==========");
     Console.ReadKey();
 }
 /// <summary>
 /// 将实验结果数据导出到Excel中
 /// </summary>
 /// <param name="filePath">文件路径</param>
 public static void DataExportToExcel(NodeList nodeList, string filePath)
 {
     List<Node> generalNodeList = nodeList.GetAllGeneralNode();
     IWorkbook workBook = new HSSFWorkbook((new FileStream(filePath, FileMode.Open)));
     ISheet sheet = workBook.GetSheetAt(0);
     int rowCount = sheet.LastRowNum ;
     for (int i = rowCount; i < generalNodeList.Count + rowCount; i++)
     {
         int connectivity = 0;
         //计算节点连通度
         foreach (int value in generalNodeList[i - rowCount].HopCountTable.Values)
         {
             if (value == 1)
             {
                 connectivity++;
             }
         }
         //创建第i行
         IRow row = sheet.CreateRow(i+1);
         //8列,分别为节点ID、通信半径、连通度、实际坐标X、实际坐标Y、估计坐标X、估计坐标Y
         ICell cell0 = row.CreateCell(0, CellType.NUMERIC);
         cell0.SetCellValue(generalNodeList[i - rowCount].Id);
         ICell cell1 = row.CreateCell(1, CellType.NUMERIC);
         cell1.SetCellValue(generalNodeList[i - rowCount].CommunicationRadius);
         ICell cell2 = row.CreateCell(2, CellType.NUMERIC);
         cell2.SetCellValue(connectivity);
         ICell cell3 = row.CreateCell(3, CellType.NUMERIC);
         cell3.SetCellValue(generalNodeList[i - rowCount].RealX);
         ICell cell4 = row.CreateCell(4, CellType.NUMERIC);
         cell4.SetCellValue(generalNodeList[i - rowCount].RealY);
         ICell cell5 = row.CreateCell(5, CellType.BOOLEAN);
         cell5.SetCellValue(((GeneralNode)generalNodeList[i - rowCount]).IsAlreadyLocated);
         ICell cell6 = row.CreateCell(6, CellType.NUMERIC);
         cell6.SetCellValue(((GeneralNode)generalNodeList[i - rowCount]).EstimatedX);
         ICell cell7 = row.CreateCell(7, CellType.NUMERIC);
         cell7.SetCellValue(((GeneralNode)generalNodeList[i - rowCount]).EstimatedY);
     }
     //文件保存
     using (Stream s = File.OpenWrite(filePath))
     {
         workBook.Write(s);
         Console.WriteLine("Data Export Success!");
     }
 }
        /// <summary>
        /// 传统DV-Hop算法计算hopSize
        /// </summary>
        /// <param name="nodeList"></param>
        public static void DV_Hop_algorithm(NodeList nodeList)
        {
            List<Node> generalNodeList = nodeList.GetAllGeneralNode();
            foreach (GeneralNode gn in generalNodeList)
            {
                //遍历每个未知节点,求跳距
                Dictionary<int, int> beaconNodeDic = new Dictionary<int, int>();
                //取得所有与未知节点可以通信的信标节点
                foreach (int key in gn.HopCountTable.Keys)
                {
                    if (nodeList.GetNodeById(key).IsBeaconNode)
                    {
                        beaconNodeDic.Add(key, gn.HopCountTable[key]);
                    }
                }
                //找到beaconNodeDic中与未知节点跳数最小的信标节点
                int shortestHop = int.MaxValue;
                int shortestHopNodeId = -1;
                foreach (int key in beaconNodeDic.Keys)
                {
                    if (beaconNodeDic[key] < shortestHop)
                    {
                        shortestHop = beaconNodeDic[key];
                        shortestHopNodeId = key;
                    }
                }
                Node nearestBeaconNode = nodeList.GetNodeById(shortestHopNodeId);
                //找出能与nearestBeaconNode信标节点通信的其他信标节点
                Dictionary<int, int> assistLocateBeaconNodeDic = new Dictionary<int, int>();
                if (nearestBeaconNode == null)
                {
                    //如果没有能与其通信的信标节点
                    gn.IsLocatable = false;
                    gn.IsAlreadyLocated = false;
                }
                else
                {
                    foreach (int id in nearestBeaconNode.HopCountTable.Keys)
                    {
                        if (nodeList.GetNodeById(id).IsBeaconNode)
                        {
                            assistLocateBeaconNodeDic.Add(id, nearestBeaconNode.HopCountTable[id]);
                        }
                    }
                    //计算hopsize
                    double sumDistance = 0d;
                    int sumHop = 0;
                    foreach (int nodeId in assistLocateBeaconNodeDic.Keys)
                    {
                        sumDistance += CalculateNodeDistance(nearestBeaconNode, nodeList.GetNodeById(nodeId));
                        sumHop += CalculateNodeHop(nearestBeaconNode, nodeList.GetNodeById(nodeId));
                    }
                    gn.DV_Hop_Hopsize = sumDistance / sumHop;
                    //利用三边测量法定位
                    List<Node> assistLocateBeaconNode = new List<Node>();
                    foreach (int key in gn.HopCountTable.Keys)
                    {
                        if (nodeList.GetNodeById(key).IsBeaconNode && assistLocateBeaconNode.Count < 3)
                        {
                            assistLocateBeaconNode.Add(nodeList.GetNodeById(key));
                        }
                    }
                    //判断信标节点数量,若小于3,则无法进行定位
                    if (assistLocateBeaconNode.Count < 3)
                    {
                        gn.IsLocatable = false;
                    }
                    else
                    {
                        //三边测量法定位
                        double[] pos = Three_edge_measurement.trilateration(assistLocateBeaconNode[0].RealX, assistLocateBeaconNode[0].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[0]), assistLocateBeaconNode[1].RealX, assistLocateBeaconNode[1].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[1]), assistLocateBeaconNode[2].RealX, assistLocateBeaconNode[2].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[2]));
                        gn.EstimatedX = pos[0];
                        gn.EstimatedY = pos[1];
                        if (gn.EstimatedX < 0)
                        {
                            gn.EstimatedX = 0;
                        }
                        if (gn.EstimatedY < 0)
                        {
                            gn.EstimatedY = 0;
                        }
                        if (gn.EstimatedX > 100)
                        {
                            gn.EstimatedX = 100;
                        }
                        if (gn.EstimatedY > 100)
                        {
                            gn.EstimatedY = 100;
                        }
                        gn.IsLocatable = true;
                        gn.IsAlreadyLocated = true;
                    }
                }

            }
        }
 /// <summary>
 /// 定位未知节点
 /// </summary>
 /// <param name="nodeList"></param>
 private static void LocateGeneralNode(NodeList nodeList, int k)
 {
     //取得所有未知节点,遍历并定位
     List<Node> generalNodeList = nodeList.GetAllGeneralNode();
     foreach (GeneralNode gn in generalNodeList)
     {
         //辅助DV-Hop算法定位节点集合
         List<Node> assistLocateBeaconNode = new List<Node>();
         //辅助质心算法定位节点集合
         List<Node> assistCOMLocateNodeList = new List<Node>();
         foreach (int key in gn.HopCountTable.Keys)
         {
             if (nodeList.GetNodeById(key).IsBeaconNode && assistLocateBeaconNode.Count < 3)
             {
                 assistLocateBeaconNode.Add(nodeList.GetNodeById(key));
             }
             if (nodeList.GetNodeById(key).IsBeaconNode && gn.HopCountTable[key] == 1)
             {
                 assistCOMLocateNodeList.Add(nodeList.GetNodeById(key));
             }
         }
         if (assistCOMLocateNodeList.Count >= k)
         {
             //信标节点数量大于事先设定阈值,使用质心算法定位
             double sumEstimatedX = 0d;
             double sumEstimatedY = 0d;
             foreach (BeaconNode bn in assistCOMLocateNodeList)
             {
                 sumEstimatedX += bn.RealX;
                 sumEstimatedY += bn.RealY;
             }
             gn.IsLocatable = true;
             gn.IsAlreadyLocated = true;
             gn.EstimatedX = sumEstimatedX / assistCOMLocateNodeList.Count;
             gn.EstimatedY = sumEstimatedY / assistCOMLocateNodeList.Count;
         }
         //判断信标节点数量,若小于3,则无法进行定位
         else if (assistLocateBeaconNode.Count < 3)
         {
             gn.IsLocatable = false;
         }
         else
         {
             //三边测量法定位
             double[] pos = Three_edge_measurement.trilateration(assistLocateBeaconNode[0].RealX, assistLocateBeaconNode[0].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[0]), assistLocateBeaconNode[1].RealX, assistLocateBeaconNode[1].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[1]), assistLocateBeaconNode[2].RealX, assistLocateBeaconNode[2].RealY, nodeList.FinalHopSize * CalculateNodeHop(gn, assistLocateBeaconNode[2]));
             gn.EstimatedX = pos[0];
             gn.EstimatedY = pos[1];
             if (gn.EstimatedX < 0)
             {
                 gn.EstimatedX = 0;
             }
             if (gn.EstimatedY < 0)
             {
                 gn.EstimatedY = 0;
             }
             if (gn.EstimatedX > 100)
             {
                 gn.EstimatedX = 100;
             }
             if (gn.EstimatedY > 100)
             {
                 gn.EstimatedY = 100;
             }
             gn.IsLocatable = true;
             gn.IsAlreadyLocated = true;
         }
     }
 }
 /// <summary>
 /// 计算未知节点加权平均每跳距离
 /// </summary>
 /// <param name="nodeList"></param>
 private static void CalculateNodeHopSize(NodeList nodeList)
 {
     List<Node> beaconNodeList = nodeList.GetAllBeaconNode();
     List<Node> generalNodeList = nodeList.GetAllGeneralNode();
     //对各个未知节点求加权平均每跳距离
     foreach (GeneralNode gn in generalNodeList)
     {
         List<Node> tempBeaconNodeList = new List<Node>();
         int sumHop = 0;
         foreach (int beaconNodeId in gn.HopCountTable.Keys)
         {
             //将gn节点HopCountTable中所有beaconNode取出放入tempBeaconNodeList中,并保存gn到所有beaconNode的跳数和
             if (nodeList.GetNodeById(beaconNodeId).IsBeaconNode == true)
             {
                 tempBeaconNodeList.Add(nodeList.GetNodeById(beaconNodeId));
                 sumHop += gn.HopCountTable[beaconNodeId];
             }
         }
         double temp = 0d;
         int tempHop = 0;
         //将tempBeaconNodeList中AvgHopDistance属性为0的节点去除
         for (int i = 0; i < tempBeaconNodeList.Count; i++)
         {
             if (((BeaconNode)tempBeaconNodeList[i]).AvgHopSize <= 0)
             {
                 tempBeaconNodeList.Remove(tempBeaconNodeList[i]);
             }
         }
         foreach (BeaconNode bn in tempBeaconNodeList)
         {
             tempHop += sumHop - CalculateNodeHop(bn, gn);
             temp += bn.AvgHopSize * (sumHop - CalculateNodeHop(bn, gn));
         }
         if (tempHop != 0)
         {
             gn.AvgHopSize = temp / tempHop;
         }
     }
 }