// This is experimental (for now at least), trying to see if we can swap edges and change assortativity while // maintaining the degree vector, really need to reorganize this part. Would move it to a new class that inherits // from Graph, but I want to use it in ER and BA.. public bool SwapRandomEdgesToIncreaseAssortativity() { Randomizer rand = new Randomizer(); var edges = EdgesAsNodes.ToList(); var e1 = edges[rand.Next(edges.Count)]; var e2 = edges[rand.Next(edges.Count)]; if (e1.Item1 == e2.Item1 || e1.Item1 == e2.Item2 || e1.Item2 == e2.Item1 || e1.Item2 == e2.Item2) { return(false); } var currVal = ((double)Math.Max(e1.Item1.Degree, e1.Item2.Degree) / Math.Min(e1.Item1.Degree, e1.Item2.Degree) + (double)Math.Max(e2.Item1.Degree, e2.Item2.Degree) / Math.Min(e2.Item1.Degree, e2.Item2.Degree)) / 2.0; var e1Ae2A = ((double)Math.Max(e1.Item1.Degree, e2.Item1.Degree) / Math.Min(e1.Item1.Degree, e2.Item1.Degree) + (double)Math.Max(e1.Item2.Degree, e2.Item2.Degree) / Math.Min(e1.Item2.Degree, e2.Item2.Degree)) / 2.0; var e1Ae2B = ((double)Math.Max(e1.Item1.Degree, e2.Item2.Degree) / Math.Min(e1.Item1.Degree, e2.Item2.Degree) + (double)Math.Max(e1.Item2.Degree, e2.Item1.Degree) / Math.Min(e1.Item2.Degree, e2.Item1.Degree)) / 2.0; String oldDegSeq = String.Join(",", DegreeVector); if (e1Ae2A < currVal && e1Ae2A < e1Ae2B && !e1.Item1.Neighbors.Contains(e2.Item1) && !e1.Item2.Neighbors.Contains(e2.Item2)) { RemoveEdge(e1.Item1, e1.Item2); RemoveEdge(e2.Item1, e2.Item2); AddEdge(e1.Item1, e2.Item1); AddEdge(e1.Item2, e2.Item2); if (oldDegSeq != String.Join(",", DegreeVector)) { throw new Exception("Holy cow"); } return(true); } else if (e1Ae2B < currVal && e1Ae2B < e1Ae2A && !e1.Item1.Neighbors.Contains(e2.Item2) && !e1.Item2.Neighbors.Contains(e2.Item1)) { RemoveEdge(e1.Item1, e1.Item2); RemoveEdge(e2.Item1, e2.Item2); AddEdge(e1.Item1, e2.Item2); AddEdge(e1.Item2, e2.Item1); if (oldDegSeq != String.Join(",", DegreeVector)) { throw new Exception("Holy cow"); } return(true); } return(false); }
public double GraphAssortativity2() { cacheIsEmpty = false; if (!Double.IsNegativeInfinity(_graphAssortativity2)) { return(_graphAssortativity2); } if (ExcessDegreeVariance == 0) // All vertices are the same degree, automatically perfect assortativity { return(_graphAssortativity2 = 1.0); } double M = Edges.Count(); double numerator = ((1 / M) * (EdgesAsNodes.Sum(e => e.Item1.Degree * e.Item2.Degree)) - Math.Pow((1 / M) * 0.5 * EdgesAsNodes.Sum(e => e.Item1.Degree + e.Item2.Degree), 2.0)); double denominator = ((1 / M) * 0.5 * EdgesAsNodes.Sum(e => Math.Pow(e.Item1.Degree, 2) + Math.Pow(e.Item2.Degree, 2)) - Math.Pow((1 / M) * 0.5 * EdgesAsNodes.Sum(e => e.Item1.Degree + e.Item2.Degree), 2.0)); return(_graphAssortativity2 = numerator / denominator); }
public void IterativelySwapEdgesToDecreaseAssortativity() { var edges = EdgesAsNodes.OrderByDescending(e => LocalAssort(e)).ToList(); while (edges.Count > 1) { var e1 = edges[0]; edges.Remove(e1); var otherEdges = edges.Where( e2 => e1.Item1 != e2.Item1 && e1.Item1 != e2.Item2 && e1.Item2 != e2.Item1 && e1.Item2 != e2.Item2).ToList(); var currVal = LocalAssort(e1); var currMaxImprovement = 0.0; Tuple <Node, Node> currMaxEdge = null; EdgeSwap bestEdgeSwap = EdgeSwap.e1Ae2A_e1Be2B; // just need to assign something.. foreach (var e2 in otherEdges) { double improvement; if (!e1.Item1.Neighbors.Contains(e2.Item1) && !e1.Item2.Neighbors.Contains(e2.Item2)) { improvement = currVal - (LocalAssort(new Tuple <Node, Node>(e1.Item1, e2.Item1)) + LocalAssort(new Tuple <Node, Node>(e1.Item2, e2.Item2))) / 2.0; if (improvement > currMaxImprovement) { currMaxImprovement = improvement; currMaxEdge = e2; bestEdgeSwap = EdgeSwap.e1Ae2A_e1Be2B; } } if (!e1.Item1.Neighbors.Contains(e2.Item2) && !e1.Item2.Neighbors.Contains(e2.Item1)) { improvement = currVal - (LocalAssort(new Tuple <Node, Node>(e1.Item1, e2.Item2)) + LocalAssort(new Tuple <Node, Node>(e1.Item2, e2.Item1))) / 2.0; if (improvement > currMaxImprovement) { currMaxImprovement = improvement; currMaxEdge = e2; bestEdgeSwap = EdgeSwap.e1Ae2B_e1Be2A; } } } if (currMaxEdge != null) { if (bestEdgeSwap == EdgeSwap.e1Ae2A_e1Be2B) { AddEdge(e1.Item1, currMaxEdge.Item1); AddEdge(e1.Item2, currMaxEdge.Item2); } else { AddEdge(e1.Item1, currMaxEdge.Item2); AddEdge(e1.Item2, currMaxEdge.Item1); } RemoveEdge(e1.Item1, e1.Item2); RemoveEdge(currMaxEdge.Item1, currMaxEdge.Item2); edges.Remove(currMaxEdge); } } }