//[TestMethod] //public void InverseFloyWarshall10Test() //{ // // Make a random 5-node undirected graph with designated connected components. // // Computes transitive closure of using Floyd-Warshall // InverseFWTest("IFW10", new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }); //} //[TestMethod] //public void InverseFloyWarshall20Test() //{ // // Make a random 5-node undirected graph with designated connected components. // // Computes transitive closure of using Floyd-Warshall // InverseFWTest("IFW20", new[] // { // "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", // "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" // }); //} private static void InverseFWTest(string name, string[] vertices) { var p = new Problem(name); var adjacent = Predicate <string, string>("adjacent"); var floyd = Predicate <string, string, int>("d"); // Inlines either adjacent or floyd, depending on k Proposition D(string v1, string v2, int k) => k == 0 ? adjacent(v1, v2) : floyd(v1, v2, k); for (int k = 1; k < vertices.Length; k++) { var vk = vertices[k]; foreach (var v1 in vertices) { foreach (var v2 in vertices) { p.Assert( D(v1, v2, k) <= D(v1, v2, k - 1), D(v1, v2, k) <= (D(v1, vk, k - 1) & D(vk, v2, k - 1)) ); } } } Proposition Connected(string v1, string v2) => D(v1, v2, vertices.Length - 1); // Now constrain its connectivity foreach (var v1 in vertices) { foreach (var v2 in vertices) { if (v1 == v2 || (v1 != "e" && v2 != "e")) { p.Assert(Connected(v1, v2)); } else { p.Assert(Not(Connected(v1, v2))); } } } p.Optimize(); for (int i = 0; i < 100; i++) { var s = p.Solve(); // a, b, c, d should be a connected component, e should be unconnected to anything but e foreach (var v1 in vertices) { foreach (var v2 in vertices) { Assert.IsTrue(s[Connected(v1, v2)] == (v1 == v2) || (v1 != "e" && v2 != "e")); } } } p.LogPerformanceData(); }