//公用调用接口,计算聚类相关三个参数 public void Calculate(pNet curNetwork) { CalCluster(curNetwork); CalLoop(curNetwork); CalClose(curNetwork); CalAverage(curNetwork); }
//K-Shell核心算法 void CalKShell(pNet curNetwork) { int intCount, intLevel; List<int> intTarget; intCount = InitState(ref curNetwork); intLevel = 1; intTarget = new List<int>(); while (intCount < curNetwork.intNumber) { intTarget.Clear(); foreach (pNode curNode in curNetwork.Network) { if(curNode.State == -1 && curNode.Degree == intLevel) {//选中度和当前级别相等的,并没有赋值的节点 curNode.State = intLevel; intCount += 1; intTarget.Add(curNode.Number); } } if (intTarget.Count == 0) {//当前循环没有节点则增加一级 intLevel += 1; } else {//选中的节点,删除所有连边 DeleteEdges(intTarget, ref curNetwork); intLevel = 0; } } foreach (pNode curNode in curNetwork.Network) { intKShell[curNode.Number] = curNode.State; } }
//PageRank核心算法 void CalPageRank(pNet curNetwork) { int i; double dubPiece; //遍历网络节点 foreach (pNode curNode in curNetwork.Network) { if (curNode.Degree == 0) { newPageRank[curNode.Number] = dubPageRank[curNode.Number]; } else {//将值分给朋友 dubPiece = dubPageRank[curNode.Number] / curNode.Degree; foreach (Edge edge in curNode) { newPageRank[edge.Target] += dubPiece; } } } for (i = 0; i < curNetwork.intNumber; i++) { dubPageRank[i] = newPageRank[i]; newPageRank[i] = 0.0; } }
//公开接口函数 public void Calculate(pNet curNetwork, int iTime) { int i; for (i = 0; i < iTime; i++) { CalPageRank(curNetwork); } }
public DiaParameter(FrmMain owner) { InitializeComponent(); //设置FrmMain为父窗体,可以读取父窗体数据 father = owner; XmlDocument doc = father.ComplexNet.ToXML(); curNetwork = new pNet(doc); }
//计算最短路径 void CalSmallPaths(pNet curNetwork) { int i, j; for (i = 0; i < curNetwork.intNumber; i++) { CalPath(i, ref curNetwork); //以每个节点为起点,向其他点传播信息,获得距离 for (j = 0; j < curNetwork.intNumber; j++) { intDistance[i, j] = curNetwork.Network[j].State; curNetwork.Network[j].State = 0; } } }
//计算聚类系数 void CalCluster(pNet curNetwork) { int intLeft, intRight; int intTotal, intSum, intUnit, intRes; double sngCluster; foreach (pNode curNode in curNetwork.Network)//遍历每个节点 { intSum = 0; intTotal = 0; foreach (Edge edge1 in curNode)//遍历当前节点的所有邻居 { intLeft = edge1.Target; intUnit = (int)Math.Ceiling(edge1.Value); foreach (Edge edge2 in curNode)//遍历当前节点的所有邻居 { intRight = edge2.Target; intUnit += (int)Math.Ceiling(edge2.Value); if (intRight == intLeft)//相等跳过 { continue; } intRes = (int)Math.Ceiling(IsFriend(intLeft, intRight, curNetwork.Network)); if (intRes == -1)//不相邻则加上当前边的权重 { intTotal += intUnit; } else//相邻则加上当前边的权重和返回权重 { intUnit += intRes; intTotal += intUnit; intSum += intUnit; } } } if (intTotal == 0)//防止除零 { sngCluster = 0.0; } else { sngCluster = intSum * 1.0 / intTotal; } dubCluster[curNode.Number] = sngCluster; } }
//节点状态初始化函数 int InitState(ref pNet curNetwork) { int intCount = 0; foreach (pNode curNode in curNetwork.Network) { if (curNode.Degree == 0) { curNode.State = 0; intCount++; } else { curNode.State = -1; } } return intCount; }
//广度优先搜索计算路径 void CalPath(int iSource, ref pNet curNetwork) { int intLevel = 1, intSource, intMaster, intTarget, intRound; foreach (pNode curNode in curNetwork.Network) { if (curNode.Number != iSource) { curNode.State = -1; } } intSource = iSource; intMaster = intSource; curNetwork.Network[intSource].State = 0; foreach (Edge edge in curNetwork.Network[intSource])//对初始节点的第一层外围节点进行初始化 { intTarget = edge.Target; curNetwork.Network[intTarget].State = intLevel; } while (true)//循环向周围节点(未得到信息)传播,直到不再有节点收到数据包 { intRound = 0; foreach (pNode curNode in curNetwork.Network) { if (curNode.State == intLevel) { intSource = curNode.Number; foreach (Edge edge in curNode) { intTarget = edge.Target; if (curNetwork.Network[intTarget].State == -1 && intTarget != intMaster) { curNetwork.Network[intTarget].State = intLevel + 1; intRound++; } } } } if (intRound == 0) {//本次没有一个新节点被处理,则认为传播完毕 break; } intLevel += 1; } }
//计算环路系数 void CalLoop(pNet curNetwork) { double sngResult = 0.0; int intDeg = 0; int intDown = 0; int intDistance = 0; double sngUp = 0; foreach(pNode curNode in curNetwork.Network) { intDeg = curNode.Degree; sngUp = 0.0; sngResult = 0.0; intDown = 1; if (intDeg == 0 || intDeg == 1) { dubLoop[curNode.Number] = 1.0; continue; } foreach (Edge edge1 in curNode) { foreach (Edge edge2 in curNode) { if (edge1.Target != edge2.Target) { intDistance = CalDistance(edge1.Target, edge2.Target, curNode.Number, curNetwork); if (intDistance == 1) { sngUp += 1.0 / intDistance; } else if (intDistance != -1) { sngUp += 1.0 / intDistance; } else { sngUp += 0; } } } } intDown = intDeg * (intDeg - 1); sngResult = sngUp / intDown; dubLoop[curNode.Number] = sngResult; } }
//计算平均值 void CalAverage(pNet curNetwork) { double totalCluster = 0; double totalLoop = 0; double totalClose = 0; if (curNetwork.intNumber == 0) { AveCluster = 0; AveLoop = 0; AveClose = 0; } for (int i = 0; i < curNetwork.intNumber; i++) { totalCluster += dubCluster[i]; totalLoop += dubLoop[i]; totalClose += dubClose[i]; } AveCluster = totalCluster / (curNetwork.intNumber * 1.0); AveLoop = totalLoop / (curNetwork.intNumber * 1.0); AveClose = totalClose / (curNetwork.intNumber * 1.0); }
//计算接近中心度 void CalClose(pNet curNetwork) { int[,] intDistance; int intCount, intSum; DistanceStrategy disStrategy = new DistanceStrategy(curNetwork.Number); disStrategy.Calculate(curNetwork); intDistance = disStrategy.Distance; foreach(pNode sourNode in curNetwork.Network) { intSum = 0; intCount = 0; foreach(pNode tarNode in curNetwork.Network) { if (intDistance[sourNode.Number,tarNode.Number] > 0) { intCount += 1; intSum += intDistance[sourNode.Number, tarNode.Number]; } } if (intSum == 0) { dubClose[sourNode.Number] = 0; } else { dubClose[sourNode.Number] = intCount * 1.0d / intSum; } } }
//节点状态初始化 void InitState(int iValue, ref pNet curNetwork) { foreach(pNode curNode in curNetwork.Network) { curNode.State = iValue; } }
//连边删除 void DeleteEdges(List<int> Source, ref pNet curNetwork) { List<int> Target; foreach (int iNum in Source) { Target = new List<int>(); //不能再foreach内部改变节点的连边,只能先记录下来 foreach (Edge edge in curNetwork.Network[iNum]) { Target.Add(edge.Target); } //依据记录结果删除连边 foreach (int intTarget in Target) { curNetwork.DecEdge(iNum, intTarget); } } }
//公用调用接口,计算距离相关三个参数 public void Calculate(pNet curNetwork) { CalSmallPaths(curNetwork); CalAveDistance(curNetwork.Number); CalDiameter(curNetwork.Number); }
//信息传播方法,计算两点间距离 int CalDistance(int iSource, int iTarget, int iMask, pNet curNetwork) { int intLevel = 0; int intTarget = 0, intRound; if (iSource == iTarget) { return 0; } InitState(-1, ref curNetwork); curNetwork.Network[iSource].State = 0; foreach (Edge edge in curNetwork.Network[iSource]) { intTarget = edge.Target; if (intTarget == iTarget) { return 1; } if (intTarget == iMask) { continue; } curNetwork.Network[intTarget].State = 1; } intLevel = 1; while (true)//循环向周围节点(未得到信息)传播,直到不再有节点收到数据包 { intRound = 0; foreach (pNode curNode in curNetwork.Network) { if (curNode.State == intLevel) { foreach (Edge edge in curNode) { intTarget = edge.Target; if (curNetwork.Network[intTarget].State == -1 && intTarget != iSource) { curNetwork.Network[intTarget].State = intLevel + 1; intRound++; } if (intTarget == iTarget) { return intLevel; } if (intTarget == iMask) { continue; } } } } if (intRound == 0) {//本次没有一个新节点被处理,则认为传播完毕 break; } intLevel += 1; } return -1; }
//公开接口函数 public void Calculate(pNet curNetwork) { CalKShell(curNetwork); }