gecoder-with-gecode 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +81 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +45 -0
- data/Rakefile +13 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +110 -0
- data/example/sudoku.rb +61 -0
- data/ext/extconf.rb +29 -0
- data/ext/gecode-1.3.1/LICENSE +34 -0
- data/ext/gecode-1.3.1/Makefile.contribs +71 -0
- data/ext/gecode-1.3.1/Makefile.dep +3928 -0
- data/ext/gecode-1.3.1/Makefile.in +966 -0
- data/ext/gecode-1.3.1/changelog.in +1065 -0
- data/ext/gecode-1.3.1/configure +8590 -0
- data/ext/gecode-1.3.1/configure.ac +179 -0
- data/ext/gecode-1.3.1/configure.ac.in +175 -0
- data/ext/gecode-1.3.1/contribs/README +26 -0
- data/ext/gecode-1.3.1/contribs/graph/INSTALL +53 -0
- data/ext/gecode-1.3.1/contribs/graph/LICENSE +11 -0
- data/ext/gecode-1.3.1/contribs/graph/Makefile +167 -0
- data/ext/gecode-1.3.1/contribs/graph/Makefile.in.in +169 -0
- data/ext/gecode-1.3.1/contribs/graph/TODO +28 -0
- data/ext/gecode-1.3.1/contribs/graph/binarysimple.hh +82 -0
- data/ext/gecode-1.3.1/contribs/graph/binarysimple.icc +186 -0
- data/ext/gecode-1.3.1/contribs/graph/branch/branch.icc +257 -0
- data/ext/gecode-1.3.1/contribs/graph/configure +2160 -0
- data/ext/gecode-1.3.1/contribs/graph/configure.ac +33 -0
- data/ext/gecode-1.3.1/contribs/graph/doxygen.conf +1226 -0
- data/ext/gecode-1.3.1/contribs/graph/doxygen.hh +132 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-basic.cc +94 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-complement.cc +104 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-instUB.cc +105 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-path.cc +92 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-path2.cc +273 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/cpgraph-pathcost.cc +311 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/g1.txt +1 -0
- data/ext/gecode-1.3.1/contribs/graph/examples/g2.txt +1 -0
- data/ext/gecode-1.3.1/contribs/graph/graph.hh +51 -0
- data/ext/gecode-1.3.1/contribs/graph/graphutils.h +46 -0
- data/ext/gecode-1.3.1/contribs/graph/graphutils.icc +140 -0
- data/ext/gecode-1.3.1/contribs/graph/misc/doxygen/footer.html +1 -0
- data/ext/gecode-1.3.1/contribs/graph/path.hh +116 -0
- data/ext/gecode-1.3.1/contribs/graph/path.icc +64 -0
- data/ext/gecode-1.3.1/contribs/graph/path/path.icc +139 -0
- data/ext/gecode-1.3.1/contribs/graph/path/pathdegree.icc +133 -0
- data/ext/gecode-1.3.1/contribs/graph/path/pathgraphs.icc +341 -0
- data/ext/gecode-1.3.1/contribs/graph/shortdesc.ac +1 -0
- data/ext/gecode-1.3.1/contribs/graph/stlutility.icc +105 -0
- data/ext/gecode-1.3.1/contribs/graph/var.icc +106 -0
- data/ext/gecode-1.3.1/contribs/graph/view.icc +373 -0
- data/ext/gecode-1.3.1/contribs/graph/view/arcnode.cc +162 -0
- data/ext/gecode-1.3.1/contribs/graph/view/arcnode.hh +78 -0
- data/ext/gecode-1.3.1/contribs/graph/view/boundsgraphs.icc +349 -0
- data/ext/gecode-1.3.1/contribs/graph/view/constant.icc +148 -0
- data/ext/gecode-1.3.1/contribs/graph/view/iter.icc +337 -0
- data/ext/gecode-1.3.1/contribs/graph/view/nodearcsets.icc +493 -0
- data/ext/gecode-1.3.1/contribs/graph/view/nodeset.icc +60 -0
- data/ext/gecode-1.3.1/contribs/graph/view/outadjsets.icc +600 -0
- data/ext/gecode-1.3.1/contribs/graph/view/prop.icc +135 -0
- data/ext/gecode-1.3.1/contribs/map/COMPILING +68 -0
- data/ext/gecode-1.3.1/contribs/map/LICENSE +11 -0
- data/ext/gecode-1.3.1/contribs/map/Makefile.in.in +173 -0
- data/ext/gecode-1.3.1/contribs/map/configure +2285 -0
- data/ext/gecode-1.3.1/contribs/map/configure.ac +32 -0
- data/ext/gecode-1.3.1/contribs/map/constraints.hh +46 -0
- data/ext/gecode-1.3.1/contribs/map/constraints.icc +84 -0
- data/ext/gecode-1.3.1/contribs/map/doxygen.conf +1229 -0
- data/ext/gecode-1.3.1/contribs/map/doxygen.hh +33 -0
- data/ext/gecode-1.3.1/contribs/map/examples/approximateMatching.cc +199 -0
- data/ext/gecode-1.3.1/contribs/map/examples/g1.txt +1 -0
- data/ext/gecode-1.3.1/contribs/map/examples/g2.txt +1 -0
- data/ext/gecode-1.3.1/contribs/map/examples/graph-examples.tgz +0 -0
- data/ext/gecode-1.3.1/contribs/map/examples/isomorphism.cc +148 -0
- data/ext/gecode-1.3.1/contribs/map/examples/map +0 -0
- data/ext/gecode-1.3.1/contribs/map/examples/map.cc +80 -0
- data/ext/gecode-1.3.1/contribs/map/examples/subgraphmonomorphism.cc +155 -0
- data/ext/gecode-1.3.1/contribs/map/map.hh +65 -0
- data/ext/gecode-1.3.1/contribs/map/matching/mono.hh +235 -0
- data/ext/gecode-1.3.1/contribs/map/matching/mono.icc +771 -0
- data/ext/gecode-1.3.1/contribs/map/shortdesc.ac +2 -0
- data/ext/gecode-1.3.1/contribs/map/var.icc +346 -0
- data/ext/gecode-1.3.1/contribs/map/var/imp.cc +42 -0
- data/ext/gecode-1.3.1/contribs/map/var/imp.icc +436 -0
- data/ext/gecode-1.3.1/doxygen.conf.in +1225 -0
- data/ext/gecode-1.3.1/doxygen.hh.in +877 -0
- data/ext/gecode-1.3.1/examples/all-interval-sort.cc +201 -0
- data/ext/gecode-1.3.1/examples/all-interval.cc +114 -0
- data/ext/gecode-1.3.1/examples/alpha.cc +112 -0
- data/ext/gecode-1.3.1/examples/baseline.cc +71 -0
- data/ext/gecode-1.3.1/examples/bibd.cc +173 -0
- data/ext/gecode-1.3.1/examples/black-hole.cc +281 -0
- data/ext/gecode-1.3.1/examples/cars.cc +165 -0
- data/ext/gecode-1.3.1/examples/crew.cc +220 -0
- data/ext/gecode-1.3.1/examples/crowded-chess.cc +312 -0
- data/ext/gecode-1.3.1/examples/donald.cc +93 -0
- data/ext/gecode-1.3.1/examples/eq20.cc +111 -0
- data/ext/gecode-1.3.1/examples/golf.cc +242 -0
- data/ext/gecode-1.3.1/examples/golomb.cc +141 -0
- data/ext/gecode-1.3.1/examples/graph-color.cc +371 -0
- data/ext/gecode-1.3.1/examples/grocery.cc +107 -0
- data/ext/gecode-1.3.1/examples/hamming.cc +107 -0
- data/ext/gecode-1.3.1/examples/ind-set.cc +130 -0
- data/ext/gecode-1.3.1/examples/knights.cc +146 -0
- data/ext/gecode-1.3.1/examples/langfordnum.cc +244 -0
- data/ext/gecode-1.3.1/examples/magic-sequence-gcc.cc +93 -0
- data/ext/gecode-1.3.1/examples/magic-sequence.cc +108 -0
- data/ext/gecode-1.3.1/examples/magic-square.cc +120 -0
- data/ext/gecode-1.3.1/examples/money.cc +92 -0
- data/ext/gecode-1.3.1/examples/ortho-latin.cc +156 -0
- data/ext/gecode-1.3.1/examples/packing.cc +211 -0
- data/ext/gecode-1.3.1/examples/partition.cc +126 -0
- data/ext/gecode-1.3.1/examples/photo.cc +155 -0
- data/ext/gecode-1.3.1/examples/picture-puzzle.cc +481 -0
- data/ext/gecode-1.3.1/examples/queen-armies.cc +240 -0
- data/ext/gecode-1.3.1/examples/queens.cc +99 -0
- data/ext/gecode-1.3.1/examples/sports-league.cc +454 -0
- data/ext/gecode-1.3.1/examples/steiner.cc +148 -0
- data/ext/gecode-1.3.1/examples/stress-domain.cc +86 -0
- data/ext/gecode-1.3.1/examples/stress-element.cc +95 -0
- data/ext/gecode-1.3.1/examples/stress-exec.cc +74 -0
- data/ext/gecode-1.3.1/examples/stress-min.cc +84 -0
- data/ext/gecode-1.3.1/examples/stress-search.cc +72 -0
- data/ext/gecode-1.3.1/examples/sudoku-mixed.cc +282 -0
- data/ext/gecode-1.3.1/examples/sudoku-set.cc +162 -0
- data/ext/gecode-1.3.1/examples/sudoku.cc +188 -0
- data/ext/gecode-1.3.1/examples/sudoku.icc +703 -0
- data/ext/gecode-1.3.1/examples/support.cc +160 -0
- data/ext/gecode-1.3.1/examples/support.hh +98 -0
- data/ext/gecode-1.3.1/examples/support.icc +187 -0
- data/ext/gecode-1.3.1/examples/timer.cc +47 -0
- data/ext/gecode-1.3.1/examples/timer.hh +72 -0
- data/ext/gecode-1.3.1/examples/warehouses.cc +176 -0
- data/ext/gecode-1.3.1/extconf.rb +8 -0
- data/ext/gecode-1.3.1/gecode.m4 +736 -0
- data/ext/gecode-1.3.1/gecode/config.icc.in +50 -0
- data/ext/gecode-1.3.1/gecode/int.hh +1426 -0
- data/ext/gecode-1.3.1/gecode/int/arithmetic.cc +87 -0
- data/ext/gecode-1.3.1/gecode/int/arithmetic.hh +292 -0
- data/ext/gecode-1.3.1/gecode/int/arithmetic/abs.icc +213 -0
- data/ext/gecode-1.3.1/gecode/int/arithmetic/max.icc +196 -0
- data/ext/gecode-1.3.1/gecode/int/arithmetic/mult.icc +478 -0
- data/ext/gecode-1.3.1/gecode/int/array.cc +61 -0
- data/ext/gecode-1.3.1/gecode/int/array.icc +264 -0
- data/ext/gecode-1.3.1/gecode/int/bool.cc +187 -0
- data/ext/gecode-1.3.1/gecode/int/bool.hh +255 -0
- data/ext/gecode-1.3.1/gecode/int/bool/base.icc +123 -0
- data/ext/gecode-1.3.1/gecode/int/bool/eq.icc +89 -0
- data/ext/gecode-1.3.1/gecode/int/bool/eqv.icc +132 -0
- data/ext/gecode-1.3.1/gecode/int/bool/or.icc +380 -0
- data/ext/gecode-1.3.1/gecode/int/branch.cc +81 -0
- data/ext/gecode-1.3.1/gecode/int/branch.hh +444 -0
- data/ext/gecode-1.3.1/gecode/int/branch/assign.cc +83 -0
- data/ext/gecode-1.3.1/gecode/int/branch/assign.icc +76 -0
- data/ext/gecode-1.3.1/gecode/int/branch/select-val.icc +104 -0
- data/ext/gecode-1.3.1/gecode/int/branch/select-view.icc +219 -0
- data/ext/gecode-1.3.1/gecode/int/channel.cc +62 -0
- data/ext/gecode-1.3.1/gecode/int/channel.hh +144 -0
- data/ext/gecode-1.3.1/gecode/int/channel/base.icc +60 -0
- data/ext/gecode-1.3.1/gecode/int/channel/dom.icc +313 -0
- data/ext/gecode-1.3.1/gecode/int/channel/stack.icc +59 -0
- data/ext/gecode-1.3.1/gecode/int/channel/val.icc +239 -0
- data/ext/gecode-1.3.1/gecode/int/count.cc +174 -0
- data/ext/gecode-1.3.1/gecode/int/count.hh +401 -0
- data/ext/gecode-1.3.1/gecode/int/count/int.icc +495 -0
- data/ext/gecode-1.3.1/gecode/int/count/rel.icc +100 -0
- data/ext/gecode-1.3.1/gecode/int/count/view.icc +332 -0
- data/ext/gecode-1.3.1/gecode/int/cumulatives.cc +210 -0
- data/ext/gecode-1.3.1/gecode/int/cumulatives.hh +118 -0
- data/ext/gecode-1.3.1/gecode/int/cumulatives/val.icc +377 -0
- data/ext/gecode-1.3.1/gecode/int/distinct.cc +77 -0
- data/ext/gecode-1.3.1/gecode/int/distinct.hh +272 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/bilink.icc +73 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/bnd.icc +335 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/combptr.icc +62 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/dom.icc +740 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/edge.icc +96 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/node.icc +107 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/ter-dom.icc +97 -0
- data/ext/gecode-1.3.1/gecode/int/distinct/val.icc +171 -0
- data/ext/gecode-1.3.1/gecode/int/dom.cc +81 -0
- data/ext/gecode-1.3.1/gecode/int/dom.hh +101 -0
- data/ext/gecode-1.3.1/gecode/int/dom/range.icc +85 -0
- data/ext/gecode-1.3.1/gecode/int/dom/spec.icc +85 -0
- data/ext/gecode-1.3.1/gecode/int/element.cc +58 -0
- data/ext/gecode-1.3.1/gecode/int/element.hh +203 -0
- data/ext/gecode-1.3.1/gecode/int/element/int.icc +396 -0
- data/ext/gecode-1.3.1/gecode/int/element/view.icc +443 -0
- data/ext/gecode-1.3.1/gecode/int/exception.icc +137 -0
- data/ext/gecode-1.3.1/gecode/int/gcc.cc +708 -0
- data/ext/gecode-1.3.1/gecode/int/gcc.hh +338 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/bnd.icc +629 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/dom.icc +504 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/gccbndsup.icc +760 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/graphsup.icc +2375 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/lbc.icc +375 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/occur.icc +687 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/ubc.icc +236 -0
- data/ext/gecode-1.3.1/gecode/int/gcc/val.icc +373 -0
- data/ext/gecode-1.3.1/gecode/int/int-set.cc +115 -0
- data/ext/gecode-1.3.1/gecode/int/int-set.icc +151 -0
- data/ext/gecode-1.3.1/gecode/int/linear.cc +247 -0
- data/ext/gecode-1.3.1/gecode/int/linear.hh +1056 -0
- data/ext/gecode-1.3.1/gecode/int/linear/binary.icc +439 -0
- data/ext/gecode-1.3.1/gecode/int/linear/bool-int.icc +422 -0
- data/ext/gecode-1.3.1/gecode/int/linear/bool-view.icc +311 -0
- data/ext/gecode-1.3.1/gecode/int/linear/dom.icc +503 -0
- data/ext/gecode-1.3.1/gecode/int/linear/nary.icc +857 -0
- data/ext/gecode-1.3.1/gecode/int/linear/noview.icc +264 -0
- data/ext/gecode-1.3.1/gecode/int/linear/post.cc +542 -0
- data/ext/gecode-1.3.1/gecode/int/linear/ternary.icc +255 -0
- data/ext/gecode-1.3.1/gecode/int/propagator.icc +194 -0
- data/ext/gecode-1.3.1/gecode/int/regular.cc +40 -0
- data/ext/gecode-1.3.1/gecode/int/regular.hh +83 -0
- data/ext/gecode-1.3.1/gecode/int/regular/dfa.cc +466 -0
- data/ext/gecode-1.3.1/gecode/int/regular/dfa.icc +172 -0
- data/ext/gecode-1.3.1/gecode/int/regular/dom.icc +480 -0
- data/ext/gecode-1.3.1/gecode/int/regular/reg.cc +738 -0
- data/ext/gecode-1.3.1/gecode/int/rel.cc +293 -0
- data/ext/gecode-1.3.1/gecode/int/rel.hh +526 -0
- data/ext/gecode-1.3.1/gecode/int/rel/eq.icc +640 -0
- data/ext/gecode-1.3.1/gecode/int/rel/lex.icc +212 -0
- data/ext/gecode-1.3.1/gecode/int/rel/lq-le.icc +246 -0
- data/ext/gecode-1.3.1/gecode/int/rel/nq.icc +188 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness.cc +124 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness.hh +108 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness/matching.icc +177 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness/narrowing.icc +243 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness/order.icc +232 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness/sortedness.icc +727 -0
- data/ext/gecode-1.3.1/gecode/int/sortedness/sortsup.icc +666 -0
- data/ext/gecode-1.3.1/gecode/int/var-imp.vis +198 -0
- data/ext/gecode-1.3.1/gecode/int/var.icc +590 -0
- data/ext/gecode-1.3.1/gecode/int/var/bool.icc +52 -0
- data/ext/gecode-1.3.1/gecode/int/var/imp-body.icc +65 -0
- data/ext/gecode-1.3.1/gecode/int/var/imp-hdr.icc +191 -0
- data/ext/gecode-1.3.1/gecode/int/var/imp.cc +361 -0
- data/ext/gecode-1.3.1/gecode/int/var/imp.icc +579 -0
- data/ext/gecode-1.3.1/gecode/int/var/int.cc +63 -0
- data/ext/gecode-1.3.1/gecode/int/var/int.icc +135 -0
- data/ext/gecode-1.3.1/gecode/int/view.icc +1219 -0
- data/ext/gecode-1.3.1/gecode/int/view/bool.icc +270 -0
- data/ext/gecode-1.3.1/gecode/int/view/constint.icc +306 -0
- data/ext/gecode-1.3.1/gecode/int/view/int.icc +221 -0
- data/ext/gecode-1.3.1/gecode/int/view/iter.icc +49 -0
- data/ext/gecode-1.3.1/gecode/int/view/minus.icc +285 -0
- data/ext/gecode-1.3.1/gecode/int/view/offset.icc +274 -0
- data/ext/gecode-1.3.1/gecode/int/view/print.cc +109 -0
- data/ext/gecode-1.3.1/gecode/int/view/rtest.icc +215 -0
- data/ext/gecode-1.3.1/gecode/int/view/scale.icc +373 -0
- data/ext/gecode-1.3.1/gecode/iter.hh +65 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-add.icc +130 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-append.icc +208 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-array.icc +123 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-cache.icc +143 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-compl.icc +206 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-diff.icc +127 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-empty.icc +96 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-inter.icc +202 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-minmax.icc +103 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-minus.icc +138 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-offset.icc +112 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-operations.icc +142 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-scale.icc +224 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-singleton.icc +71 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-size.icc +131 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-union.icc +211 -0
- data/ext/gecode-1.3.1/gecode/iter/ranges-values.icc +125 -0
- data/ext/gecode-1.3.1/gecode/iter/values-ranges.icc +91 -0
- data/ext/gecode-1.3.1/gecode/iter/virtual-ranges-compl.icc +247 -0
- data/ext/gecode-1.3.1/gecode/iter/virtual-ranges-inter.icc +227 -0
- data/ext/gecode-1.3.1/gecode/iter/virtual-ranges-union.icc +236 -0
- data/ext/gecode-1.3.1/gecode/iter/virtual-ranges.icc +126 -0
- data/ext/gecode-1.3.1/gecode/kernel.hh +141 -0
- data/ext/gecode-1.3.1/gecode/kernel/array.icc +954 -0
- data/ext/gecode-1.3.1/gecode/kernel/branching.icc +233 -0
- data/ext/gecode-1.3.1/gecode/kernel/core.cc +417 -0
- data/ext/gecode-1.3.1/gecode/kernel/core.icc +1681 -0
- data/ext/gecode-1.3.1/gecode/kernel/exception.cc +49 -0
- data/ext/gecode-1.3.1/gecode/kernel/exception.icc +104 -0
- data/ext/gecode-1.3.1/gecode/kernel/macros.icc +98 -0
- data/ext/gecode-1.3.1/gecode/kernel/memory-manager.cc +41 -0
- data/ext/gecode-1.3.1/gecode/kernel/memory-manager.icc +438 -0
- data/ext/gecode-1.3.1/gecode/kernel/memory.icc +205 -0
- data/ext/gecode-1.3.1/gecode/kernel/modevent.icc +53 -0
- data/ext/gecode-1.3.1/gecode/kernel/propagator.icc +680 -0
- data/ext/gecode-1.3.1/gecode/kernel/view.icc +583 -0
- data/ext/gecode-1.3.1/gecode/limits.hh +87 -0
- data/ext/gecode-1.3.1/gecode/minimodel.hh +942 -0
- data/ext/gecode-1.3.1/gecode/minimodel/arithmetic.cc +137 -0
- data/ext/gecode-1.3.1/gecode/minimodel/bool-expr.cc +207 -0
- data/ext/gecode-1.3.1/gecode/minimodel/bool-expr.icc +191 -0
- data/ext/gecode-1.3.1/gecode/minimodel/bool-rel.icc +66 -0
- data/ext/gecode-1.3.1/gecode/minimodel/exception.icc +59 -0
- data/ext/gecode-1.3.1/gecode/minimodel/lin-expr.cc +103 -0
- data/ext/gecode-1.3.1/gecode/minimodel/lin-expr.icc +192 -0
- data/ext/gecode-1.3.1/gecode/minimodel/lin-rel.icc +200 -0
- data/ext/gecode-1.3.1/gecode/minimodel/matrix.icc +118 -0
- data/ext/gecode-1.3.1/gecode/minimodel/scheduling.cc +241 -0
- data/ext/gecode-1.3.1/gecode/search.hh +745 -0
- data/ext/gecode-1.3.1/gecode/search/bab.cc +153 -0
- data/ext/gecode-1.3.1/gecode/search/bab.icc +101 -0
- data/ext/gecode-1.3.1/gecode/search/dfs.cc +63 -0
- data/ext/gecode-1.3.1/gecode/search/dfs.icc +144 -0
- data/ext/gecode-1.3.1/gecode/search/engine-ctrl.icc +109 -0
- data/ext/gecode-1.3.1/gecode/search/lds.cc +237 -0
- data/ext/gecode-1.3.1/gecode/search/lds.icc +57 -0
- data/ext/gecode-1.3.1/gecode/search/reco-stack.icc +219 -0
- data/ext/gecode-1.3.1/gecode/search/restart.icc +76 -0
- data/ext/gecode-1.3.1/gecode/search/statistics.icc +30 -0
- data/ext/gecode-1.3.1/gecode/search/stop.cc +58 -0
- data/ext/gecode-1.3.1/gecode/search/stop.icc +100 -0
- data/ext/gecode-1.3.1/gecode/set.hh +419 -0
- data/ext/gecode-1.3.1/gecode/set/array.cc +114 -0
- data/ext/gecode-1.3.1/gecode/set/array.icc +134 -0
- data/ext/gecode-1.3.1/gecode/set/branch.cc +57 -0
- data/ext/gecode-1.3.1/gecode/set/branch.hh +176 -0
- data/ext/gecode-1.3.1/gecode/set/branch/select-val.icc +72 -0
- data/ext/gecode-1.3.1/gecode/set/branch/select-view.icc +112 -0
- data/ext/gecode-1.3.1/gecode/set/cardinality.cc +49 -0
- data/ext/gecode-1.3.1/gecode/set/convex.cc +43 -0
- data/ext/gecode-1.3.1/gecode/set/convex.hh +92 -0
- data/ext/gecode-1.3.1/gecode/set/convex/conv.cc +81 -0
- data/ext/gecode-1.3.1/gecode/set/convex/conv.icc +51 -0
- data/ext/gecode-1.3.1/gecode/set/convex/hull.cc +100 -0
- data/ext/gecode-1.3.1/gecode/set/convex/hull.icc +52 -0
- data/ext/gecode-1.3.1/gecode/set/distinct.cc +48 -0
- data/ext/gecode-1.3.1/gecode/set/distinct.hh +97 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/atmostOne.cc +151 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/atmostOne.icc +50 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/binomial.cc +46 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/binomial.icc +157 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/distinct.cc +124 -0
- data/ext/gecode-1.3.1/gecode/set/distinct/distinct.icc +58 -0
- data/ext/gecode-1.3.1/gecode/set/dom.cc +224 -0
- data/ext/gecode-1.3.1/gecode/set/exception.icc +132 -0
- data/ext/gecode-1.3.1/gecode/set/int.cc +139 -0
- data/ext/gecode-1.3.1/gecode/set/int.hh +226 -0
- data/ext/gecode-1.3.1/gecode/set/int/card.cc +61 -0
- data/ext/gecode-1.3.1/gecode/set/int/card.icc +54 -0
- data/ext/gecode-1.3.1/gecode/set/int/channel.cc +100 -0
- data/ext/gecode-1.3.1/gecode/set/int/channel.icc +75 -0
- data/ext/gecode-1.3.1/gecode/set/int/match.cc +148 -0
- data/ext/gecode-1.3.1/gecode/set/int/match.icc +67 -0
- data/ext/gecode-1.3.1/gecode/set/int/minmax.cc +109 -0
- data/ext/gecode-1.3.1/gecode/set/int/minmax.icc +63 -0
- data/ext/gecode-1.3.1/gecode/set/int/weights.cc +182 -0
- data/ext/gecode-1.3.1/gecode/set/int/weights.icc +174 -0
- data/ext/gecode-1.3.1/gecode/set/projectors-compiler.hh +148 -0
- data/ext/gecode-1.3.1/gecode/set/projectors.cc +109 -0
- data/ext/gecode-1.3.1/gecode/set/projectors.hh +319 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/compiler.cc +841 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/projector-set.cc +69 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/projector-set.icc +66 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/projector.cc +125 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/projector.icc +79 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/propagator.hh +127 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/propagator/card.icc +96 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/propagator/nary.icc +106 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/propagator/re-nary.cc +76 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/propagator/re-nary.icc +53 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/set-expr.cc +306 -0
- data/ext/gecode-1.3.1/gecode/set/projectors/set-expr.icc +192 -0
- data/ext/gecode-1.3.1/gecode/set/propagator.icc +96 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op-const.cc +233 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op.cc +96 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op.hh +267 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/common.icc +528 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/inter.icc +312 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/partition.icc +131 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/post.icc +198 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/subofunion.icc +150 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/superofinter.icc +151 -0
- data/ext/gecode-1.3.1/gecode/set/rel-op/union.icc +292 -0
- data/ext/gecode-1.3.1/gecode/set/rel.cc +201 -0
- data/ext/gecode-1.3.1/gecode/set/rel.hh +250 -0
- data/ext/gecode-1.3.1/gecode/set/rel/common.icc +109 -0
- data/ext/gecode-1.3.1/gecode/set/rel/eq.icc +101 -0
- data/ext/gecode-1.3.1/gecode/set/rel/nosubset.icc +88 -0
- data/ext/gecode-1.3.1/gecode/set/rel/nq.icc +132 -0
- data/ext/gecode-1.3.1/gecode/set/rel/re-eq.icc +142 -0
- data/ext/gecode-1.3.1/gecode/set/rel/re-subset.icc +121 -0
- data/ext/gecode-1.3.1/gecode/set/rel/subset.icc +80 -0
- data/ext/gecode-1.3.1/gecode/set/select.cc +88 -0
- data/ext/gecode-1.3.1/gecode/set/select.hh +113 -0
- data/ext/gecode-1.3.1/gecode/set/select/disjoint.cc +267 -0
- data/ext/gecode-1.3.1/gecode/set/select/disjoint.icc +59 -0
- data/ext/gecode-1.3.1/gecode/set/select/idxarray.hh +91 -0
- data/ext/gecode-1.3.1/gecode/set/select/idxarray.icc +112 -0
- data/ext/gecode-1.3.1/gecode/set/select/inter.icc +300 -0
- data/ext/gecode-1.3.1/gecode/set/sequence.cc +48 -0
- data/ext/gecode-1.3.1/gecode/set/sequence.hh +97 -0
- data/ext/gecode-1.3.1/gecode/set/sequence/common.icc +79 -0
- data/ext/gecode-1.3.1/gecode/set/sequence/seq-u.cc +83 -0
- data/ext/gecode-1.3.1/gecode/set/sequence/seq-u.icc +63 -0
- data/ext/gecode-1.3.1/gecode/set/sequence/seq.cc +61 -0
- data/ext/gecode-1.3.1/gecode/set/sequence/seq.icc +53 -0
- data/ext/gecode-1.3.1/gecode/set/var-imp.vis +205 -0
- data/ext/gecode-1.3.1/gecode/set/var.icc +1090 -0
- data/ext/gecode-1.3.1/gecode/set/var/imp-body.icc +192 -0
- data/ext/gecode-1.3.1/gecode/set/var/imp-hdr.icc +235 -0
- data/ext/gecode-1.3.1/gecode/set/var/imp.cc +127 -0
- data/ext/gecode-1.3.1/gecode/set/var/imp.icc +356 -0
- data/ext/gecode-1.3.1/gecode/set/var/integerset.cc +256 -0
- data/ext/gecode-1.3.1/gecode/set/var/integerset.icc +512 -0
- data/ext/gecode-1.3.1/gecode/set/var/iter.icc +47 -0
- data/ext/gecode-1.3.1/gecode/set/var/set.cc +99 -0
- data/ext/gecode-1.3.1/gecode/set/var/set.icc +282 -0
- data/ext/gecode-1.3.1/gecode/set/view.icc +1075 -0
- data/ext/gecode-1.3.1/gecode/set/view/complement.icc +525 -0
- data/ext/gecode-1.3.1/gecode/set/view/const.icc +651 -0
- data/ext/gecode-1.3.1/gecode/set/view/print.cc +120 -0
- data/ext/gecode-1.3.1/gecode/set/view/set.icc +217 -0
- data/ext/gecode-1.3.1/gecode/set/view/singleton.icc +348 -0
- data/ext/gecode-1.3.1/gecode/support/block-allocator.hh +152 -0
- data/ext/gecode-1.3.1/gecode/support/dynamic-array.hh +131 -0
- data/ext/gecode-1.3.1/gecode/support/dynamic-stack.hh +157 -0
- data/ext/gecode-1.3.1/gecode/support/random.hh +100 -0
- data/ext/gecode-1.3.1/gecode/support/shared-array.hh +255 -0
- data/ext/gecode-1.3.1/gecode/support/sort.hh +193 -0
- data/ext/gecode-1.3.1/gecode/support/static-pqueue.hh +240 -0
- data/ext/gecode-1.3.1/gecode/support/static-stack.hh +117 -0
- data/ext/gecode-1.3.1/install-sh +323 -0
- data/ext/gecode-1.3.1/misc/debian/Makefile.am +8 -0
- data/ext/gecode-1.3.1/misc/debian/changelog +6 -0
- data/ext/gecode-1.3.1/misc/debian/control +11 -0
- data/ext/gecode-1.3.1/misc/debian/copyright +44 -0
- data/ext/gecode-1.3.1/misc/debian/gecode.info +9 -0
- data/ext/gecode-1.3.1/misc/debian/gecode.install +2 -0
- data/ext/gecode-1.3.1/misc/debian/gecode.spec +58 -0
- data/ext/gecode-1.3.1/misc/debian/rules +81 -0
- data/ext/gecode-1.3.1/misc/doxygen/back.png +0 -0
- data/ext/gecode-1.3.1/misc/doxygen/footer.html +3 -0
- data/ext/gecode-1.3.1/misc/doxygen/gecode-logo-100.png +0 -0
- data/ext/gecode-1.3.1/misc/doxygen/header.html +46 -0
- data/ext/gecode-1.3.1/misc/doxygen/stylesheet.css +460 -0
- data/ext/gecode-1.3.1/misc/fixproperties.sh +32 -0
- data/ext/gecode-1.3.1/misc/gecode-minimodel.pc.in +12 -0
- data/ext/gecode-1.3.1/misc/gecode-search.pc.in +12 -0
- data/ext/gecode-1.3.1/misc/gecode.pc.in +12 -0
- data/ext/gecode-1.3.1/misc/genchangelog.perl +190 -0
- data/ext/gecode-1.3.1/misc/genlicense.perl +113 -0
- data/ext/gecode-1.3.1/misc/genstatistics.perl +155 -0
- data/ext/gecode-1.3.1/misc/gentxtchangelog.perl +170 -0
- data/ext/gecode-1.3.1/misc/genvarimp.perl +666 -0
- data/ext/gecode-1.3.1/misc/getrevision.perl +32 -0
- data/ext/gecode-1.3.1/misc/makedepend.perl +66 -0
- data/ext/gecode-1.3.1/test/int.cc +497 -0
- data/ext/gecode-1.3.1/test/int.hh +119 -0
- data/ext/gecode-1.3.1/test/int/arithmetic.cc +262 -0
- data/ext/gecode-1.3.1/test/int/basic.cc +42 -0
- data/ext/gecode-1.3.1/test/int/bool.cc +189 -0
- data/ext/gecode-1.3.1/test/int/channel.cc +79 -0
- data/ext/gecode-1.3.1/test/int/count.cc +264 -0
- data/ext/gecode-1.3.1/test/int/distinct.cc +121 -0
- data/ext/gecode-1.3.1/test/int/dom.cc +69 -0
- data/ext/gecode-1.3.1/test/int/element.cc +132 -0
- data/ext/gecode-1.3.1/test/int/gcc.cc +592 -0
- data/ext/gecode-1.3.1/test/int/linear.cc +315 -0
- data/ext/gecode-1.3.1/test/int/minimodel.cc +451 -0
- data/ext/gecode-1.3.1/test/int/regular.cc +105 -0
- data/ext/gecode-1.3.1/test/int/rel.cc +283 -0
- data/ext/gecode-1.3.1/test/int/scheduling.cc +259 -0
- data/ext/gecode-1.3.1/test/int/sortedness.cc +272 -0
- data/ext/gecode-1.3.1/test/intset.cc +40 -0
- data/ext/gecode-1.3.1/test/log.cc +515 -0
- data/ext/gecode-1.3.1/test/log.hh +68 -0
- data/ext/gecode-1.3.1/test/set.cc +542 -0
- data/ext/gecode-1.3.1/test/set.hh +152 -0
- data/ext/gecode-1.3.1/test/set/convex.cc +94 -0
- data/ext/gecode-1.3.1/test/set/distinct.cc +148 -0
- data/ext/gecode-1.3.1/test/set/dom.cc +67 -0
- data/ext/gecode-1.3.1/test/set/int.cc +249 -0
- data/ext/gecode-1.3.1/test/set/projection.cc +333 -0
- data/ext/gecode-1.3.1/test/set/rel-op.cc +662 -0
- data/ext/gecode-1.3.1/test/set/rel.cc +198 -0
- data/ext/gecode-1.3.1/test/set/select.cc +108 -0
- data/ext/gecode-1.3.1/test/set/sequence.cc +83 -0
- data/ext/gecode-1.3.1/test/stress.cc +93 -0
- data/ext/gecode-1.3.1/test/stress.hh +74 -0
- data/ext/gecode-1.3.1/test/stress/distinct.cc +70 -0
- data/ext/gecode-1.3.1/test/stress/domain.cc +69 -0
- data/ext/gecode-1.3.1/test/stress/exec.cc +60 -0
- data/ext/gecode-1.3.1/test/stress/minsort.cc +63 -0
- data/ext/gecode-1.3.1/test/stress/regular.cc +112 -0
- data/ext/gecode-1.3.1/test/test.cc +215 -0
- data/ext/gecode-1.3.1/test/test.hh +107 -0
- data/ext/missing.cpp +328 -0
- data/ext/missing.h +120 -0
- data/ext/vararray.cpp +330 -0
- data/ext/vararray.h +149 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +34 -0
- data/lib/gecoder/bindings/bindings.rb +2209 -0
- data/lib/gecoder/interface.rb +8 -0
- data/lib/gecoder/interface/binding_changes.rb +313 -0
- data/lib/gecoder/interface/branch.rb +152 -0
- data/lib/gecoder/interface/constraints.rb +397 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +153 -0
- data/lib/gecoder/interface/model.rb +251 -0
- data/lib/gecoder/interface/search.rb +123 -0
- data/lib/gecoder/interface/variables.rb +254 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/binding_changes.rb +76 -0
- data/specs/bool_var.rb +74 -0
- data/specs/branch.rb +170 -0
- data/specs/constraints/arithmetic.rb +266 -0
- data/specs/constraints/bool_enum.rb +140 -0
- data/specs/constraints/boolean.rb +232 -0
- data/specs/constraints/cardinality.rb +154 -0
- data/specs/constraints/channel.rb +126 -0
- data/specs/constraints/connection.rb +373 -0
- data/specs/constraints/constraint_helper.rb +180 -0
- data/specs/constraints/constraints.rb +74 -0
- data/specs/constraints/count.rb +139 -0
- data/specs/constraints/distinct.rb +218 -0
- data/specs/constraints/element.rb +106 -0
- data/specs/constraints/equality.rb +31 -0
- data/specs/constraints/int_domain.rb +69 -0
- data/specs/constraints/int_relation.rb +78 -0
- data/specs/constraints/linear.rb +332 -0
- data/specs/constraints/reification_sugar.rb +96 -0
- data/specs/constraints/selection.rb +292 -0
- data/specs/constraints/set_domain.rb +181 -0
- data/specs/constraints/set_operation.rb +285 -0
- data/specs/constraints/set_relation.rb +201 -0
- data/specs/constraints/sort.rb +175 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +122 -0
- data/specs/int_var.rb +144 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +190 -0
- data/specs/search.rb +246 -0
- data/specs/set_var.rb +68 -0
- data/specs/spec_helper.rb +93 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/distribution.rake +129 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/specs.rake +15 -0
- data/tasks/svn.rake +11 -0
- data/tasks/website.rake +51 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +339 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +98 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- metadata +826 -0
|
@@ -0,0 +1,2375 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Main authors:
|
|
3
|
+
* Patrick Pekczynski <pekczynski@ps.uni-sb.de>
|
|
4
|
+
*
|
|
5
|
+
* Copyright:
|
|
6
|
+
* Patrick Pekczynski, 2005
|
|
7
|
+
*
|
|
8
|
+
* Last modified:
|
|
9
|
+
* $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
|
|
10
|
+
* $Revision: 3512 $
|
|
11
|
+
*
|
|
12
|
+
* This file is part of Gecode, the generic constraint
|
|
13
|
+
* development environment:
|
|
14
|
+
* http://www.gecode.org
|
|
15
|
+
*
|
|
16
|
+
* See the file "LICENSE" for information on usage and
|
|
17
|
+
* redistribution of this file, and for a
|
|
18
|
+
* DISCLAIMER OF ALL WARRANTIES.
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
namespace Gecode { namespace Int { namespace GCC {
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* \brief Bounds constraint (BC) type
|
|
26
|
+
*
|
|
27
|
+
* If BC = UBC, then we argue about the Upper Bounds Constraint
|
|
28
|
+
* else we use the functions for the Lower Bounds Constraint
|
|
29
|
+
*/
|
|
30
|
+
enum BC {UBC = 1, LBC = 0};
|
|
31
|
+
|
|
32
|
+
class Edge;
|
|
33
|
+
/// Base class for nodes in the variable-value-graph
|
|
34
|
+
class VVGNode{
|
|
35
|
+
private:
|
|
36
|
+
/// stores all incident edges on the node
|
|
37
|
+
Edge* e;
|
|
38
|
+
/// returns the first edge
|
|
39
|
+
Edge* fst;
|
|
40
|
+
/// returns the last edge
|
|
41
|
+
Edge* lst;
|
|
42
|
+
/// single incoming edge used for storing a path in the algorithms
|
|
43
|
+
Edge* ie;
|
|
44
|
+
/// Mark as matching edge in LBC
|
|
45
|
+
bool lm;
|
|
46
|
+
/// Mark as matching edge in UBC
|
|
47
|
+
bool um;
|
|
48
|
+
/// Explicit node type
|
|
49
|
+
bool type;
|
|
50
|
+
public:
|
|
51
|
+
/// \name Constructors and initialization
|
|
52
|
+
//@{
|
|
53
|
+
/// Default constructor
|
|
54
|
+
VVGNode(void);
|
|
55
|
+
//@}
|
|
56
|
+
/// Destructor
|
|
57
|
+
virtual ~VVGNode(void){};
|
|
58
|
+
/// Create a new node
|
|
59
|
+
void* operator new(size_t, void*);
|
|
60
|
+
|
|
61
|
+
/// \name Access
|
|
62
|
+
//@{
|
|
63
|
+
/// return reference to the incident edges
|
|
64
|
+
Edge** adj(void);
|
|
65
|
+
/// return pointer to the first incident edge
|
|
66
|
+
Edge* first(void);
|
|
67
|
+
/// return pointer to the last incident edge
|
|
68
|
+
Edge* last(void);
|
|
69
|
+
/// return pointer to the node's inedge
|
|
70
|
+
Edge* inedge(void);
|
|
71
|
+
/// return the type of the node
|
|
72
|
+
bool get_type(void);
|
|
73
|
+
/// access the matching flag of the node
|
|
74
|
+
template <BC>
|
|
75
|
+
bool get_match_flag(void);
|
|
76
|
+
/// get the information on the node (either var-index or value)
|
|
77
|
+
virtual int get_info(void) = 0;
|
|
78
|
+
/// test whether the node is matched
|
|
79
|
+
virtual bool is_matched(BC) = 0;
|
|
80
|
+
|
|
81
|
+
/// check whether a node has been removed from the graph
|
|
82
|
+
virtual bool removed(void) = 0;
|
|
83
|
+
//@}
|
|
84
|
+
|
|
85
|
+
/// \name Update
|
|
86
|
+
//@{
|
|
87
|
+
/// set the first edge pointer to \a p
|
|
88
|
+
void first(Edge* p);
|
|
89
|
+
/// set the last edge pointer to \a p
|
|
90
|
+
void last(Edge* p);
|
|
91
|
+
/// set the inedge pointer to \a p
|
|
92
|
+
void inedge(Edge* p);
|
|
93
|
+
/// set the node type to \a t
|
|
94
|
+
void set_type(bool t);
|
|
95
|
+
/// set the matching flag to \a f
|
|
96
|
+
template <BC>
|
|
97
|
+
void set_match_flag(bool f);
|
|
98
|
+
/// set the node information to \a i
|
|
99
|
+
virtual void set_info(int i) = 0;
|
|
100
|
+
//@}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/// %Variable Node
|
|
104
|
+
class VarNode : public VVGNode{
|
|
105
|
+
private:
|
|
106
|
+
/// stores the matching edge on this node in the UBC
|
|
107
|
+
Edge* ubm;
|
|
108
|
+
/// stores the matching edge on this node in the LBC
|
|
109
|
+
Edge* lbm;
|
|
110
|
+
|
|
111
|
+
public:
|
|
112
|
+
/// stores the variable index of the node
|
|
113
|
+
unsigned int var;
|
|
114
|
+
/// stores the number of incident edges on the node
|
|
115
|
+
unsigned int noe;
|
|
116
|
+
|
|
117
|
+
/// stores the variable index of the node
|
|
118
|
+
unsigned int xindex;
|
|
119
|
+
|
|
120
|
+
/// \name Constructors and initialization
|
|
121
|
+
//@{
|
|
122
|
+
/// Creates a variable node with index i
|
|
123
|
+
VarNode(int i, int oidx);
|
|
124
|
+
//@}
|
|
125
|
+
|
|
126
|
+
/// \name Access
|
|
127
|
+
//@{
|
|
128
|
+
/// return the matching edge on the node
|
|
129
|
+
template <BC>
|
|
130
|
+
Edge* get_match(void);
|
|
131
|
+
/// return the variable index of the node
|
|
132
|
+
int get_info(void);
|
|
133
|
+
/// returns whether the node is still matchable
|
|
134
|
+
bool is_matched(BC);
|
|
135
|
+
/// tests whether the node is matched or not
|
|
136
|
+
template <BC>
|
|
137
|
+
bool matched(void);
|
|
138
|
+
|
|
139
|
+
/// check for removal from graph
|
|
140
|
+
bool removed(void);
|
|
141
|
+
//@}
|
|
142
|
+
|
|
143
|
+
/// \name Update
|
|
144
|
+
//@{
|
|
145
|
+
/// set the node info to \a i
|
|
146
|
+
void set_info(int i);
|
|
147
|
+
/// set the pointer of the matching edge to m
|
|
148
|
+
template <BC>
|
|
149
|
+
void set_match(Edge* m);
|
|
150
|
+
/// match the node
|
|
151
|
+
template <BC>
|
|
152
|
+
void match(void);
|
|
153
|
+
/// unmatch the node
|
|
154
|
+
template <BC>
|
|
155
|
+
void unmatch(void);
|
|
156
|
+
//@}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/// Value node
|
|
160
|
+
class ValNode : public VVGNode{
|
|
161
|
+
private:
|
|
162
|
+
/// minimal required occurence of the value as stored in k
|
|
163
|
+
int _klb;
|
|
164
|
+
/// maximal required occurence of the value as stored in k
|
|
165
|
+
int _kub;
|
|
166
|
+
/// index to acces the value via cardinality array k
|
|
167
|
+
int _kidx;
|
|
168
|
+
/// stores the current number of occurences of the value
|
|
169
|
+
int _kcount;
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
/// store numbre of conflicting matching edges
|
|
173
|
+
int noc;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* \brief Minimal capacity of the value node
|
|
177
|
+
*
|
|
178
|
+
* Stores who often the value node can be matched in a LBC-matching
|
|
179
|
+
*/
|
|
180
|
+
int lb;
|
|
181
|
+
int ublow;
|
|
182
|
+
/**
|
|
183
|
+
* \brief Maximal capacity of the value node
|
|
184
|
+
*
|
|
185
|
+
* Stores who often the value node can be matched in a UBC-matching
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
int ub;
|
|
189
|
+
|
|
190
|
+
public:
|
|
191
|
+
/// stores the value of the node
|
|
192
|
+
int val;
|
|
193
|
+
/// stores the index of the node
|
|
194
|
+
int idx;
|
|
195
|
+
/// stores the number of incident edges on the node
|
|
196
|
+
int noe;
|
|
197
|
+
|
|
198
|
+
/// \name Constructors and destructors
|
|
199
|
+
//@{
|
|
200
|
+
/**
|
|
201
|
+
* \brief Constructor for value node
|
|
202
|
+
*
|
|
203
|
+
* with minimal capacity \a min,
|
|
204
|
+
* maximal capacity \a max,
|
|
205
|
+
* the value \a value and the index \a k_access in \a k
|
|
206
|
+
*/
|
|
207
|
+
ValNode(int min, int max, int value, int kidx, int kshift, int count);
|
|
208
|
+
//@}
|
|
209
|
+
|
|
210
|
+
/// \name Access
|
|
211
|
+
//@{
|
|
212
|
+
|
|
213
|
+
/// set the max cap for LBC
|
|
214
|
+
void set_maxlow(int i);
|
|
215
|
+
/// get max cap for LBC
|
|
216
|
+
int get_maxlow(void);
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
/// Mark the value node as conflicting in case of variable cardinalities
|
|
220
|
+
void card_conflict(int c);
|
|
221
|
+
/// Check whether the value node is conflicting
|
|
222
|
+
int card_conflict(void);
|
|
223
|
+
/// Reduce the conflict counter
|
|
224
|
+
void red_conflict(void);
|
|
225
|
+
|
|
226
|
+
/// check for removal from graph
|
|
227
|
+
bool removed(void);
|
|
228
|
+
|
|
229
|
+
/// increases the value counter
|
|
230
|
+
void inc(void);
|
|
231
|
+
/// returns the current number of occurences of the value
|
|
232
|
+
int kcount(void);
|
|
233
|
+
/// returns the number of incident matching edges on a value node
|
|
234
|
+
template <BC>
|
|
235
|
+
int incid_match(void);
|
|
236
|
+
/// returns the index in cardinality array k
|
|
237
|
+
int kindex(void);
|
|
238
|
+
/// return the node information
|
|
239
|
+
int get_info(void);
|
|
240
|
+
/// returns \a true if the node is matched in BC, \a false otherwise
|
|
241
|
+
template <BC>
|
|
242
|
+
bool matched(void);
|
|
243
|
+
/// tests whether the node is a sink
|
|
244
|
+
bool sink(void);
|
|
245
|
+
/// tests whether the node is a source
|
|
246
|
+
bool source(void);
|
|
247
|
+
/// return the minimal node capacity as stored in \a k
|
|
248
|
+
int kmin(void);
|
|
249
|
+
/// return the maximal node capacity as stored in \a k
|
|
250
|
+
int kmax(void);
|
|
251
|
+
/// return minimal or maximal capacity
|
|
252
|
+
template <BC>
|
|
253
|
+
int kbound(void);
|
|
254
|
+
|
|
255
|
+
/// returns whether the node is still matchable
|
|
256
|
+
bool is_matched(BC);
|
|
257
|
+
//@}
|
|
258
|
+
|
|
259
|
+
/// \name Update
|
|
260
|
+
//@{
|
|
261
|
+
void kcount(int);
|
|
262
|
+
/// changes the index in the cardinality array k
|
|
263
|
+
void kindex(int);
|
|
264
|
+
/// decrease the node-capacity
|
|
265
|
+
template <BC>
|
|
266
|
+
void dec(void);
|
|
267
|
+
/// increase the node-capacity
|
|
268
|
+
template <BC>
|
|
269
|
+
void inc(void);
|
|
270
|
+
/// return the the node-capacity
|
|
271
|
+
template <BC>
|
|
272
|
+
int cap(void);
|
|
273
|
+
/// set the node-capacity to \a c
|
|
274
|
+
template <BC>
|
|
275
|
+
void set_cap(int c);
|
|
276
|
+
/// match the node
|
|
277
|
+
template <BC>
|
|
278
|
+
void match(void);
|
|
279
|
+
/// unmatch the node
|
|
280
|
+
template <BC>
|
|
281
|
+
void unmatch(void);
|
|
282
|
+
/// node reset to original capacity values
|
|
283
|
+
void reset(void);
|
|
284
|
+
/// set the node infomration to \a i
|
|
285
|
+
void set_info(int i);
|
|
286
|
+
/// set the minimal k-capacity to min
|
|
287
|
+
void set_kmin(int min);
|
|
288
|
+
/// set the maximal k-capacity to max
|
|
289
|
+
void set_kmax(int max);
|
|
290
|
+
//@}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/// Class for edges \f$ e(x,v) \f$ in the variable-value-graph
|
|
294
|
+
class Edge{
|
|
295
|
+
private:
|
|
296
|
+
/// pointer to the variable node
|
|
297
|
+
VarNode* x;
|
|
298
|
+
/// pointer to the value node
|
|
299
|
+
ValNode* v;
|
|
300
|
+
/// pointer to the next edge incident on the same variable node
|
|
301
|
+
Edge* next_edge;
|
|
302
|
+
/// pointer to the previous edge incident on the same variable node
|
|
303
|
+
Edge* prev_edge;
|
|
304
|
+
/// pointer to the next edge on the same value node
|
|
305
|
+
Edge* next_vedge;
|
|
306
|
+
/// pointer to the previous edge on the same value node
|
|
307
|
+
Edge* prev_vedge;
|
|
308
|
+
/**
|
|
309
|
+
* \brief stores whether the edge is used in LBC
|
|
310
|
+
* Flag storing whether the edge is used in any maximum LBC matching
|
|
311
|
+
* in the variable-value-graph
|
|
312
|
+
*/
|
|
313
|
+
bool mrklb;
|
|
314
|
+
/**
|
|
315
|
+
* \brief stores whether the edge is used in UBC
|
|
316
|
+
* Flag storing whether the edge is used in any maximum UBC matching
|
|
317
|
+
* in the variable-value-graph
|
|
318
|
+
*/
|
|
319
|
+
bool mrkub;
|
|
320
|
+
/// stores whether the edge is matched in LBC matching
|
|
321
|
+
bool um;
|
|
322
|
+
/// stores whether the edge is matched in UBC matching
|
|
323
|
+
bool lm;
|
|
324
|
+
/// stores whether the edge has been deleted during syncronization
|
|
325
|
+
bool deleted; // del
|
|
326
|
+
|
|
327
|
+
public:
|
|
328
|
+
/// \name Constructors
|
|
329
|
+
//@{
|
|
330
|
+
/**
|
|
331
|
+
* \brief Construct edge \f$e(x,v)\f$ from variable node \a x
|
|
332
|
+
* and value node \a y
|
|
333
|
+
*/
|
|
334
|
+
Edge(VarNode* x, ValNode* v);
|
|
335
|
+
/// Create a new edge in memory
|
|
336
|
+
void* operator new(size_t, void*);
|
|
337
|
+
//@}
|
|
338
|
+
|
|
339
|
+
/// \name Access
|
|
340
|
+
//@{
|
|
341
|
+
/**
|
|
342
|
+
* \brief return whether the edge is used
|
|
343
|
+
*
|
|
344
|
+
* An edge can be used in a matching on the graph,
|
|
345
|
+
* a path on the graph or a cycle in the graph.
|
|
346
|
+
*
|
|
347
|
+
*/
|
|
348
|
+
template <BC>
|
|
349
|
+
bool used(void);
|
|
350
|
+
/// return whether the edge is matched
|
|
351
|
+
template <BC>
|
|
352
|
+
bool matched(void);
|
|
353
|
+
/// return whether the edge has been deleted from the graph
|
|
354
|
+
bool is_deleted(void);
|
|
355
|
+
/**
|
|
356
|
+
* \brief return a pointer to the next edge
|
|
357
|
+
* If \a t is false the function returns the next edge incident on \a x
|
|
358
|
+
* otherwise it returns the next edge incident on \a v
|
|
359
|
+
*/
|
|
360
|
+
Edge* next(bool t) const;
|
|
361
|
+
/// return the pointer to the next edge incident on \a x
|
|
362
|
+
Edge* next(void) const;
|
|
363
|
+
/// return the pointer to the previous edge incident on \a x
|
|
364
|
+
Edge* prev(void) const;
|
|
365
|
+
/// return the pointer to the next edge incident on \a v
|
|
366
|
+
Edge* vnext(void) const;
|
|
367
|
+
/// return the pointer to the previous edge incident on \a v
|
|
368
|
+
Edge* vprev(void) const;
|
|
369
|
+
/// return the pointer to the variable node \a x of this edge
|
|
370
|
+
VarNode* getVar(void);
|
|
371
|
+
/// return the pointer to the value node \a v of this edge
|
|
372
|
+
ValNode* getVal(void);
|
|
373
|
+
/**
|
|
374
|
+
* \brief return pointer to \a x if \a t = true otherwise return \a v
|
|
375
|
+
*
|
|
376
|
+
*/
|
|
377
|
+
VVGNode* getMate(bool t);
|
|
378
|
+
//@}
|
|
379
|
+
|
|
380
|
+
/// Update
|
|
381
|
+
//@{
|
|
382
|
+
/// Mark the edge as used
|
|
383
|
+
template <BC>
|
|
384
|
+
void use(void);
|
|
385
|
+
/// Mark the edge as unused
|
|
386
|
+
template <BC>
|
|
387
|
+
void free(void);
|
|
388
|
+
/**
|
|
389
|
+
* \brief Reset the edge ( free the edge, and unmatch
|
|
390
|
+
* the edge including its end-nodes
|
|
391
|
+
*
|
|
392
|
+
*/
|
|
393
|
+
template <BC>
|
|
394
|
+
void reset(void);
|
|
395
|
+
/// Match the edge
|
|
396
|
+
template <BC>
|
|
397
|
+
void match(void);
|
|
398
|
+
/// Unmatch the edge and the incident nodes
|
|
399
|
+
template <BC>
|
|
400
|
+
void unmatch(void);
|
|
401
|
+
/// Unmatch the edge and ( \a x if t=false, \a v otherwise )
|
|
402
|
+
template <BC>
|
|
403
|
+
void unmatch(bool t);
|
|
404
|
+
/// Unlink the edge from the linked list of edges
|
|
405
|
+
void unlink(void);
|
|
406
|
+
/// Mark the edge as deleted during synchronization
|
|
407
|
+
void del_edge(void);
|
|
408
|
+
/// Insert the edge again
|
|
409
|
+
void insert_edge(void);
|
|
410
|
+
/// return the reference to the next edge incident on \a x
|
|
411
|
+
Edge** next_ref(void);
|
|
412
|
+
/// return the reference to the previous edge incident on \a x
|
|
413
|
+
Edge** prev_ref(void);
|
|
414
|
+
/// return the reference to the next edge incident on \a v
|
|
415
|
+
Edge** vnext_ref(void);
|
|
416
|
+
/// return the reference to the previous edge incident on \a v
|
|
417
|
+
Edge** vprev_ref(void);
|
|
418
|
+
//@}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
/// Debugging: print a variable node
|
|
422
|
+
inline std::ostream&
|
|
423
|
+
operator<<(std::ostream& os, VarNode* v) {
|
|
424
|
+
os << v->var<<":{";
|
|
425
|
+
for (Edge* e = v->first(); e != NULL; e = e->next()) {
|
|
426
|
+
os << e->getVal()->val<<",";
|
|
427
|
+
}
|
|
428
|
+
os << "}(";
|
|
429
|
+
os << v->xindex << ") ";
|
|
430
|
+
return os;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/// Debugging: print a value node
|
|
434
|
+
inline std::ostream&
|
|
435
|
+
operator<<(std::ostream& os, ValNode* v) {
|
|
436
|
+
os << v->val<<":{";
|
|
437
|
+
for (Edge* e = v->first(); e != NULL; e = e->vnext()) {
|
|
438
|
+
os << e->getVar()->var<<",";
|
|
439
|
+
}
|
|
440
|
+
os << "} ";
|
|
441
|
+
return os;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* \brief Variable-value-graph used during propagation
|
|
446
|
+
*
|
|
447
|
+
*/
|
|
448
|
+
template <class View, class Card, bool isView>
|
|
449
|
+
class VarValGraph{
|
|
450
|
+
private:
|
|
451
|
+
/// failure flag
|
|
452
|
+
bool fail;
|
|
453
|
+
/// Allocated memory for nodes and edges
|
|
454
|
+
char* mem;
|
|
455
|
+
/// Problem variables
|
|
456
|
+
ViewArray<View>& x;
|
|
457
|
+
/// Copy keeping track of removed variables
|
|
458
|
+
ViewArray<View>& y;
|
|
459
|
+
/// Occurences
|
|
460
|
+
ViewArray<Card>& k;
|
|
461
|
+
/// Variable partition representing the problem variables
|
|
462
|
+
VarNode** vars;
|
|
463
|
+
/**
|
|
464
|
+
* \brief Value partition
|
|
465
|
+
* For each value
|
|
466
|
+
* \f$ v_i\in V=\left(\bigcup_\{0, \dots, |x|-1\}\right) D_i \f$
|
|
467
|
+
* in the domains of the
|
|
468
|
+
* problem variables there is a node in the graph.
|
|
469
|
+
*/
|
|
470
|
+
ValNode** vals; // value partition De
|
|
471
|
+
/// the edges connecting the variable and the value partition
|
|
472
|
+
Edge* edges; // edges e
|
|
473
|
+
/// cardinality of the variable partition
|
|
474
|
+
int n_var;
|
|
475
|
+
/**
|
|
476
|
+
* \brief cardinality of the value partition
|
|
477
|
+
*
|
|
478
|
+
* Computed as \f$ |V| = \left(\bigcup_\{0, \dots, |x|-1\}\right) D_i \f$
|
|
479
|
+
*/
|
|
480
|
+
int n_val;
|
|
481
|
+
/// the number of edges in the graph
|
|
482
|
+
int n_edge;
|
|
483
|
+
/// total number of nodes in the graph
|
|
484
|
+
int node_size;
|
|
485
|
+
/**
|
|
486
|
+
* \brief The sum over the minimal capacities of all value nodes
|
|
487
|
+
*
|
|
488
|
+
* \f$sum_min = \sum_{v_i \in V} l_i= k[i].min() \f$
|
|
489
|
+
*/
|
|
490
|
+
int sum_min;
|
|
491
|
+
/**
|
|
492
|
+
* \brief The sum over the maximal capacities of all value nodes
|
|
493
|
+
*
|
|
494
|
+
* \f$sum_max = \sum_{v_i \in V} l_i= k[i].max() \f$
|
|
495
|
+
*/
|
|
496
|
+
int sum_max;
|
|
497
|
+
public:
|
|
498
|
+
/// \name Constructors and Destructors
|
|
499
|
+
//@{
|
|
500
|
+
VarValGraph(ViewArray<View>&, ViewArray<View>&, ViewArray<Card>&,
|
|
501
|
+
int , int , int );
|
|
502
|
+
/// Destructor
|
|
503
|
+
~VarValGraph(void);
|
|
504
|
+
//@}
|
|
505
|
+
/// \name Graph-interface
|
|
506
|
+
//@{
|
|
507
|
+
/**
|
|
508
|
+
* \brief Check whether propagation failed
|
|
509
|
+
* This is actually needed to cope with failures
|
|
510
|
+
* occuring in functions returing only a boolean value
|
|
511
|
+
* and not an ExecStatus.
|
|
512
|
+
*/
|
|
513
|
+
bool failed(void);
|
|
514
|
+
/**
|
|
515
|
+
* \brief Set the failure flag of the graph
|
|
516
|
+
*/
|
|
517
|
+
void failed(bool b);
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* \brief Check whether minimum requirements shrink variable domains
|
|
521
|
+
*
|
|
522
|
+
*/
|
|
523
|
+
bool min_require(Space* home);
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* \brief Synchronization of the graph
|
|
527
|
+
*
|
|
528
|
+
* If the graph has already been constructed and some edges have
|
|
529
|
+
* been removed during propagation \fn sync removes those edges
|
|
530
|
+
* that do not longer belong to the graph associated with the current
|
|
531
|
+
* variable domains.
|
|
532
|
+
*/
|
|
533
|
+
bool sync(void);
|
|
534
|
+
|
|
535
|
+
/// Print graph information for debugging
|
|
536
|
+
void print_graph(void);
|
|
537
|
+
/// Print matching information for debugging
|
|
538
|
+
template <BC>
|
|
539
|
+
void print_matching(void);
|
|
540
|
+
/// Gather matching information
|
|
541
|
+
void print_match(void);
|
|
542
|
+
|
|
543
|
+
/// Print edge information
|
|
544
|
+
void print_edges(void);
|
|
545
|
+
|
|
546
|
+
/// Allocate memory for the graph
|
|
547
|
+
void* operator new(size_t t);
|
|
548
|
+
/// Free the memory for the graph
|
|
549
|
+
void operator delete(void* p);
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* \brief Remove all those edges from the graph
|
|
553
|
+
* that do not belong
|
|
554
|
+
* to any possible maximum matching on the graph
|
|
555
|
+
*
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
template <BC>
|
|
559
|
+
bool narrow(Space*);
|
|
560
|
+
|
|
561
|
+
/** \brief Compute a maximum matching M on the graph
|
|
562
|
+
*
|
|
563
|
+
* - If BC=UBC then \f$|M|= |X|\f$
|
|
564
|
+
* - If BC=LBC then \f$|M|= \sum_{i\in \{ 0, \dots, |X|-1\}}
|
|
565
|
+
* k[i].min()\f$
|
|
566
|
+
*/
|
|
567
|
+
template <BC>
|
|
568
|
+
bool maximum_matching(void);
|
|
569
|
+
|
|
570
|
+
/// Compute possible free alternating paths in the graph
|
|
571
|
+
template <BC>
|
|
572
|
+
void free_alternating_paths(void);
|
|
573
|
+
/// Compute possible strongly connected components of the graph
|
|
574
|
+
template <BC>
|
|
575
|
+
void strongly_connected_components(void);
|
|
576
|
+
/**
|
|
577
|
+
* \brief Test whether the current maximal matching on the graph
|
|
578
|
+
* can be augmented by an alternating path starting and ending with
|
|
579
|
+
* a free node.
|
|
580
|
+
*/
|
|
581
|
+
template <BC>
|
|
582
|
+
bool augmenting_path(VVGNode*);
|
|
583
|
+
|
|
584
|
+
protected:
|
|
585
|
+
/**
|
|
586
|
+
* \brief Perform depth-first search on the graph
|
|
587
|
+
*
|
|
588
|
+
* Depth first search used to compute the
|
|
589
|
+
* strongly connected components of the graph.
|
|
590
|
+
*/
|
|
591
|
+
template <BC>
|
|
592
|
+
void dfs(VVGNode*,
|
|
593
|
+
bool[], bool[], int[],
|
|
594
|
+
Support::StaticStack<VVGNode*>&,
|
|
595
|
+
Support::StaticStack<VVGNode*>&,
|
|
596
|
+
int&);
|
|
597
|
+
|
|
598
|
+
//@}
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
forceinline
|
|
602
|
+
VVGNode::VVGNode(void){} //no-op
|
|
603
|
+
|
|
604
|
+
forceinline void*
|
|
605
|
+
VVGNode::operator new(size_t n, void* p){
|
|
606
|
+
return p;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
forceinline Edge**
|
|
610
|
+
VVGNode::adj(void){
|
|
611
|
+
return &e;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
forceinline Edge*
|
|
615
|
+
VVGNode::first(void){
|
|
616
|
+
return fst;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
forceinline Edge*
|
|
620
|
+
VVGNode::last(void){
|
|
621
|
+
return lst;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
forceinline void
|
|
625
|
+
VVGNode::first(Edge* p){
|
|
626
|
+
fst = p;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
forceinline void
|
|
630
|
+
VVGNode::last(Edge* p){
|
|
631
|
+
lst = p;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
forceinline bool
|
|
635
|
+
VVGNode::get_type(void){
|
|
636
|
+
return type;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
forceinline void
|
|
640
|
+
VVGNode::set_type(bool b){
|
|
641
|
+
type = b;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
forceinline Edge*
|
|
645
|
+
VVGNode::inedge(void){
|
|
646
|
+
return ie;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
forceinline void
|
|
650
|
+
VVGNode::inedge(Edge* p){
|
|
651
|
+
ie = p;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
template <BC direction>
|
|
655
|
+
forceinline void
|
|
656
|
+
VVGNode::set_match_flag(bool b){
|
|
657
|
+
if (direction == UBC) {
|
|
658
|
+
um = b;
|
|
659
|
+
} else {
|
|
660
|
+
lm = b;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
template <BC direction>
|
|
665
|
+
forceinline bool
|
|
666
|
+
VVGNode::get_match_flag(void){
|
|
667
|
+
if (direction == UBC) {
|
|
668
|
+
return um;
|
|
669
|
+
} else {
|
|
670
|
+
return lm;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
/// Variable Node
|
|
676
|
+
|
|
677
|
+
forceinline bool
|
|
678
|
+
VarNode::removed(void) {
|
|
679
|
+
return noe == 0;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
forceinline
|
|
685
|
+
VarNode::VarNode(int x, int orig_idx) :
|
|
686
|
+
ubm(NULL), lbm(NULL), var(x), noe(0), xindex(orig_idx){
|
|
687
|
+
first(NULL);
|
|
688
|
+
last(NULL);
|
|
689
|
+
inedge(NULL);
|
|
690
|
+
unmatch<LBC>();
|
|
691
|
+
unmatch<UBC>();
|
|
692
|
+
set_type(false);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
forceinline bool
|
|
696
|
+
VarNode::is_matched(BC d) {
|
|
697
|
+
if (d == UBC) {
|
|
698
|
+
return matched<UBC>();
|
|
699
|
+
} else {
|
|
700
|
+
return matched<LBC>();
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
template <BC direction>
|
|
705
|
+
forceinline bool
|
|
706
|
+
VarNode::matched(void){
|
|
707
|
+
return get_match_flag<direction>();
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
template <BC direction>
|
|
711
|
+
forceinline void
|
|
712
|
+
VarNode::match(void){
|
|
713
|
+
set_match_flag<direction>(true);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
template <BC direction>
|
|
717
|
+
forceinline void
|
|
718
|
+
VarNode::unmatch(void){
|
|
719
|
+
set_match_flag<direction>(false);
|
|
720
|
+
set_match<direction>(NULL);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
template <BC direction>
|
|
724
|
+
forceinline void
|
|
725
|
+
VarNode::set_match(Edge* p){
|
|
726
|
+
if (direction == UBC) {
|
|
727
|
+
ubm = p;
|
|
728
|
+
} else {
|
|
729
|
+
lbm = p;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
template <BC direction>
|
|
734
|
+
forceinline Edge*
|
|
735
|
+
VarNode::get_match(void){
|
|
736
|
+
if (direction == UBC) {
|
|
737
|
+
return ubm;
|
|
738
|
+
} else {
|
|
739
|
+
return lbm;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
forceinline void
|
|
744
|
+
VarNode::set_info(int i){
|
|
745
|
+
var = i;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
forceinline int
|
|
749
|
+
VarNode::get_info(void){
|
|
750
|
+
return var;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/// Value Node
|
|
754
|
+
|
|
755
|
+
forceinline void
|
|
756
|
+
ValNode::set_maxlow(int i){
|
|
757
|
+
assert(i >= lb);
|
|
758
|
+
ublow = i;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
forceinline int
|
|
762
|
+
ValNode::get_maxlow(void) {
|
|
763
|
+
if (_klb == _kub) {
|
|
764
|
+
assert(ublow == lb);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
return ublow;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
forceinline void
|
|
772
|
+
ValNode::card_conflict(int c){
|
|
773
|
+
noc = c;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
forceinline void
|
|
777
|
+
ValNode::red_conflict(void){
|
|
778
|
+
noc--;
|
|
779
|
+
assert(noc >= 0);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
forceinline int
|
|
783
|
+
ValNode::card_conflict(void){
|
|
784
|
+
return noc;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
forceinline bool
|
|
788
|
+
ValNode::removed(void) {
|
|
789
|
+
return noe == 0;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
forceinline bool
|
|
793
|
+
ValNode::is_matched(BC d) {
|
|
794
|
+
if (d == UBC) {
|
|
795
|
+
return matched<UBC>();
|
|
796
|
+
} else {
|
|
797
|
+
return ublow == 0;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
forceinline void
|
|
802
|
+
ValNode::reset(void){
|
|
803
|
+
lb = _klb;
|
|
804
|
+
ublow = _kub;
|
|
805
|
+
ub = _kub;
|
|
806
|
+
noe = 0;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
template <BC direction>
|
|
810
|
+
forceinline int
|
|
811
|
+
ValNode::kbound(void){
|
|
812
|
+
if (direction == UBC) {
|
|
813
|
+
return _kub;
|
|
814
|
+
} else {
|
|
815
|
+
return _klb;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
forceinline int
|
|
820
|
+
ValNode::kmax(void){
|
|
821
|
+
return _kub;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
forceinline int
|
|
825
|
+
ValNode::kmin(void){
|
|
826
|
+
return _klb;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
forceinline void
|
|
830
|
+
ValNode::set_kmin(int klb){
|
|
831
|
+
_klb = klb;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
forceinline void
|
|
835
|
+
ValNode::set_kmax(int kub){
|
|
836
|
+
_kub = kub;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
template <BC direction>
|
|
840
|
+
forceinline int
|
|
841
|
+
ValNode::cap(void){
|
|
842
|
+
if (direction == UBC) {
|
|
843
|
+
return ub;
|
|
844
|
+
} else {
|
|
845
|
+
return lb;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
template <BC direction>
|
|
850
|
+
forceinline void
|
|
851
|
+
ValNode::dec(void){
|
|
852
|
+
if (direction == UBC) {
|
|
853
|
+
ub--;
|
|
854
|
+
} else {
|
|
855
|
+
lb--;
|
|
856
|
+
ublow--;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
template <BC direction>
|
|
861
|
+
forceinline void
|
|
862
|
+
ValNode::inc(void){
|
|
863
|
+
if (direction == UBC) {
|
|
864
|
+
ub++;
|
|
865
|
+
} else {
|
|
866
|
+
lb++;
|
|
867
|
+
ublow++;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
template <BC direction>
|
|
872
|
+
forceinline void
|
|
873
|
+
ValNode::match(void){
|
|
874
|
+
dec<direction>();
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
template <BC direction>
|
|
878
|
+
forceinline void
|
|
879
|
+
ValNode::unmatch(void){
|
|
880
|
+
inc<direction>();
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
template <BC direction>
|
|
884
|
+
forceinline bool
|
|
885
|
+
ValNode::matched(void){
|
|
886
|
+
return ( cap<direction>() == 0);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
forceinline
|
|
890
|
+
ValNode::ValNode(int min, int max, int value,
|
|
891
|
+
int kidx, int kshift, int count) :
|
|
892
|
+
_klb(min), _kub(max), _kidx(kidx), _kcount(count),
|
|
893
|
+
noc(0),
|
|
894
|
+
lb(min), ublow(max), ub(max),
|
|
895
|
+
val(value), idx(kshift), noe(0) {
|
|
896
|
+
first(NULL);
|
|
897
|
+
last(NULL);
|
|
898
|
+
inedge(NULL);
|
|
899
|
+
Edge** vadjacent = adj();
|
|
900
|
+
*vadjacent = NULL;
|
|
901
|
+
set_type(true);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
template<BC direction>
|
|
905
|
+
forceinline void
|
|
906
|
+
ValNode::set_cap(int c){
|
|
907
|
+
if (direction == UBC) {
|
|
908
|
+
ub = c;
|
|
909
|
+
} else {
|
|
910
|
+
lb = c;
|
|
911
|
+
// ublow = c;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
forceinline void
|
|
916
|
+
ValNode::set_info(int i){
|
|
917
|
+
idx = i;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
forceinline int
|
|
921
|
+
ValNode::get_info(void){
|
|
922
|
+
return idx;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
forceinline void
|
|
926
|
+
ValNode::inc(void) {
|
|
927
|
+
_kcount++;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
forceinline int
|
|
931
|
+
ValNode::kcount(void) {
|
|
932
|
+
return _kcount;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
forceinline void
|
|
936
|
+
ValNode::kcount(int c) {
|
|
937
|
+
_kcount = c;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
forceinline void
|
|
941
|
+
ValNode::kindex(int i){
|
|
942
|
+
_kidx = i;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
forceinline int
|
|
946
|
+
ValNode::kindex(void){
|
|
947
|
+
return _kidx;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/// Returs the number of incident matching edges on the node
|
|
951
|
+
template <BC direction>
|
|
952
|
+
forceinline int
|
|
953
|
+
ValNode::incid_match(void){
|
|
954
|
+
if (direction == LBC) {
|
|
955
|
+
// std::cout << "LBC: "<< _kub <<"-"<<ublow <<"+"<<_kcount<<"\n";
|
|
956
|
+
return _kub - ublow + _kcount;
|
|
957
|
+
} else {
|
|
958
|
+
// std::cout << "UBC: "<< _kub <<"-"<<ub <<"+"<<_kcount<<"\n";
|
|
959
|
+
return _kub - ub + _kcount;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
forceinline bool
|
|
965
|
+
ValNode::sink(void){
|
|
966
|
+
// there are only incoming edges
|
|
967
|
+
// in case of the UBC-matching
|
|
968
|
+
bool is_sink = false;
|
|
969
|
+
is_sink = (_kub - ub == noe);
|
|
970
|
+
return is_sink;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
forceinline bool
|
|
974
|
+
ValNode::source(void){
|
|
975
|
+
// there are only incoming edges
|
|
976
|
+
// in case of the UBC-matching
|
|
977
|
+
bool is_sink = false;
|
|
978
|
+
is_sink = (_klb - lb == noe);
|
|
979
|
+
return is_sink;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/// Edge
|
|
983
|
+
/// Debugging: print an edge
|
|
984
|
+
inline std::ostream&
|
|
985
|
+
operator<<(std::ostream& os, Edge* e){
|
|
986
|
+
if (e== NULL) {
|
|
987
|
+
os << "(N)";
|
|
988
|
+
} else {
|
|
989
|
+
os << "e("<<e->getVar()->var<<","<<e->getVal()->val<<")";
|
|
990
|
+
}
|
|
991
|
+
return os;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
forceinline void
|
|
996
|
+
Edge::unlink(void){
|
|
997
|
+
// unlink from variable side
|
|
998
|
+
Edge* p = prev_edge;
|
|
999
|
+
Edge* n = next_edge;
|
|
1000
|
+
|
|
1001
|
+
if (p != NULL) {
|
|
1002
|
+
Edge** pnext = p->next_ref();
|
|
1003
|
+
*pnext = n;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (n != NULL) {
|
|
1007
|
+
Edge** nprev = n->prev_ref();
|
|
1008
|
+
*nprev = p;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
if (this == x->first()) {
|
|
1012
|
+
Edge** ref = x->adj();
|
|
1013
|
+
*ref = n;
|
|
1014
|
+
x->first(n);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if (this == x->last()) {
|
|
1018
|
+
x->last(p);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// unlink from value side
|
|
1022
|
+
Edge* pv = prev_vedge;
|
|
1023
|
+
Edge* nv = next_vedge;
|
|
1024
|
+
|
|
1025
|
+
if (pv != NULL) {
|
|
1026
|
+
Edge** pvnext = pv->vnext_ref();
|
|
1027
|
+
*pvnext = nv;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
if (nv != NULL) {
|
|
1031
|
+
Edge** nvprev = nv->vprev_ref();
|
|
1032
|
+
*nvprev = pv;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
if (this == v->first()) {
|
|
1036
|
+
Edge** ref = v->adj();
|
|
1037
|
+
*ref = nv;
|
|
1038
|
+
v->first(nv);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
if (this == v->last()) {
|
|
1042
|
+
v->last(pv);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
forceinline
|
|
1047
|
+
Edge::Edge(VarNode* var, ValNode* val) :
|
|
1048
|
+
x(var), v(val),
|
|
1049
|
+
next_edge(NULL), prev_edge(NULL),
|
|
1050
|
+
next_vedge(NULL), prev_vedge(NULL),
|
|
1051
|
+
mrklb(false), mrkub(false),
|
|
1052
|
+
um(false), lm(false), deleted(false) {};
|
|
1053
|
+
|
|
1054
|
+
forceinline void*
|
|
1055
|
+
Edge::operator new(size_t, void* p){ //why is there no argument?
|
|
1056
|
+
return p;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
template <BC direction>
|
|
1060
|
+
forceinline void
|
|
1061
|
+
Edge::use(void){
|
|
1062
|
+
if (direction == UBC) {
|
|
1063
|
+
mrkub = true;
|
|
1064
|
+
} else {
|
|
1065
|
+
mrklb = true;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
template <BC direction>
|
|
1070
|
+
forceinline void
|
|
1071
|
+
Edge::free(void){
|
|
1072
|
+
/// the failure is here, capacity is not increased for value nodes
|
|
1073
|
+
if (direction == UBC) {
|
|
1074
|
+
mrkub = false;
|
|
1075
|
+
} else {
|
|
1076
|
+
mrklb = false;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
template <BC direction>
|
|
1081
|
+
forceinline void
|
|
1082
|
+
Edge::reset(void){
|
|
1083
|
+
this->free<direction>();
|
|
1084
|
+
this->unmatch<direction>();
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
template <BC direction>
|
|
1088
|
+
forceinline bool
|
|
1089
|
+
Edge::used(void){
|
|
1090
|
+
if (direction == UBC){
|
|
1091
|
+
return mrkub;
|
|
1092
|
+
} else {
|
|
1093
|
+
return mrklb;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
forceinline Edge*
|
|
1098
|
+
Edge::next(void) const{
|
|
1099
|
+
return next_edge;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
forceinline Edge*
|
|
1103
|
+
Edge::next(bool t) const{
|
|
1104
|
+
if (t) {
|
|
1105
|
+
return next_vedge;
|
|
1106
|
+
} else {
|
|
1107
|
+
return next_edge;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
forceinline Edge*
|
|
1112
|
+
Edge::vnext(void) const{
|
|
1113
|
+
return next_vedge;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
forceinline Edge**
|
|
1117
|
+
Edge::vnext_ref(void) {
|
|
1118
|
+
return &next_vedge;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
forceinline Edge*
|
|
1122
|
+
Edge::prev(void) const{
|
|
1123
|
+
return prev_edge;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
forceinline Edge**
|
|
1127
|
+
Edge::prev_ref(void) {
|
|
1128
|
+
return &prev_edge;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
forceinline Edge*
|
|
1132
|
+
Edge::vprev(void) const{
|
|
1133
|
+
return prev_vedge;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
forceinline Edge**
|
|
1137
|
+
Edge::vprev_ref(void) {
|
|
1138
|
+
return &prev_vedge;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
forceinline Edge**
|
|
1142
|
+
Edge::next_ref(void){
|
|
1143
|
+
return &next_edge;
|
|
1144
|
+
}
|
|
1145
|
+
forceinline VarNode*
|
|
1146
|
+
Edge::getVar(void){
|
|
1147
|
+
assert(x != NULL);
|
|
1148
|
+
return x;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
forceinline ValNode*
|
|
1152
|
+
Edge::getVal(void){
|
|
1153
|
+
assert(v != NULL);
|
|
1154
|
+
return v;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
forceinline VVGNode*
|
|
1158
|
+
Edge::getMate(bool type){
|
|
1159
|
+
if (type) {
|
|
1160
|
+
return x;
|
|
1161
|
+
} else {
|
|
1162
|
+
return v;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
template <BC direction>
|
|
1167
|
+
forceinline void
|
|
1168
|
+
Edge::unmatch(void){
|
|
1169
|
+
if (direction == UBC) {
|
|
1170
|
+
um = false;
|
|
1171
|
+
} else {
|
|
1172
|
+
lm = false;
|
|
1173
|
+
}
|
|
1174
|
+
x->unmatch<direction>();
|
|
1175
|
+
v->unmatch<direction>();
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
template <BC direction>
|
|
1179
|
+
forceinline void
|
|
1180
|
+
Edge::unmatch(bool node){
|
|
1181
|
+
if (direction == UBC) {
|
|
1182
|
+
um = false;
|
|
1183
|
+
} else {
|
|
1184
|
+
lm = false;
|
|
1185
|
+
}
|
|
1186
|
+
if (node) {
|
|
1187
|
+
v->template unmatch<direction>();
|
|
1188
|
+
} else {
|
|
1189
|
+
x->template unmatch<direction>();
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
template <BC direction>
|
|
1194
|
+
forceinline void
|
|
1195
|
+
Edge::match(void){
|
|
1196
|
+
if (direction == UBC) {
|
|
1197
|
+
um = true;
|
|
1198
|
+
x->template match<direction>();
|
|
1199
|
+
x->template set_match<direction>(this);
|
|
1200
|
+
v->template match<direction>();
|
|
1201
|
+
} else {
|
|
1202
|
+
lm = true;
|
|
1203
|
+
x->template match<direction>();
|
|
1204
|
+
x->template set_match<direction>(this);
|
|
1205
|
+
assert(x->template matched<direction>());
|
|
1206
|
+
v->template match<direction>();
|
|
1207
|
+
// assert(v->template matched<direction>());
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
template <BC direction>
|
|
1212
|
+
forceinline bool
|
|
1213
|
+
Edge::matched(void){
|
|
1214
|
+
if (direction == UBC) {
|
|
1215
|
+
return um;
|
|
1216
|
+
} else {
|
|
1217
|
+
return lm;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
forceinline void
|
|
1222
|
+
Edge::del_edge(void){
|
|
1223
|
+
deleted = true;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
forceinline void
|
|
1227
|
+
Edge::insert_edge(void){
|
|
1228
|
+
deleted = false;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
forceinline bool
|
|
1233
|
+
Edge::is_deleted(void){
|
|
1234
|
+
return deleted;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/**
|
|
1238
|
+
* \brief Constructor for the variable-value-graph
|
|
1239
|
+
*
|
|
1240
|
+
* The variable parition is initialized with the variables from \a x,
|
|
1241
|
+
* the value partition is initialized with the values from \a v,
|
|
1242
|
+
* where \f$ \forall v_i\in V:\f$ \a val_idx[i] is the
|
|
1243
|
+
* index of \f$ v_i\f$ in \f$ k \f$. \a nov denotes the cardinality of the
|
|
1244
|
+
* value partition in the graph, \a noe the number of edges in the
|
|
1245
|
+
* graph, \a min_occ the sum over the minimal occurences
|
|
1246
|
+
* of all values and \a max_occ the sum over the maximal occurences
|
|
1247
|
+
* of all values.
|
|
1248
|
+
**/
|
|
1249
|
+
|
|
1250
|
+
template <class View, class Card, bool isView>
|
|
1251
|
+
VarValGraph<View, Card, isView>::VarValGraph(ViewArray<View>& xref,
|
|
1252
|
+
ViewArray<View>& yref,
|
|
1253
|
+
ViewArray<Card>& kref,
|
|
1254
|
+
int noe,
|
|
1255
|
+
int smin, int smax)
|
|
1256
|
+
: fail(false),
|
|
1257
|
+
x(xref),
|
|
1258
|
+
y(yref),
|
|
1259
|
+
k(kref),
|
|
1260
|
+
n_var(x.size()),
|
|
1261
|
+
n_val(k.size()),
|
|
1262
|
+
n_edge(noe),
|
|
1263
|
+
node_size(n_var + n_val),
|
|
1264
|
+
sum_min(smin),
|
|
1265
|
+
sum_max(smax) {
|
|
1266
|
+
|
|
1267
|
+
//memory allocation
|
|
1268
|
+
size_t edge_size = sizeof(Edge) * n_edge;
|
|
1269
|
+
size_t var_size = sizeof(VarNode) * n_var;
|
|
1270
|
+
size_t var_ptr_size = sizeof(VarNode*) * n_var;
|
|
1271
|
+
size_t val_size = sizeof(ValNode) * n_val;
|
|
1272
|
+
size_t val_ptr_size = sizeof(ValNode*) * n_val;
|
|
1273
|
+
size_t size = edge_size + var_size + var_ptr_size +
|
|
1274
|
+
val_size + val_ptr_size;
|
|
1275
|
+
|
|
1276
|
+
mem = reinterpret_cast<char*>
|
|
1277
|
+
(Memory::malloc(size));
|
|
1278
|
+
edges = reinterpret_cast<Edge*>
|
|
1279
|
+
(mem);
|
|
1280
|
+
VarNode* vars_ptr = reinterpret_cast<VarNode*>
|
|
1281
|
+
(mem + edge_size);
|
|
1282
|
+
ValNode* vals_ptr = reinterpret_cast<ValNode*>
|
|
1283
|
+
(mem + edge_size + var_size);
|
|
1284
|
+
vars = reinterpret_cast<VarNode**>
|
|
1285
|
+
(mem + edge_size + var_size + val_size);
|
|
1286
|
+
vals = reinterpret_cast<ValNode**>
|
|
1287
|
+
(mem + edge_size + var_size + val_size + var_ptr_size);
|
|
1288
|
+
|
|
1289
|
+
for (int i = n_val; i--; ){
|
|
1290
|
+
int kmi = k[i].min();
|
|
1291
|
+
int kma = k[i].max();
|
|
1292
|
+
int kc = k[i].counter();
|
|
1293
|
+
if (kc != kma) {
|
|
1294
|
+
if (kmi >= kc) {
|
|
1295
|
+
kmi -=kc;
|
|
1296
|
+
assert(kmi >=0);
|
|
1297
|
+
} else {
|
|
1298
|
+
kmi = 0;
|
|
1299
|
+
}
|
|
1300
|
+
kma -= kc;
|
|
1301
|
+
assert (kma > 0);
|
|
1302
|
+
vals[i] = new (vals_ptr + i)
|
|
1303
|
+
ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
|
|
1304
|
+
} else {
|
|
1305
|
+
vals[i] = new (vals_ptr + i)
|
|
1306
|
+
ValNode(0, 0, k[i].card(), i, i + n_var, kc);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
for (int i = n_var; i--; ){
|
|
1311
|
+
|
|
1312
|
+
vars[i] = new (vars_ptr + i) VarNode(i, i);
|
|
1313
|
+
VarNode* vrn = vars[i];
|
|
1314
|
+
// get the space for the edges of the varnode
|
|
1315
|
+
Edge** xadjacent = vrn->adj();
|
|
1316
|
+
|
|
1317
|
+
ViewValues<View> xiter(x[i]);
|
|
1318
|
+
int j = 0;
|
|
1319
|
+
for (; xiter(); ++xiter){
|
|
1320
|
+
int v = xiter.val();
|
|
1321
|
+
// get the correct index for the value
|
|
1322
|
+
while(vals[j]->val < v){
|
|
1323
|
+
j++;
|
|
1324
|
+
}
|
|
1325
|
+
ValNode* vln = vals[j];
|
|
1326
|
+
*xadjacent = new (edges) Edge(vars_ptr + i, vals_ptr + j);
|
|
1327
|
+
vrn->noe++;
|
|
1328
|
+
if (vrn->first() == NULL) {
|
|
1329
|
+
vrn->first(*xadjacent);
|
|
1330
|
+
}
|
|
1331
|
+
Edge* oldprev = vrn->last();
|
|
1332
|
+
vrn->last(*xadjacent);
|
|
1333
|
+
Edge** newprev = vrn->last()->prev_ref();
|
|
1334
|
+
*newprev = oldprev;
|
|
1335
|
+
|
|
1336
|
+
if (vln->first() == NULL) {
|
|
1337
|
+
vln->first(*xadjacent);
|
|
1338
|
+
vln->last(*xadjacent);
|
|
1339
|
+
vln->noe++;
|
|
1340
|
+
} else {
|
|
1341
|
+
Edge* old = vln->first();
|
|
1342
|
+
vln->first(*xadjacent);
|
|
1343
|
+
Edge** newnext = vln->first()->vnext_ref();
|
|
1344
|
+
*newnext = old;
|
|
1345
|
+
Edge** setprev = old->vprev_ref();
|
|
1346
|
+
*setprev = vln->first();
|
|
1347
|
+
vln->noe++;
|
|
1348
|
+
}
|
|
1349
|
+
edges++;
|
|
1350
|
+
xadjacent = (*xadjacent)->next_ref();
|
|
1351
|
+
}
|
|
1352
|
+
*xadjacent = NULL;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
template <class View, class Card, bool isView>
|
|
1357
|
+
forceinline bool
|
|
1358
|
+
VarValGraph<View, Card, isView>::failed(void){
|
|
1359
|
+
return fail;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
template <class View, class Card, bool isView>
|
|
1363
|
+
forceinline void
|
|
1364
|
+
VarValGraph<View, Card, isView>::failed(bool b){
|
|
1365
|
+
fail = b;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
template <class View, class Card, bool isView>
|
|
1371
|
+
inline bool
|
|
1372
|
+
VarValGraph<View, Card, isView>::min_require(Space* home){
|
|
1373
|
+
bool modified = false;
|
|
1374
|
+
for (int i = n_val; i--; ) {
|
|
1375
|
+
ValNode* vln = vals[i];
|
|
1376
|
+
if (vln->noe > 0) {
|
|
1377
|
+
if (k[i].min() == vln->noe) {
|
|
1378
|
+
// all variable nodes reachable from vln should be equal to vln->val
|
|
1379
|
+
for (Edge* e = vln->first(); e != NULL; e = e->vnext()) {
|
|
1380
|
+
VarNode* vrn = e->getVar();
|
|
1381
|
+
int vi = vrn->get_info();
|
|
1382
|
+
for (Edge* f = vrn->first(); f != NULL; f = f->next()) {
|
|
1383
|
+
if (f != e) {
|
|
1384
|
+
ValNode* w = f->getVal();
|
|
1385
|
+
w->noe--;
|
|
1386
|
+
vrn->noe--;
|
|
1387
|
+
f->del_edge();
|
|
1388
|
+
f->unlink();
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
assert(vrn->noe == 1);
|
|
1392
|
+
modified |= x[vi].modified();
|
|
1393
|
+
|
|
1394
|
+
x[vi].eq(home, vln->val);
|
|
1395
|
+
vars[vi] = vars[--n_var];
|
|
1396
|
+
vars[vi]->set_info(vi);
|
|
1397
|
+
|
|
1398
|
+
int n = x.size();
|
|
1399
|
+
x[vi] = x[--n];
|
|
1400
|
+
// x[vi].index(vi);
|
|
1401
|
+
x.size(n);
|
|
1402
|
+
|
|
1403
|
+
node_size--;
|
|
1404
|
+
vln->noe--;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
int vidx = vln->kindex();
|
|
1409
|
+
if (isView)
|
|
1410
|
+
k[vidx].eq(home, k[vidx].min());
|
|
1411
|
+
|
|
1412
|
+
k[vidx].counter(k[vidx].min());
|
|
1413
|
+
modified |= k[vidx].modified();
|
|
1414
|
+
|
|
1415
|
+
vln->template set_cap<UBC>(0);
|
|
1416
|
+
vln->template set_cap<LBC>(0);
|
|
1417
|
+
vln->set_maxlow(0);
|
|
1418
|
+
|
|
1419
|
+
if (sum_min && sum_min >= k[vidx].min()) {
|
|
1420
|
+
sum_min -= k[vidx].min();
|
|
1421
|
+
}
|
|
1422
|
+
assert(sum_min >=0);
|
|
1423
|
+
|
|
1424
|
+
if (sum_max && sum_max >= k[vidx].max()) {
|
|
1425
|
+
sum_max -= k[vidx].max();
|
|
1426
|
+
}
|
|
1427
|
+
assert(sum_max >=0);
|
|
1428
|
+
}
|
|
1429
|
+
} else {
|
|
1430
|
+
vals[i]->template set_cap<UBC>(0);
|
|
1431
|
+
vals[i]->template set_cap<LBC>(0);
|
|
1432
|
+
vals[i]->set_maxlow(0);
|
|
1433
|
+
vals[i]->set_kmax(0);
|
|
1434
|
+
vals[i]->set_kmin(0);
|
|
1435
|
+
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
if (isView) {
|
|
1439
|
+
if (k[i].counter() == 0) {
|
|
1440
|
+
ModEvent klq = k[i].lq(home, vals[i]->noe);
|
|
1441
|
+
if (me_failed(klq)) {
|
|
1442
|
+
failed(true);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
modified |= k[i].modified() && k[i].max() != vals[i]->noe;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
for (int i = n_val; i--; ) {
|
|
1450
|
+
vals[i]->set_info(n_var + i);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
return modified;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
template <class View, class Card, bool isView>
|
|
1457
|
+
inline bool
|
|
1458
|
+
VarValGraph<View, Card, isView>::sync(void){
|
|
1459
|
+
GECODE_AUTOARRAY(VVGNode*, re, node_size);
|
|
1460
|
+
int n_re = 0;
|
|
1461
|
+
|
|
1462
|
+
// synchronize cardinality variables
|
|
1463
|
+
if (isView) {
|
|
1464
|
+
for (int i = n_val; i--; ) {
|
|
1465
|
+
ValNode* v = vals[i];
|
|
1466
|
+
int inc_ubc = v->template incid_match<UBC>();
|
|
1467
|
+
int inc_lbc = v->template incid_match<LBC>();
|
|
1468
|
+
if (v->noe == 0) {
|
|
1469
|
+
inc_ubc = 0;
|
|
1470
|
+
inc_lbc = 0;
|
|
1471
|
+
}
|
|
1472
|
+
int rm = v->kmax() - k[i].max();
|
|
1473
|
+
// the cardinality bounds have been modified
|
|
1474
|
+
if (k[i].max() < v->kmax() || k[i].min() > v->kmin()) {
|
|
1475
|
+
if (k[i].max() != k[i].counter() || k[i].max() == 0) {
|
|
1476
|
+
// update the bounds
|
|
1477
|
+
v->set_kmax(k[i].max());
|
|
1478
|
+
v->set_kmin(k[i].min());
|
|
1479
|
+
|
|
1480
|
+
//everything is fine
|
|
1481
|
+
if (inc_ubc <= k[i].max()) {
|
|
1482
|
+
// adjust capacities
|
|
1483
|
+
v->template set_cap<UBC>(k[i].max() - (inc_ubc));
|
|
1484
|
+
v->set_maxlow(k[i].max() - (inc_lbc));
|
|
1485
|
+
if (v->kmin() == v->kmax()) {
|
|
1486
|
+
v->template set_cap<LBC>(k[i].max() - (inc_lbc));
|
|
1487
|
+
}
|
|
1488
|
+
} else {
|
|
1489
|
+
// set cap to max and resolve conflicts on view side
|
|
1490
|
+
// set to full capacity for later rescheduling
|
|
1491
|
+
if (v->template cap<UBC>()) {
|
|
1492
|
+
v->template set_cap<UBC>(k[i].max());
|
|
1493
|
+
}
|
|
1494
|
+
v->set_maxlow(k[i].max() - (inc_lbc));
|
|
1495
|
+
if (v->kmin() == v->kmax()) {
|
|
1496
|
+
v->template set_cap<LBC>(k[i].max() - (inc_lbc));
|
|
1497
|
+
}
|
|
1498
|
+
v->card_conflict(rm);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
if (inc_lbc < k[i].min() && v->noe > 0) {
|
|
1503
|
+
|
|
1504
|
+
v->template set_cap<LBC>(k[i].min() - inc_lbc);
|
|
1505
|
+
re[n_re] = v;
|
|
1506
|
+
n_re++;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
for (int i = n_var; i--; ) {
|
|
1511
|
+
Edge* mub = vars[i]->template get_match<UBC>();
|
|
1512
|
+
if (mub != NULL) {
|
|
1513
|
+
ValNode* vu = mub->getVal();
|
|
1514
|
+
if (! (vars[i]->noe == 1) ) {
|
|
1515
|
+
if (vu->card_conflict()) {
|
|
1516
|
+
vu->red_conflict();
|
|
1517
|
+
mub->template unmatch<UBC>(vars[i]->get_type());
|
|
1518
|
+
re[n_re] = vars[i];
|
|
1519
|
+
n_re++;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
// go on with synchronization
|
|
1527
|
+
assert(x.size() == n_var);
|
|
1528
|
+
for (int i = n_var; i--; ) {
|
|
1529
|
+
|
|
1530
|
+
VarNode* vrn = vars[i];
|
|
1531
|
+
if(x[i].size() != vrn->noe){
|
|
1532
|
+
// if the variable is already assigned
|
|
1533
|
+
if (x[i].assigned()) {
|
|
1534
|
+
int v = x[i].val();
|
|
1535
|
+
ValNode* rv = NULL;
|
|
1536
|
+
int rv_idx = 0;
|
|
1537
|
+
Edge* mub = vrn->template get_match<UBC>();
|
|
1538
|
+
if (mub != NULL) {
|
|
1539
|
+
if (v != mub->getVal()->val) {
|
|
1540
|
+
mub->template unmatch<UBC>();
|
|
1541
|
+
re[n_re] = vars[i];
|
|
1542
|
+
n_re++;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
Edge* mlb = vrn->template get_match<LBC>();
|
|
1547
|
+
if (mlb != NULL) {
|
|
1548
|
+
ValNode* vln = mlb->getVal();
|
|
1549
|
+
if (v != vln->val) {
|
|
1550
|
+
mlb->template unmatch<LBC>();
|
|
1551
|
+
int nom = vln->template incid_match<LBC>();
|
|
1552
|
+
// less values than required
|
|
1553
|
+
bool cond = nom < vln->kmin();
|
|
1554
|
+
if (cond) {
|
|
1555
|
+
re[n_re] = vln;
|
|
1556
|
+
n_re++;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
for (Edge* e = vrn->first(); e != NULL; e = e->next()){
|
|
1562
|
+
ValNode* vln = e->getVal();
|
|
1563
|
+
if (vln->val != v) {
|
|
1564
|
+
vrn->noe--;
|
|
1565
|
+
e->getVal()->noe--;
|
|
1566
|
+
e->del_edge();
|
|
1567
|
+
e->unlink();
|
|
1568
|
+
} else {
|
|
1569
|
+
rv = e->getVal();
|
|
1570
|
+
rv_idx = rv->kindex();
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
} else {
|
|
1574
|
+
|
|
1575
|
+
// delete the edge
|
|
1576
|
+
ViewValues<View> xiter(x[i]);
|
|
1577
|
+
Edge* mub = vrn->template get_match<UBC>();
|
|
1578
|
+
Edge* mlb = vrn->template get_match<LBC>();
|
|
1579
|
+
Edge** p = vrn->adj();
|
|
1580
|
+
Edge* e = *p;
|
|
1581
|
+
do {
|
|
1582
|
+
// search the edge that has to be deleted
|
|
1583
|
+
while (e != NULL && e->getVal()->val < xiter.val()) {
|
|
1584
|
+
// Skip edge
|
|
1585
|
+
e->getVal()->noe--;
|
|
1586
|
+
vrn->noe--;
|
|
1587
|
+
e->del_edge();
|
|
1588
|
+
e->unlink();
|
|
1589
|
+
e = e ->next();
|
|
1590
|
+
*p = e;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
assert(xiter.val() == e->getVal()->val);
|
|
1594
|
+
|
|
1595
|
+
// This edge must be kept
|
|
1596
|
+
e->template free<UBC>();
|
|
1597
|
+
e->template free<LBC>();
|
|
1598
|
+
++xiter;
|
|
1599
|
+
p = e->next_ref();
|
|
1600
|
+
e = e->next();
|
|
1601
|
+
} while (xiter());
|
|
1602
|
+
*p = NULL;
|
|
1603
|
+
while (e) {
|
|
1604
|
+
e->getVar()->noe--;
|
|
1605
|
+
e->getVal()->noe--;
|
|
1606
|
+
e->del_edge();
|
|
1607
|
+
e->unlink();
|
|
1608
|
+
e = e->next();
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (mub != NULL){
|
|
1612
|
+
if (mub->is_deleted()) {
|
|
1613
|
+
mub->template unmatch<UBC>();
|
|
1614
|
+
re[n_re] = vars[i];
|
|
1615
|
+
n_re++;
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
//lower bound matching can be zero
|
|
1620
|
+
if (mlb != NULL) {
|
|
1621
|
+
if (mlb->is_deleted()) {
|
|
1622
|
+
ValNode* vln = mlb->getVal();
|
|
1623
|
+
mlb->template unmatch<LBC>();
|
|
1624
|
+
int nom = vln->template incid_match<LBC>();
|
|
1625
|
+
bool cond = nom < vln->kmin();
|
|
1626
|
+
if (cond) {
|
|
1627
|
+
re[n_re] = vln;
|
|
1628
|
+
n_re++;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
vars[i]->set_info(i);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
for (int i = n_val; i--; ) {
|
|
1638
|
+
if (k[i].min() > vals[i]->noe && k[i].counter() == 0) {
|
|
1639
|
+
failed(true);
|
|
1640
|
+
return false;
|
|
1641
|
+
}
|
|
1642
|
+
vals[i]->set_info(n_var + i);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
if (n_re == 0) {
|
|
1646
|
+
// no repair needed
|
|
1647
|
+
return true;
|
|
1648
|
+
} else {
|
|
1649
|
+
// start repair
|
|
1650
|
+
|
|
1651
|
+
bool repaired = true;
|
|
1652
|
+
while (n_re ) {
|
|
1653
|
+
n_re--;
|
|
1654
|
+
assert(re[n_re] != NULL);
|
|
1655
|
+
if (!(re[n_re]->removed())) {
|
|
1656
|
+
if (!(re[n_re]->get_type())) {
|
|
1657
|
+
VarNode* vrn = reinterpret_cast<VarNode*> (re[n_re]);
|
|
1658
|
+
if (!vrn->template matched<UBC>()) {
|
|
1659
|
+
repaired &= augmenting_path<UBC>(vrn);
|
|
1660
|
+
}
|
|
1661
|
+
} else {
|
|
1662
|
+
assert(re[n_re]->get_type());
|
|
1663
|
+
ValNode* vln = reinterpret_cast<ValNode*> (re[n_re]);
|
|
1664
|
+
while(!vln->template matched<LBC>()) {
|
|
1665
|
+
repaired &= augmenting_path<LBC>(vln);
|
|
1666
|
+
if (!repaired) {
|
|
1667
|
+
break;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return repaired;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
template <class View, class Card, bool isView> template <BC direction>
|
|
1678
|
+
inline bool
|
|
1679
|
+
VarValGraph<View, Card, isView>::narrow(Space* home){
|
|
1680
|
+
|
|
1681
|
+
bool shared = false;
|
|
1682
|
+
for (int i = n_var; i--; ) {
|
|
1683
|
+
VarNode* vrn = vars[i];
|
|
1684
|
+
if (vrn->noe == 1) {
|
|
1685
|
+
Edge* e = vrn->first();
|
|
1686
|
+
shared |= x[i].modified();
|
|
1687
|
+
ValNode* v = e->getVal();
|
|
1688
|
+
e->template free<direction>();
|
|
1689
|
+
x[i].eq(home, v->val);
|
|
1690
|
+
v->inc();
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
for (int i = n_val; i--; ) {
|
|
1694
|
+
ValNode* v = vals[i];
|
|
1695
|
+
if (isView) {
|
|
1696
|
+
if (k[i].counter() == 0) {
|
|
1697
|
+
ModEvent klq = k[i].lq(home, v->noe);
|
|
1698
|
+
if (me_failed(klq)) {
|
|
1699
|
+
failed(true);
|
|
1700
|
+
return false;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
if (v->noe > 0) {
|
|
1706
|
+
|
|
1707
|
+
if (isView) {
|
|
1708
|
+
ModEvent klq = k[i].lq(home, v->noe);
|
|
1709
|
+
if (me_failed(klq)) {
|
|
1710
|
+
failed(true);
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
// If the maximum number of occurences of a value is reached
|
|
1716
|
+
// it cannot be consumed by another view
|
|
1717
|
+
|
|
1718
|
+
if (v->kcount() == v->kmax()) {
|
|
1719
|
+
int vidx = v->kindex();
|
|
1720
|
+
|
|
1721
|
+
k[i].counter(v->kcount());
|
|
1722
|
+
// std::cout << "eq on : " << v->val<<"\n";
|
|
1723
|
+
if (isView) {
|
|
1724
|
+
if (!k[i].assigned()) {
|
|
1725
|
+
ModEvent me = k[i].eq(home, k[i].counter());
|
|
1726
|
+
if (me_failed(me)) {
|
|
1727
|
+
failed(true);
|
|
1728
|
+
return false;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
bool delall = false;
|
|
1734
|
+
if (v->card_conflict() &&
|
|
1735
|
+
v->noe > v->kmax()) {
|
|
1736
|
+
delall = true;
|
|
1737
|
+
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
for (Edge* e = v->last(); e != NULL; e = e->vprev()) {
|
|
1741
|
+
VarNode* vrn = e->getVar();
|
|
1742
|
+
if (vrn->noe == 1) {
|
|
1743
|
+
vrn->noe--;
|
|
1744
|
+
v->noe--;
|
|
1745
|
+
int vi= vrn->get_info();
|
|
1746
|
+
|
|
1747
|
+
int n = x.size();
|
|
1748
|
+
x[vi] = x[--n];
|
|
1749
|
+
// x[vi].index(vi);
|
|
1750
|
+
x.size(n);
|
|
1751
|
+
|
|
1752
|
+
vars[vi] = vars[--n_var];
|
|
1753
|
+
vars[vi]->set_info(vi);
|
|
1754
|
+
node_size--;
|
|
1755
|
+
e->del_edge();
|
|
1756
|
+
e->unlink();
|
|
1757
|
+
|
|
1758
|
+
} else {
|
|
1759
|
+
if (delall) {
|
|
1760
|
+
x[vrn->get_info()].nq(home, v->val);
|
|
1761
|
+
vrn->noe--;
|
|
1762
|
+
v->noe--;
|
|
1763
|
+
e->del_edge();
|
|
1764
|
+
e->unlink();
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
v->template set_cap<UBC>(0);
|
|
1769
|
+
v->template set_cap<LBC>(0);
|
|
1770
|
+
v->set_maxlow(0);
|
|
1771
|
+
if (sum_min && sum_min >= k[vidx].min()) {
|
|
1772
|
+
sum_min -= k[vidx].min();
|
|
1773
|
+
}
|
|
1774
|
+
assert(sum_min >=0);
|
|
1775
|
+
|
|
1776
|
+
if (sum_max && sum_max >= k[vidx].max()) {
|
|
1777
|
+
sum_max -= k[vidx].max();
|
|
1778
|
+
}
|
|
1779
|
+
assert(sum_max >=0);
|
|
1780
|
+
|
|
1781
|
+
} else {
|
|
1782
|
+
int cur = v->kcount();
|
|
1783
|
+
if (cur > 0) {
|
|
1784
|
+
v->kcount(0);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
for (int i = n_var; i--; )
|
|
1790
|
+
vars[i]->set_info(i);
|
|
1791
|
+
|
|
1792
|
+
for (int i = n_val; i--; ) {
|
|
1793
|
+
if (vals[i]->noe == 0) {
|
|
1794
|
+
vals[i]->template set_cap<UBC>(0);
|
|
1795
|
+
vals[i]->template set_cap<LBC>(0);
|
|
1796
|
+
vals[i]->set_maxlow(0);
|
|
1797
|
+
}
|
|
1798
|
+
vals[i]->set_info(n_var + i);
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
for (int i = n_var; i--; )
|
|
1802
|
+
if (vars[i]->noe > 1)
|
|
1803
|
+
for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
|
|
1804
|
+
bool keepedge = false;
|
|
1805
|
+
keepedge = (e->template matched<direction>() ||
|
|
1806
|
+
e->template used<direction>());
|
|
1807
|
+
if (!keepedge) {
|
|
1808
|
+
ValNode* v = e->getVal();
|
|
1809
|
+
shared |= x[i].modified();
|
|
1810
|
+
x[i].nq(home, v->val);
|
|
1811
|
+
} else {
|
|
1812
|
+
e->template free<direction>();
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
return shared;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
template <class View, class Card, bool isView> template <BC direction>
|
|
1819
|
+
inline bool
|
|
1820
|
+
VarValGraph<View, Card, isView>::maximum_matching(void){
|
|
1821
|
+
|
|
1822
|
+
int required_size = 0;
|
|
1823
|
+
int card_match = 0;
|
|
1824
|
+
|
|
1825
|
+
if (direction == UBC) {
|
|
1826
|
+
required_size = n_var;
|
|
1827
|
+
} else {
|
|
1828
|
+
required_size = sum_min;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// find an intial matching in O(n*d)
|
|
1832
|
+
// greedy algorithm
|
|
1833
|
+
|
|
1834
|
+
for (int i = n_val; i--; ){
|
|
1835
|
+
ValNode* vln = vals[i];
|
|
1836
|
+
for (Edge* e = vln->first(); e != NULL ; e = e->vnext()) {
|
|
1837
|
+
VarNode* vrn = e->getVar();
|
|
1838
|
+
if (!vrn->template matched<direction>() &&
|
|
1839
|
+
!vln->template matched<direction>()) {
|
|
1840
|
+
e->template match<direction>();
|
|
1841
|
+
card_match++;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
if (card_match < required_size) {
|
|
1847
|
+
if (direction == LBC) {
|
|
1848
|
+
// collect free value nodes
|
|
1849
|
+
GECODE_AUTOARRAY(ValNode*, free, n_val);
|
|
1850
|
+
int f = 0;
|
|
1851
|
+
// find failed nodes
|
|
1852
|
+
for (int i = n_val; i--; ) {
|
|
1853
|
+
ValNode* vln = vals[i];
|
|
1854
|
+
if (!vln->template matched<direction>()) {
|
|
1855
|
+
free[f++] = vln;
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
for (int i = 0; i < f; i++) {
|
|
1860
|
+
while(!free[i]->template matched<direction>()) {
|
|
1861
|
+
if (augmenting_path<direction>(free[i])) {
|
|
1862
|
+
card_match++;
|
|
1863
|
+
} else {
|
|
1864
|
+
break;
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
} else {
|
|
1869
|
+
GECODE_AUTOARRAY(VarNode*, free, n_var);
|
|
1870
|
+
int f = 0;
|
|
1871
|
+
// find failed nodes
|
|
1872
|
+
for (int i = n_var; i--; ) {
|
|
1873
|
+
VarNode* vrn = vars[i];
|
|
1874
|
+
if (!vrn->template matched<direction>()) {
|
|
1875
|
+
free[f++] = vrn;
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
for (int i = 0; i < f; i++) {
|
|
1880
|
+
if (!free[i]->template matched<direction>()) {
|
|
1881
|
+
if (augmenting_path<direction>(free[i])) {
|
|
1882
|
+
card_match++;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
return (card_match >= required_size);
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
template <class View, class Card, bool isView> template<BC direction>
|
|
1892
|
+
inline bool
|
|
1893
|
+
VarValGraph<View, Card, isView>::augmenting_path(VVGNode* v){
|
|
1894
|
+
Support::StaticStack<VVGNode*> ns(node_size);
|
|
1895
|
+
GECODE_AUTOARRAY(bool, visited, node_size);
|
|
1896
|
+
GECODE_AUTOARRAY(Edge*, start, node_size);
|
|
1897
|
+
|
|
1898
|
+
// augmenting path starting in a free var node
|
|
1899
|
+
assert(!v->is_matched(direction));
|
|
1900
|
+
|
|
1901
|
+
// keep track of the nodes that have already been visited
|
|
1902
|
+
VVGNode* sn = v;
|
|
1903
|
+
|
|
1904
|
+
// mark the start partition
|
|
1905
|
+
bool sp = sn->get_type();
|
|
1906
|
+
|
|
1907
|
+
// nodes in sp only follow free edges
|
|
1908
|
+
// nodes in V - sp only follow matched edges
|
|
1909
|
+
|
|
1910
|
+
for (int i = node_size; i--; ){
|
|
1911
|
+
visited[i] = false;
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
for (int i = node_size; i--; ){
|
|
1915
|
+
if (i >= n_var) {
|
|
1916
|
+
vals[i - n_var]->inedge(NULL);
|
|
1917
|
+
start[i] = vals[i - n_var]->first();
|
|
1918
|
+
} else {
|
|
1919
|
+
vars[i]->inedge(NULL);
|
|
1920
|
+
start[i] = vars[i]->first();
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
v->inedge(NULL);
|
|
1925
|
+
ns.push(v);
|
|
1926
|
+
visited[v->get_info()] = true;
|
|
1927
|
+
while (!ns.empty()) {
|
|
1928
|
+
VVGNode* v = ns.top();
|
|
1929
|
+
Edge* e = NULL;
|
|
1930
|
+
if (v->get_type() == sp) {
|
|
1931
|
+
// follow next free edge
|
|
1932
|
+
e = start[v->get_info()];
|
|
1933
|
+
while (e != NULL && e->template matched<direction>()) {
|
|
1934
|
+
e = e->next(v->get_type());
|
|
1935
|
+
}
|
|
1936
|
+
} else {
|
|
1937
|
+
e = start[v->get_info()];
|
|
1938
|
+
while (e != NULL && !e->template matched<direction>()) {
|
|
1939
|
+
e = e->next(v->get_type());
|
|
1940
|
+
}
|
|
1941
|
+
start[v->get_info()] = e;
|
|
1942
|
+
}
|
|
1943
|
+
if (e != NULL) {
|
|
1944
|
+
start[v->get_info()] = e->next(v->get_type());
|
|
1945
|
+
VVGNode* w = e->getMate(v->get_type());
|
|
1946
|
+
if (!visited[w->get_info()]) {
|
|
1947
|
+
// unexplored path
|
|
1948
|
+
if (!w->is_matched(direction) && w->get_type() != sp) {
|
|
1949
|
+
if (v->inedge() != NULL) {
|
|
1950
|
+
// augmenting path of length l > 1
|
|
1951
|
+
e->template match<direction>();
|
|
1952
|
+
break;
|
|
1953
|
+
} else {
|
|
1954
|
+
// augmenting path of length l = 1
|
|
1955
|
+
e->template match<direction>();
|
|
1956
|
+
ns.pop();
|
|
1957
|
+
return true;
|
|
1958
|
+
}
|
|
1959
|
+
} else {
|
|
1960
|
+
w->inedge(e);
|
|
1961
|
+
visited[w->get_info()] = true;
|
|
1962
|
+
// find matching edge m incident with w
|
|
1963
|
+
ns.push(w);
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
} else {
|
|
1967
|
+
// tried all outgoing edges without finding an augmenting path
|
|
1968
|
+
ns.pop();
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
bool pathfound = false;
|
|
1973
|
+
if (!ns.empty()) {
|
|
1974
|
+
pathfound = true;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
while (!ns.empty()) {
|
|
1978
|
+
VVGNode* t = ns.top();
|
|
1979
|
+
if (t != sn) {
|
|
1980
|
+
Edge* in = t->inedge();
|
|
1981
|
+
if (t->get_type() != sp) {
|
|
1982
|
+
assert(in != NULL);
|
|
1983
|
+
in->template match<direction>();
|
|
1984
|
+
} else {
|
|
1985
|
+
// avoid defects
|
|
1986
|
+
if (!sp) {
|
|
1987
|
+
in->template unmatch<direction>(!sp);
|
|
1988
|
+
} else {
|
|
1989
|
+
in->template unmatch<direction>();
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
ns.pop();
|
|
1993
|
+
} else {
|
|
1994
|
+
ns.pop();
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return pathfound;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
template <class View, class Card, bool isView> template<BC direction>
|
|
2001
|
+
inline void
|
|
2002
|
+
VarValGraph<View, Card, isView>::free_alternating_paths(void){
|
|
2003
|
+
Support::StaticStack<VVGNode*> ns(node_size);
|
|
2004
|
+
GECODE_AUTOARRAY(bool, visited, node_size);
|
|
2005
|
+
// keep track of the nodes that have already been visited
|
|
2006
|
+
for (int i = node_size; i--; ){
|
|
2007
|
+
visited[i] = false;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
if (direction == LBC) {
|
|
2011
|
+
// after a maximum matching on the value nodes there still can be
|
|
2012
|
+
// free value nodes, hence we have to consider ALL nodes whether
|
|
2013
|
+
// they are the starting point of an even alternating path in G
|
|
2014
|
+
for (int i = n_var; i--; ){
|
|
2015
|
+
if(!vars[i]->is_matched(LBC)){
|
|
2016
|
+
// unmatched var-node
|
|
2017
|
+
ns.push(vars[i]);
|
|
2018
|
+
visited[vars[i]->get_info()] = true;
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
for (int i = n_val; i--; ){
|
|
2022
|
+
if(!vals[i]->is_matched(LBC)){
|
|
2023
|
+
// unmatched val-node
|
|
2024
|
+
ns.push(vals[i]);
|
|
2025
|
+
visited[vals[i]->get_info()] = true;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
} else {
|
|
2030
|
+
// clearly, after a maximum matching on the x variables
|
|
2031
|
+
// corresponding to a set cover on x there are NO free var nodes
|
|
2032
|
+
// std::cout << "alt_path for ubm: \n";
|
|
2033
|
+
// after max_match_ub there can only be free val-nodes
|
|
2034
|
+
for (int i = n_val; i--; ){
|
|
2035
|
+
if(!vals[i]->is_matched(UBC)){
|
|
2036
|
+
// still capacities left
|
|
2037
|
+
ns.push(vals[i]);
|
|
2038
|
+
visited[vals[i]->get_info()] = true;
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
while(!ns.empty()){
|
|
2044
|
+
VVGNode* node = ns.top();
|
|
2045
|
+
ns.pop();
|
|
2046
|
+
if (node->get_type()) {
|
|
2047
|
+
// ValNode
|
|
2048
|
+
ValNode* vln = reinterpret_cast<ValNode*> (node);
|
|
2049
|
+
for (Edge* cur = vln->first(); cur != NULL; cur = cur->vnext()){
|
|
2050
|
+
VarNode* mate = cur->getVar();
|
|
2051
|
+
bool follow = false;
|
|
2052
|
+
switch (direction) {
|
|
2053
|
+
// edges in M_l are directed from values to variables
|
|
2054
|
+
case LBC: {
|
|
2055
|
+
follow = cur->template matched<direction>();
|
|
2056
|
+
break;
|
|
2057
|
+
}
|
|
2058
|
+
case UBC: {
|
|
2059
|
+
follow = !cur->template matched<direction>();
|
|
2060
|
+
break;
|
|
2061
|
+
default: GECODE_NEVER;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
if (follow) {
|
|
2065
|
+
// mark the edge
|
|
2066
|
+
cur->template use<direction>();
|
|
2067
|
+
if (!visited[mate->get_info()]) {
|
|
2068
|
+
ns.push(mate);
|
|
2069
|
+
visited[mate->get_info()] = true;
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
} else {
|
|
2074
|
+
// VarNode
|
|
2075
|
+
VarNode* vrn = reinterpret_cast<VarNode*> (node);
|
|
2076
|
+
switch (direction) {
|
|
2077
|
+
// after LBC-matching we can follow every unmatched edge
|
|
2078
|
+
case LBC: {
|
|
2079
|
+
for (Edge* cur = vrn->first(); cur != NULL; cur = cur->next()){
|
|
2080
|
+
ValNode* mate = cur->getVal();
|
|
2081
|
+
if (!cur->template matched<LBC>()) {
|
|
2082
|
+
cur->template use<LBC>();
|
|
2083
|
+
if (!visited[mate->get_info()]) {
|
|
2084
|
+
ns.push(mate);
|
|
2085
|
+
visited[mate->get_info()] = true;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
break;
|
|
2090
|
+
}
|
|
2091
|
+
// after ub-matching we can only follow a matched edge
|
|
2092
|
+
case UBC: {
|
|
2093
|
+
Edge* cur = vrn->template get_match<UBC>();
|
|
2094
|
+
if (cur != NULL) {
|
|
2095
|
+
cur->template use<UBC>();
|
|
2096
|
+
ValNode* mate = cur->getVal();
|
|
2097
|
+
if (!visited[mate->get_info()]) {
|
|
2098
|
+
ns.push(mate);
|
|
2099
|
+
visited[mate->get_info()] = true;
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
break;
|
|
2103
|
+
}
|
|
2104
|
+
default: GECODE_NEVER;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
template <class View, class Card, bool isView> template <BC direction>
|
|
2111
|
+
inline void
|
|
2112
|
+
VarValGraph<View, Card, isView>::dfs(VVGNode* v,
|
|
2113
|
+
bool inscc[],
|
|
2114
|
+
bool in_unfinished[],
|
|
2115
|
+
int dfsnum[],
|
|
2116
|
+
Support::StaticStack<VVGNode*>& roots,
|
|
2117
|
+
Support::StaticStack<VVGNode*>& unfinished,
|
|
2118
|
+
int& count){
|
|
2119
|
+
count++;
|
|
2120
|
+
int v_index = v->get_info();
|
|
2121
|
+
dfsnum[v_index] = count;
|
|
2122
|
+
inscc[v_index] = true;
|
|
2123
|
+
in_unfinished[v_index] = true;
|
|
2124
|
+
|
|
2125
|
+
unfinished.push(v);
|
|
2126
|
+
roots.push(v);
|
|
2127
|
+
for (Edge* e = v->first(); e != NULL; e = e->next(v->get_type())) {
|
|
2128
|
+
bool condition = false;
|
|
2129
|
+
// LBC-matching
|
|
2130
|
+
if (direction == LBC) {
|
|
2131
|
+
// ValNode
|
|
2132
|
+
if (v->get_type()) {
|
|
2133
|
+
condition = e->template matched<LBC>();
|
|
2134
|
+
} else {
|
|
2135
|
+
condition = !e->template matched<LBC>();
|
|
2136
|
+
}
|
|
2137
|
+
// UBC - matching
|
|
2138
|
+
} else {
|
|
2139
|
+
if (v->get_type()) {
|
|
2140
|
+
// in an upper bound matching a valnode only can follow unmatched edges
|
|
2141
|
+
condition = !e->template matched<UBC>();
|
|
2142
|
+
} else {
|
|
2143
|
+
condition = e->template matched<UBC>();
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
if (condition) {
|
|
2147
|
+
VVGNode* w = e->getMate(v->get_type());
|
|
2148
|
+
int w_index = w->get_info();
|
|
2149
|
+
|
|
2150
|
+
assert(w_index < node_size);
|
|
2151
|
+
if (!inscc[w_index]) {
|
|
2152
|
+
// w is an uncompleted scc
|
|
2153
|
+
w->inedge(e);
|
|
2154
|
+
dfs<direction>(w, inscc, in_unfinished, dfsnum,
|
|
2155
|
+
roots, unfinished, count);
|
|
2156
|
+
} else {
|
|
2157
|
+
if (in_unfinished[w_index]) {
|
|
2158
|
+
// even alternating cycle found mark the edge closing the cycle,
|
|
2159
|
+
// completing the scc
|
|
2160
|
+
e->template use<direction>();
|
|
2161
|
+
// if w belongs to an scc we detected earlier
|
|
2162
|
+
// merge components
|
|
2163
|
+
assert(roots.top()->get_info() < node_size);
|
|
2164
|
+
while (dfsnum[roots.top()->get_info()] > dfsnum[w_index]) {
|
|
2165
|
+
roots.pop();
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
if (v == roots.top()) {
|
|
2173
|
+
while (v != unfinished.top()) {
|
|
2174
|
+
// w belongs to the scc with root v
|
|
2175
|
+
VVGNode* w = unfinished.top();
|
|
2176
|
+
Edge* ie = w->inedge();
|
|
2177
|
+
ie->template use<direction>();
|
|
2178
|
+
in_unfinished[w->get_info()] = false;
|
|
2179
|
+
unfinished.pop();
|
|
2180
|
+
}
|
|
2181
|
+
assert(v == unfinished.top());
|
|
2182
|
+
in_unfinished[v_index] = false;
|
|
2183
|
+
roots.pop();
|
|
2184
|
+
unfinished.pop();
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
template <class View, class Card, bool isView> template <BC direction>
|
|
2189
|
+
inline void
|
|
2190
|
+
VarValGraph<View, Card, isView>::strongly_connected_components(void){
|
|
2191
|
+
GECODE_AUTOARRAY(bool, inscc, node_size);
|
|
2192
|
+
GECODE_AUTOARRAY(bool, in_unfinished, node_size);
|
|
2193
|
+
GECODE_AUTOARRAY(int, dfsnum, node_size);
|
|
2194
|
+
|
|
2195
|
+
for (int i = node_size; i--; ) {
|
|
2196
|
+
inscc[i] = false;
|
|
2197
|
+
in_unfinished[i] = false;
|
|
2198
|
+
dfsnum[i] = 0;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
int count = 0;
|
|
2202
|
+
Support::StaticStack<VVGNode*> roots(node_size);
|
|
2203
|
+
Support::StaticStack<VVGNode*> unfinished(node_size);
|
|
2204
|
+
|
|
2205
|
+
for (int i = n_var; i--; ) {
|
|
2206
|
+
dfs<direction>(vars[i], inscc, in_unfinished, dfsnum,
|
|
2207
|
+
roots, unfinished, count);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
|
|
2212
|
+
template <class View, class Card, bool isView>
|
|
2213
|
+
void
|
|
2214
|
+
VarValGraph<View, Card, isView>::print_match(void) {
|
|
2215
|
+
print_matching<UBC>();
|
|
2216
|
+
print_matching<LBC>();
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
|
|
2220
|
+
template <class View, class Card, bool isView>
|
|
2221
|
+
void
|
|
2222
|
+
VarValGraph<View, Card, isView>::print_edges(void) {
|
|
2223
|
+
for (int i = 0; i < n_var; i++) {
|
|
2224
|
+
std::cout << vars[i]->var<<": ";
|
|
2225
|
+
for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
|
|
2226
|
+
bool ml = e->template matched<LBC>();
|
|
2227
|
+
bool ul = e->template used<LBC>();
|
|
2228
|
+
bool mu = e->template matched<UBC>();
|
|
2229
|
+
bool uu = e->template used<UBC>();
|
|
2230
|
+
bool condition = (ml || ul || mu || uu);
|
|
2231
|
+
if (ml) {
|
|
2232
|
+
std::cout << e->getVal()->val<<" mL, ";
|
|
2233
|
+
}
|
|
2234
|
+
if (ul) {
|
|
2235
|
+
std::cout << e->getVal()->val<<" uL, ";
|
|
2236
|
+
}
|
|
2237
|
+
if (mu) {
|
|
2238
|
+
std::cout << e->getVal()->val<<" mU, ";
|
|
2239
|
+
}
|
|
2240
|
+
if (uu) {
|
|
2241
|
+
std::cout << e->getVal()->val<<" uU, ";
|
|
2242
|
+
}
|
|
2243
|
+
if (!condition) {
|
|
2244
|
+
std::cout << e->getVal()->val<<" x ";
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
std::cout <<"\n";
|
|
2248
|
+
}
|
|
2249
|
+
std::cout <<"\n";
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
// for debugging purposes
|
|
2253
|
+
template <class View, class Card, bool isView> template <BC direction>
|
|
2254
|
+
void
|
|
2255
|
+
VarValGraph<View, Card, isView>::print_matching(void) {
|
|
2256
|
+
if (direction == UBC) {
|
|
2257
|
+
std::cout << "UBM - check:\n";
|
|
2258
|
+
} else {
|
|
2259
|
+
std::cout << "LBM - check:\n";
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
for (int i = 0; i < n_var; i++ ){
|
|
2263
|
+
std::cout << vars[i]->var <<" ";
|
|
2264
|
+
if (vars[i]->template matched<direction>()) {
|
|
2265
|
+
if (vars[i]->template get_match<direction>() == NULL) {
|
|
2266
|
+
std::cout << "N ";
|
|
2267
|
+
} else {
|
|
2268
|
+
std::cout << vars[i]->template get_match<direction>() << " ";
|
|
2269
|
+
std::cout << vars[i]->template get_match<direction>()->getVal()->val << " ";
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
std::cout << " <==" << vars[i] <<"\n";
|
|
2273
|
+
}
|
|
2274
|
+
std::cout <<"\n";
|
|
2275
|
+
|
|
2276
|
+
for (int i = 0; i < n_val; i++ ){
|
|
2277
|
+
if (vals[i]->template matched<direction>()) {
|
|
2278
|
+
std::cout << "X ";
|
|
2279
|
+
} else {
|
|
2280
|
+
std::cout << "- ";
|
|
2281
|
+
}
|
|
2282
|
+
std::cout << vals[i]->template cap<direction>() << " ";
|
|
2283
|
+
std::cout << vals[i]->get_maxlow() << " ";
|
|
2284
|
+
std::cout << vals[i]->val << " <==";
|
|
2285
|
+
for (Edge* e = vals[i]->first(); e != NULL; e = e->vnext()) {
|
|
2286
|
+
if (e->template matched<direction>()) {
|
|
2287
|
+
std::cout << e->getVar()->var << ",";
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
std::cout <<"\n";
|
|
2291
|
+
}
|
|
2292
|
+
std::cout <<"\n";
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
template <class View, class Card, bool isView>
|
|
2296
|
+
void
|
|
2297
|
+
VarValGraph<View, Card, isView>::print_graph(void) {
|
|
2298
|
+
std::cout << "Graph-size = "<<node_size<<" ";
|
|
2299
|
+
std::cout << "sum_min ="<<sum_min << " & "
|
|
2300
|
+
<< "sum_max ="<<sum_max << "\n";
|
|
2301
|
+
std::cout << "X-Partition: \n";
|
|
2302
|
+
for (int i = 0; i < n_var; i++) {
|
|
2303
|
+
VarNode* vrn = vars[i];
|
|
2304
|
+
std::cout << "X("<<vars[i]->get_info()<<") ";
|
|
2305
|
+
std::cout << "["<<vrn->xindex <<"]";
|
|
2306
|
+
std::cout << "|"<<vrn->noe <<"|";
|
|
2307
|
+
std::cout << "{";
|
|
2308
|
+
for (Edge* e = vrn->first(); e != NULL; e = e->next()){
|
|
2309
|
+
assert(e != NULL);
|
|
2310
|
+
assert(e->getVal() != NULL);
|
|
2311
|
+
std::cout << e->getVal()->val<<",";
|
|
2312
|
+
}
|
|
2313
|
+
std::cout <<"}\t";
|
|
2314
|
+
std::cout << "F"<<vrn->first() << ", L" << vrn->last() << " ";
|
|
2315
|
+
std::cout <<"\n";
|
|
2316
|
+
}
|
|
2317
|
+
std::cout <<"\n";
|
|
2318
|
+
|
|
2319
|
+
std::cout << "V-Partition: \n";
|
|
2320
|
+
for (int i = 0; i < n_val; i++) {
|
|
2321
|
+
ValNode* vln = vals[i];
|
|
2322
|
+
std::cout << vln->val <<" ";
|
|
2323
|
+
std::cout << "V(" << i << ") ";
|
|
2324
|
+
std::cout << "k(" << vln->kmin() << "," <<vln->kmax() << ") ";
|
|
2325
|
+
std::cout << "c(" << vln->template cap<LBC>() << ","
|
|
2326
|
+
<< vln->template cap<UBC>() << ") ";
|
|
2327
|
+
std::cout << "ublow: "<<vln->get_maxlow() <<" ";
|
|
2328
|
+
std::cout << "|"<<vln->noe <<"|";
|
|
2329
|
+
std::cout << "{";
|
|
2330
|
+
if (vln->noe == 0 || vln->first() == NULL) {
|
|
2331
|
+
std::cout << "EMPTY";
|
|
2332
|
+
} else {
|
|
2333
|
+
for(Edge* c = vln->first(); c != NULL; c = c->vnext()){
|
|
2334
|
+
assert(c != NULL);
|
|
2335
|
+
assert(c->getVar() != NULL);
|
|
2336
|
+
std::cout << c->getVar()->var << ",";
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
std::cout <<"}\t";
|
|
2340
|
+
std::cout <<"\t";
|
|
2341
|
+
if (vln->noe == 0 || vln->first() == NULL) {
|
|
2342
|
+
std::cout <<"no-ptr";
|
|
2343
|
+
} else {
|
|
2344
|
+
std::cout << "F"<<vln->first() << ", L" <<vln->last() << " ";
|
|
2345
|
+
}
|
|
2346
|
+
std::cout <<"\n";
|
|
2347
|
+
}
|
|
2348
|
+
std::cout <<"\n";
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
template <class View, class Card, bool isView>
|
|
2353
|
+
forceinline
|
|
2354
|
+
VarValGraph<View, Card, isView>::~VarValGraph(void){
|
|
2355
|
+
Memory::free(mem);
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
template <class View, class Card, bool isView>
|
|
2359
|
+
forceinline void*
|
|
2360
|
+
VarValGraph<View, Card, isView>::operator new(size_t t){
|
|
2361
|
+
return Memory::malloc(t);
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
template <class View, class Card, bool isView>
|
|
2365
|
+
forceinline void
|
|
2366
|
+
VarValGraph<View, Card, isView>::operator delete(void* p){
|
|
2367
|
+
Memory::free(p);
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
}}}
|
|
2372
|
+
|
|
2373
|
+
// STATISTICS: int-prop
|
|
2374
|
+
|
|
2375
|
+
|