private static IEnumerable <(Graph <int, double, double>, Graph <int, double, double>, IHeuristic <int, double>)> generateTestCases() { var densityCount = 6; foreach (var graph1nodeCount in FibonacciGenerator()) { foreach (var graph2nodeCount in FibonacciGenerator().TakeWhile(number => number <= graph1nodeCount)) { foreach (var density1 in Enumerable.Range(1, densityCount).Select(integer => integer * 1d / densityCount)) { foreach (var density2 in Enumerable.Range(1, densityCount).Select(integer => integer * 1d / densityCount)) { foreach (var heuristic in generateAllHeuristics()) { var random1 = new Random(graph2nodeCount + graph1nodeCount * graph1nodeCount + (int)(density1 * 1000) + (int)(density2 * 100000)); var random2 = new Random(random1.Next()); Func <double> vertexAttributeGenerator1 = () => random1.NextDouble(); Func <double> vertexAttributeGenerator2 = () => random2.NextDouble(); Func <double> edgeAttributeGenerator1 = () => random1.NextDouble(); Func <double> edgeAttributeGenerator2 = () => random2.NextDouble(); var randomTemporalGraph1 = RandomGraphFactory.GenerateRandomInstance(graph1nodeCount, density1, true, vertexAttributeGenerator1, edgeAttributeGenerator1, random1); var randomTemporalGraph2 = RandomGraphFactory.GenerateRandomInstance(graph2nodeCount, density2, true, vertexAttributeGenerator2, edgeAttributeGenerator2, random2, graph1nodeCount); yield return(randomTemporalGraph1, randomTemporalGraph2, heuristic); } } } } } }
public static IEnumerable <object[]> RandomCases(string name) { var densityCount = 6; var verticesCount = 7; var offset = verticesCount; foreach (var vertexCount1 in Enumerable.Range(0, verticesCount)) { foreach (var vertexCount2 in Enumerable.Range(0, vertexCount1)) { foreach (var density1 in Enumerable.Range(1, densityCount).Select(integer => integer * 1d / densityCount)) { foreach (var density2 in Enumerable.Range(1, densityCount).Select(integer => integer * 1d / densityCount)) { var random = new Random(vertexCount1 + verticesCount * vertexCount2 + (int)(density1 * 1000) + (int)(density2 * 100000)); var random2 = new Random(random.Next()); var random3 = new Random(random.Next()); Func <double> edgeAttributeGenerator = () => random.NextDouble(); var graph1 = RandomGraphFactory.GenerateRandomInstance(vertexCount1, density1, true, () => 0, edgeAttributeGenerator, random2, allowLoops: false); var graph2 = RandomGraphFactory.GenerateRandomInstance(vertexCount1, density2, true, () => 0, edgeAttributeGenerator, random2, allowLoops: false, vertexOffset: offset); yield return(new object[] { $"VertexCount1: {vertexCount1}, density1: {density1:0.00}, vertexCount2: {vertexCount2}, density2: {density2:0.00}", graph1, graph2 }); } } } } }
public static IEnumerable <object[]> IsomorphicGraphCases(string name) { var densityCount = 9; var verticesCount = 9; var offset = verticesCount; foreach (var heuristic in generateAllHeuristics()) { foreach (var density in Enumerable.Range(1, densityCount).Select(integer => integer * 1d / densityCount)) { foreach (var vertexCount in Enumerable.Range(2, verticesCount)) { var random = new Random(vertexCount + (int)(density * 10000)); var random2 = new Random(random.Next()); var random3 = new Random(random.Next()); Func <double> edgeAttributeGenerator = () => random.NextDouble(); var graph1 = RandomGraphFactory.GenerateRandomInstance(vertexCount, density, true, () => 0, edgeAttributeGenerator, random2, allowLoops: false); var graph2 = Transform.PermuteClone(graph1, random3, (id, attr) => (id + offset, attr), (pair, attr) => ((pair.Item1 + offset, pair.Item2 + offset), attr)); yield return(new object[] { $"VertexCount: {vertexCount}, density: {density:0.00}", heuristic, graph1, graph2 }); } } } }
static void Main(string[] args) { var random = new Random(3_14159265); Func <double> vertexAttributeGenerator = () => { return(random.NextDouble()); }; Func <double> edgeAttributeGenerator = () => { return(random.NextDouble()); }; double vertexBound = 2; double edgeBound = 3; double vertexDecay = 1; double edgeDecay = 1; Func <double, double, double, double> boundMetric = (a, bound, decay) => bound * a / (1 / decay + a); Func <double, double, double> vertexRelabel = (a1, a2) => { return(boundMetric(Math.Abs(a1 - a2), vertexBound, vertexDecay)); }; Func <double, double> vertexAdd = a => boundMetric(Math.Abs(a), vertexBound, vertexDecay); Func <double, double> vertexRemove = vertexAdd; Func <double, double, double> edgeRelabel = (a1, a2) => { return(boundMetric(Math.Abs(a1 - a2), edgeBound, edgeDecay)); }; Func <double, double> edgeAdd = a => boundMetric(Math.Abs(a), edgeBound, edgeDecay); Func <double, double> edgeRemove = edgeAdd; // Func<double, double, double> vertexRelabel = (a1, a2) => // { // return Math.Abs(a1 - a2); // }; // Func<double, double> vertexAdd = a => Math.Abs(a); // Func<double, double> vertexRemove = vertexAdd; // Func<double, double, double> edgeRelabel = (a1, a2) => // { // return Math.Abs(a1 - a2); // }; // Func<double, double> edgeAdd = a => Math.Abs(a); // Func<double, double> edgeRemove = edgeAdd; var a = new List <double>() { 0, 1, .5, 1d / 3, 2d / 3, -1, 2, 10, -10, 100, -100, 1000, -1000 }; var b = new List <double>() { 0, 1, .5, 1d / 3, 2d / 3, -1, 2, 10, -10, 100, -100, 1000, -1000 }; var RiesenBunke2009AB = (1, 1); for (int gVertices = 8; gVertices < 12; gVertices++) { var hVertices = gVertices; // for (int hVertices = gVertices; hVertices > 0; hVertices-=1) { var measurements = 0; var results = new Dictionary <(double, double), double>(); foreach (var aElement in a) { foreach (var bElement in b) { results.Add((aElement, bElement), 0); } } for (double gDensity = 1.0; gDensity > 0; gDensity -= 0.1) { for (double hDensity = gDensity; hDensity > 0; hDensity -= 0.1) { for (int iter = 0; iter < 5; iter++) { var G = RandomGraphFactory.GenerateRandomInstance( vertices: gVertices, density: gDensity, directed: true, vertexAttributeGenerator: vertexAttributeGenerator, edgeAttributeGenerator: edgeAttributeGenerator ); var H = RandomGraphFactory.GenerateRandomInstance( vertices: hVertices, density: hDensity, directed: true, vertexAttributeGenerator: vertexAttributeGenerator, edgeAttributeGenerator: edgeAttributeGenerator ); var matchingParameters = new GraphMatchingParameters <int, double, double> { aCollection = a, bCollection = b, edgeAdd = edgeAdd, vertexAdd = vertexAdd, edgeRelabel = edgeRelabel, edgeRemove = edgeRemove, vertexRemove = vertexRemove, vertexRelabel = vertexRelabel, encodingMethod = GraphEncodingMethod.Wojciechowski }; var matching = new VertexPartialMatchingNode <int, double, double>( G, H, matchingParameters ); var myRelativeError = (matching.BestUpperBound - matching.BestLowerBound) / matching.BestLowerBound; var theirRelativeError = (matching.BestUpperBound - matching.abLowerBounds[RiesenBunke2009AB]) / matching.abLowerBounds[RiesenBunke2009AB]; var eps = 1e-12; // if (theirRelativeError > eps) // { // System.Console.WriteLine($"|Vg|={gVertices}, |Eg|={gDensity:f2}, |Vh|={hVertices}, |Eh|={hDensity:f2}. My estimate / theirs {matching.LowerBound / matching.abLowerBounds[RiesenBunke2009AB]:f2}."); // } // var theirLowerBound = matching.abLowerBounds[(2d/3, .5)]; // if (theirLowerBound > eps) { measurements += 1; foreach (var kvp in matching.abLowerBounds) { // var score = (matching.UpperBound - kvp.Value) / matching.UpperBound; var score = kvp.Value > Math.Max(Math.Max( matching.abLowerBounds[(.5, .5)],