/solver/src/test/java/org/chocosolver/solver/variables/view/graph/TestGraphUnionView.java

https://github.com/chocoteam/choco3 · Java · 295 lines · 257 code · 9 blank · 29 comment · 51 complexity · 8e6468c141ef2663a4f2eac898582c01 MD5 · raw file

  1. /*
  2. * This file is part of choco-solver, http://choco-solver.org/
  3. *
  4. * Copyright (c) 2022, IMT Atlantique. All rights reserved.
  5. *
  6. * Licensed under the BSD 4-clause license.
  7. *
  8. * See LICENSE file in the project root for full license information.
  9. */
  10. package org.chocosolver.solver.variables.view.graph;
  11. import org.chocosolver.solver.ICause;
  12. import org.chocosolver.solver.Model;
  13. import org.chocosolver.solver.exception.ContradictionException;
  14. import org.chocosolver.solver.search.strategy.Search;
  15. import org.chocosolver.solver.variables.DirectedGraphVar;
  16. import org.chocosolver.solver.variables.SetVar;
  17. import org.chocosolver.solver.variables.UndirectedGraphVar;
  18. import org.chocosolver.solver.variables.delta.IGraphDeltaMonitor;
  19. import org.chocosolver.solver.variables.events.GraphEventType;
  20. import org.chocosolver.util.objects.graphs.DirectedGraph;
  21. import org.chocosolver.util.objects.graphs.GraphFactory;
  22. import org.chocosolver.util.objects.graphs.UndirectedGraph;
  23. import org.chocosolver.util.objects.setDataStructures.ISet;
  24. import org.chocosolver.util.objects.setDataStructures.SetFactory;
  25. import org.chocosolver.util.objects.setDataStructures.SetType;
  26. import org.chocosolver.util.procedure.IntProcedure;
  27. import org.chocosolver.util.procedure.PairProcedure;
  28. import org.testng.Assert;
  29. import org.testng.annotations.Test;
  30. /**
  31. * Test class for subgraphInducedByNodesView
  32. *
  33. * @author Dimitri Justeau-Allaire
  34. * @since 31/03/2021
  35. */
  36. public class TestGraphUnionView {
  37. @Test(groups = "1s", timeOut = 60000)
  38. public void testInstantiateAndGenerate() {
  39. Model m = new Model();
  40. int n = 4;
  41. UndirectedGraph LB1 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  42. UndirectedGraph UB1 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  43. UndirectedGraphVar g1 = m.graphVar("g1", LB1, UB1);
  44. UndirectedGraph LB2 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  45. UndirectedGraph UB2 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  46. UndirectedGraphVar g2 = m.graphVar("g2", LB2, UB2);
  47. //
  48. UndirectedGraphVar g3 = m.graphUnionView(g1, g2);
  49. while (m.getSolver().solve()) {
  50. for (int i = 0; i < n; i++) {
  51. boolean b = g3.getValue().containsNode(i);
  52. Assert.assertEquals(g1.getValue().containsNode(i) || g2.getValue().containsNode(i), b);
  53. if (b) {
  54. for (int j = 0; j < n; j++) {
  55. Assert.assertEquals(g1.getValue().containsEdge(i, j) || g2.getValue().containsEdge(i, j), g3.getValue().containsEdge(i, j));
  56. }
  57. }
  58. }
  59. }
  60. }
  61. @Test(groups="10s", timeOut=60000)
  62. public void testConstrained() {
  63. Model m = new Model();
  64. int n = 5;
  65. UndirectedGraph LB1 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  66. UndirectedGraph UB1 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  67. UndirectedGraphVar g1 = m.graphVar("g1", LB1, UB1);
  68. UndirectedGraph LB2 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  69. UndirectedGraph UB2 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  70. UndirectedGraphVar g2 = m.graphVar("g2", LB2, UB2);
  71. //
  72. UndirectedGraphVar g3 = m.graphUnionView(g1, g2);
  73. SetVar nodesG = m.graphNodeSetView(g3);
  74. m.member(3, nodesG).post();
  75. m.notMember(2, nodesG).post();
  76. SetVar neigh3 = m.graphNeighborsSetView(g3, 3);
  77. m.member(1, neigh3).post();
  78. m.nbNodes(g2, m.intVar(1, 4)).post();
  79. m.connected(g2).post();
  80. m.getSolver().setSearch(Search.graphVarSearch(g1, g2, g3));
  81. m.getSolver().solve();
  82. while (m.getSolver().solve()) {
  83. for (int i = 0; i < n; i++) {
  84. boolean b = g3.getValue().containsNode(i);
  85. Assert.assertEquals(g1.getValue().containsNode(i) || g2.getValue().containsNode(i), b);
  86. if (b) {
  87. for (int j = 0; j < n; j++) {
  88. Assert.assertEquals(g1.getValue().containsEdge(i, j) || g2.getValue().containsEdge(i, j), g3.getValue().containsEdge(i, j));
  89. }
  90. }
  91. }
  92. }
  93. }
  94. @Test(groups = "1s", timeOut = 60000)
  95. public void testInstantiateAndGenerateDirected() {
  96. Model m = new Model();
  97. int n = 3;
  98. DirectedGraph LB1 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  99. DirectedGraph UB1 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  100. DirectedGraphVar g1 = m.digraphVar("g1", LB1, UB1);
  101. DirectedGraph LB2 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  102. DirectedGraph UB2 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  103. DirectedGraphVar g2 = m.digraphVar("g2", LB2, UB2);
  104. //
  105. DirectedGraphVar g3 = m.graphUnionView(g1, g2);
  106. while (m.getSolver().solve()) {
  107. for (int i = 0; i < n; i++) {
  108. boolean b = g3.getValue().containsNode(i);
  109. Assert.assertEquals(g1.getValue().containsNode(i) || g2.getValue().containsNode(i), b);
  110. if (b) {
  111. for (int j = 0; j < n; j++) {
  112. Assert.assertEquals(g1.getValue().containsEdge(i, j) || g2.getValue().containsEdge(i, j), g3.getValue().containsEdge(i, j));
  113. }
  114. }
  115. }
  116. }
  117. }
  118. @Test(groups="1s", timeOut=60000)
  119. public void testConstrainedDirected() {
  120. Model m = new Model();
  121. int n = 4;
  122. DirectedGraph LB1 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  123. DirectedGraph UB1 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  124. DirectedGraphVar g1 = m.digraphVar("g1", LB1, UB1);
  125. DirectedGraph LB2 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  126. DirectedGraph UB2 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  127. DirectedGraphVar g2 = m.digraphVar("g2", LB2, UB2);
  128. //
  129. DirectedGraphVar g3 = m.graphUnionView(g1, g2);
  130. SetVar nodesG = m.graphNodeSetView(g3);
  131. m.member(3, nodesG).post();
  132. m.notMember(2, nodesG).post();
  133. SetVar neigh3 = m.graphPredecessorsSetView(g3, 3);
  134. m.member(1, neigh3).post();
  135. m.nbNodes(g2, m.intVar(1, 4)).post();
  136. m.stronglyConnected(g2).post();
  137. m.getSolver().setSearch(Search.graphVarSearch(g1, g2, g3));
  138. m.getSolver().solve();
  139. while (m.getSolver().solve()) {
  140. for (int i = 0; i < n; i++) {
  141. boolean b = g3.getValue().containsNode(i);
  142. Assert.assertEquals(g1.getValue().containsNode(i) || g2.getValue().containsNode(i), b);
  143. if (b) {
  144. for (int j = 0; j < n; j++) {
  145. Assert.assertEquals(g1.getValue().containsEdge(i, j) || g2.getValue().containsEdge(i, j), g3.getValue().containsEdge(i, j));
  146. }
  147. }
  148. }
  149. }
  150. }
  151. @Test(groups="1s", timeOut=60000)
  152. public void testDeltaUndirected() throws ContradictionException {
  153. Model m = new Model();
  154. int n = 5;
  155. UndirectedGraph LB1 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  156. UndirectedGraph UB1 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  157. UndirectedGraphVar g1 = m.graphVar("g1", LB1, UB1);
  158. UndirectedGraph LB2 = GraphFactory.makeStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  159. UndirectedGraph UB2 = GraphFactory.makeCompleteStoredUndirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  160. UndirectedGraphVar g2 = m.graphVar("g2", LB2, UB2);
  161. UndirectedGraphVar g3 = m.graphUnionView(g1, g2);
  162. ICause fakeCauseA = new ICause() {};
  163. ICause fakeCauseB = new ICause() {};
  164. IGraphDeltaMonitor monitor = g3.monitorDelta(fakeCauseA);
  165. monitor.startMonitoring();
  166. ISet delta = SetFactory.makeBitSet(0);
  167. IntProcedure nodeProc = delta::add;
  168. // Test add nodes
  169. g1.enforceNode(0, fakeCauseB);
  170. monitor.forEachNode(nodeProc, GraphEventType.ADD_NODE);
  171. Assert.assertTrue(delta.size() == 1);
  172. Assert.assertTrue(delta.contains(0));
  173. delta.clear();
  174. g2.enforceNode(0, fakeCauseB);
  175. monitor.forEachNode(nodeProc, GraphEventType.ADD_NODE);
  176. Assert.assertTrue(delta.size() == 0);
  177. // Test remove node
  178. g1.removeNode(2, fakeCauseB);
  179. monitor.forEachNode(nodeProc, GraphEventType.REMOVE_NODE);
  180. Assert.assertTrue(delta.size() == 0);
  181. g2.removeNode(2, fakeCauseB);
  182. monitor.forEachNode(nodeProc, GraphEventType.REMOVE_NODE);
  183. Assert.assertTrue(delta.size() == 1);
  184. Assert.assertTrue(delta.contains(2));
  185. delta.clear();
  186. // Test add edges
  187. // First clear monitor from node operations that can cause edge operations
  188. monitor.forEachEdge((i, j) -> {}, GraphEventType.ADD_EDGE);
  189. monitor.forEachEdge((i, j) -> {}, GraphEventType.REMOVE_EDGE);
  190. PairProcedure edgeProc = (i, j) -> {
  191. if (i == 1) {
  192. delta.add(j);
  193. } else if (j == 1) {
  194. delta.add(i);
  195. }
  196. };
  197. g1.enforceEdge(1, 3, fakeCauseB);
  198. g2.enforceEdge(1, 4, fakeCauseB);
  199. monitor.forEachEdge(edgeProc, GraphEventType.ADD_EDGE);
  200. Assert.assertTrue(delta.size() == 2);
  201. Assert.assertTrue(delta.contains(3));
  202. Assert.assertTrue(delta.contains(4));
  203. delta.clear();
  204. g1.enforceEdge(1, 4, fakeCauseB);
  205. g2.enforceEdge(1, 3, fakeCauseB);
  206. monitor.forEachEdge(edgeProc, GraphEventType.ADD_EDGE);
  207. Assert.assertTrue(delta.size() == 0);
  208. // Test remove edges
  209. g1.removeEdge(0, 1, fakeCauseB);
  210. monitor.forEachEdge(edgeProc, GraphEventType.REMOVE_EDGE);
  211. Assert.assertTrue(delta.size() == 0);
  212. g2.removeEdge(1, 0, fakeCauseB);
  213. monitor.forEachEdge(edgeProc, GraphEventType.REMOVE_EDGE);
  214. Assert.assertTrue(delta.size() == 1);
  215. Assert.assertTrue(delta.contains(0));
  216. }
  217. @Test(groups="1s", timeOut=60000)
  218. public void testDeltaDirected() throws ContradictionException {
  219. Model m = new Model();
  220. int n = 5;
  221. DirectedGraph LB1 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  222. DirectedGraph UB1 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  223. DirectedGraphVar g1 = m.digraphVar("g1", LB1, UB1);
  224. DirectedGraph LB2 = GraphFactory.makeStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET);
  225. DirectedGraph UB2 = GraphFactory.makeCompleteStoredDirectedGraph(m, n, SetType.BITSET, SetType.BITSET, false);
  226. DirectedGraphVar g2 = m.digraphVar("g2", LB2, UB2);
  227. DirectedGraphVar g3 = m.graphUnionView(g1, g2);
  228. ICause fakeCauseA = new ICause() {};
  229. ICause fakeCauseB = new ICause() {};
  230. IGraphDeltaMonitor monitor = g3.monitorDelta(fakeCauseA);
  231. monitor.startMonitoring();
  232. ISet delta = SetFactory.makeBitSet(0);
  233. IntProcedure nodeProc = delta::add;
  234. // Test add nodes
  235. g1.enforceNode(0, fakeCauseB);
  236. monitor.forEachNode(nodeProc, GraphEventType.ADD_NODE);
  237. Assert.assertTrue(delta.size() == 1);
  238. Assert.assertTrue(delta.contains(0));
  239. delta.clear();
  240. g2.enforceNode(0, fakeCauseB);
  241. monitor.forEachNode(nodeProc, GraphEventType.ADD_NODE);
  242. Assert.assertTrue(delta.size() == 0);
  243. // Test remove node
  244. g1.removeNode(2, fakeCauseB);
  245. monitor.forEachNode(nodeProc, GraphEventType.REMOVE_NODE);
  246. Assert.assertTrue(delta.size() == 0);
  247. g2.removeNode(2, fakeCauseB);
  248. monitor.forEachNode(nodeProc, GraphEventType.REMOVE_NODE);
  249. Assert.assertTrue(delta.size() == 1);
  250. Assert.assertTrue(delta.contains(2));
  251. delta.clear();
  252. // Test add edges
  253. // First clear monitor from node operations that can cause edge operations
  254. monitor.forEachEdge((i, j) -> {}, GraphEventType.ADD_EDGE);
  255. monitor.forEachEdge((i, j) -> {}, GraphEventType.REMOVE_EDGE);
  256. PairProcedure edgeProc = (i, j) -> {
  257. if (i == 1) {
  258. delta.add(j);
  259. } else if (j == 1) {
  260. delta.add(i);
  261. }
  262. };
  263. g1.enforceEdge(1, 3, fakeCauseB);
  264. g2.enforceEdge(1, 4, fakeCauseB);
  265. monitor.forEachEdge(edgeProc, GraphEventType.ADD_EDGE);
  266. Assert.assertTrue(delta.size() == 2);
  267. Assert.assertTrue(delta.contains(3));
  268. Assert.assertTrue(delta.contains(4));
  269. delta.clear();
  270. g1.enforceEdge(1, 4, fakeCauseB);
  271. g2.enforceEdge(1, 3, fakeCauseB);
  272. monitor.forEachEdge(edgeProc, GraphEventType.ADD_EDGE);
  273. Assert.assertTrue(delta.size() == 0);
  274. // Test remove edges
  275. g1.removeEdge(0, 1, fakeCauseB);
  276. monitor.forEachEdge(edgeProc, GraphEventType.REMOVE_EDGE);
  277. Assert.assertTrue(delta.size() == 0);
  278. g2.removeEdge(1, 0, fakeCauseB);
  279. monitor.forEachEdge(edgeProc, GraphEventType.REMOVE_EDGE);
  280. Assert.assertTrue(delta.size() == 0);
  281. g1.removeEdge(1, 0, fakeCauseB);
  282. monitor.forEachEdge(edgeProc, GraphEventType.REMOVE_EDGE);
  283. Assert.assertTrue(delta.size() == 1);
  284. Assert.assertTrue(delta.contains(0));
  285. }
  286. }