<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Covering complete graphs using the dancing links algorithm⋆</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Petr Kovář</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Yifan Zhang</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>VŠB - Technical University of Ostrava, Department of Applied Mathematics</institution>
          ,
          <addr-line>17. listopadu 2172/15, 708 00 Ostrava</addr-line>
          ,
          <country country="CZ">Czech Republic</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>The dancing links algorithm by Knuth can be used to find decompositions of a complete graph eficiently. In this paper, we generalize it to find covers of a complete graph by cliques as well. This problem arose as one step of a parallel implementation of the bounded element method when solving partial diferential equations. The modification brought up an issue of counting certain covers of multiple edges multiple times. Having solved the problem by imposing a natural order, we show the computational results achieved by the modified algorithm.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;graph covering</kwd>
        <kwd>combinatorial design</kwd>
        <kwd>dancing links</kwd>
        <kwd>complete graph</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Motivation</title>
      <p>however the core memory is rather limited. While
computation is cheap, memory and data transfer are
expensive, therefore it is favorable to keep  small.</p>
      <p>
        Boundary element methods (BEM) have become a useful
tool for solving partial diferential equations. In
comparison to widely used discretization techniques, as smaller 1.1. Covering of complete graphs
systems with fewer degrees of freedom they ofer certain
advantages. However, when implementing BEM, one of In this paper, we address the hardest part of the BEM
the major dificulties lies in dense matrices. To parallelize implementation - the problem of decomposing  into
the computation, a method of decomposing a dense ma- ’s where  is a small integer while  grows along with
trix into (dense) submatrices using cyclic decomposition the number of available cores. In general, such
decomof complete graphs  into  complete subgraphs  position cannot be cyclic. For fixed  = 3 and  = 4
was introduced in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]. This translates to a decomposi- constructions based on Steiner triple or quadruple
systion of an  by  block matrix to  submatrices with tems can be used for certain limited values of . For
 by  blocks each, in which only one diagonal block remaining values of  we use covers in addition to
deis occupied. The additional requirement for the decom- composition. We want to guarantee that only a small
position to be cyclic simplified the implementation, but percentage of computation will be doubled. This can be
introduced certain restrictions. The parameters  and  modeled by graph coverings with a small number of
douare not independent: a necessary condition for a cyclic bly or triply covered edges called excess. Constructions
decomposition to exist is  = 2 −  + 1. Moreover, of covers are known for fixed values  = 3,  = 4 as
the existence of a cyclic decomposition follows from the well as for most values  = 5 and  = 6.
existence of the so called  -labeling, for which existence Covering of  by  for a single fixed ,  = 3, 4
is guaranteed only if  − 1 is a prime power. with a given excess is based on results by Hanani [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ]
      </p>
      <p>
        When  becomes large, the cyclic decomposition is and Mills [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ], [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] and other authors and can be found in
suitable only for parallel systems with shared memory. [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ]. Covers using simultaneously 3 and 4 allow an
At the same time, parameter  is preferably small. The ar- even smaller excess. In Section 4 we provide solutions for
chitecture of contemporary supercomputers relies rather small  found by brute force and compare the running
on fast local memory for each processor or each core, times.
      </p>
      <p>
        To find such covers for small  by brute force, we
suc23rd Conference ITAT: Workshop on the Computational Aspects of cessfully use a modification of the dancing link algorithm
Large-Scale Problems in Discrete Mathematics, September 22–26, 2023, (DLX) by Donald Knuth [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. Even though the solution
Vysoké Tatry, Slovakia of the decomposition problem (exact cover problem in
*⋆ C20o0r0reMspSoCn:d0in5Cg7a0u,t0h5oCr.78 Knuth’s terminology) is NP hard in general, the eficient
S These authors contributed equally. implementation of the DLX algorithm allows to find
solu$ petr.kovar@vsb.cz (P. Kovář) tions for not very large  or in some cases even disprove
 http://homel.vsb.cz/~kov16 (P. Kovář) the existence for certain small values of . In this
pa0000-0002-7847-5060 (P. Kovář) per we present two ways of modifying the algorithm for
© 2023 Copyright for this paper by its authors. Use permitted under Creative Commons License solving a covering problem instead of a decomposition
CPWrEooUrckReshdoinpgs IhStpN:/c1e6u1r3-w-0s.o7r3g ACttEribUutRion W4.0oInrtekrnsahtioonpal (PCCroBYce4.0e).dings (CEUR-WS.org)
The dancing links algorithm, proposed by Donald
E. Knuth in [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ], has been an eficient 1 approach to solving
the exact cover problem, in which a matrix of 0s and 1s is
given and we would like to determine whether it admits
a set of rows containing exactly one 1 in each column.
      </p>
      <p>For example, the following matrix has such a set formed
by the rows 2 and 3.
problem. One modification is based on extending the reaches a point where all columns have been “removed”,
data structure, while the other is a modification of the i.e. [ℎ] = ℎ. Then the algorithm goes back to the
algorithm itself. In the forthcoming sections, we describe last level of depth and attempts to include the next row
the two approaches. that covers the same column, as soon as the “removed”
columns are “restored” in the matrix by the
correspond1.2. Decomposition of complete graphs ing modifications of links in the function uncover_column.</p>
      <p>The output of the algorithm would contain all feasible
using the dancing links algorithm
solutions to the exact cover problem, while it also makes
sense to stop after finding the first solution when we are
only interested in the existence of a solution.
⎛1 1 0 1 0 0 1⎞
⎜0 1 1 0 1 1 0⎟
⎜⎜1 0 0 1 0 0 1⎟⎟
⎜⎜0 1 1 0 1 1 1⎟⎟
⎜⎝1 0 1 1 1 1 0⎟⎠</p>
      <p>1 1 1 0 0 1 0</p>
      <p>A special data structure is suggested by Knuth to
implement the algorithm, that each 1 in the matrix be
represented by a data object  with five fields including [],
[],  [], [], pointing circularly left, right, up, down
to the neighbour of , as well as [] that links  to the
column object it belongs to. Situated in the list header,
each column object  has two additional fields besides
those attributed to a normal data object, its size []
which counts the number of 1s in the column as well as
its name  [] that serves as an identifier for printing.</p>
      <p>An additional root object ℎ is added linking all column
objects circularly, i.e. [ℎ] points to the leftmost column,
while [ℎ] to the rightmost one. The object ℎ does not
admit the other fields, i.e.  [ℎ], [ℎ], [ℎ], [ℎ] and
 [ℎ] are not used.</p>
      <p>The algorithm works as follows. A depth-first search
tree is set up by invoking search(0). As long as there is
at least one column in the list headers, the algorithm
chooses the leftmost column, and tries to form a
solution by the first row that is able to cover this column.</p>
      <p>The choice of column we made here left the field 
unused throughout the algorithm. Before continuing, the
algorithm requires the chosen column to be “removed”
by modifying the links of its neighbours in the
function cover_column. Other columns covered by the same
row need to be “removed” in the same way, so that the
size of the data matrix will decrease. Then search(1) is
invoked recursively on the shrunk matrix to include
another row in the partial solution. If this partial
solution turns out to be a valid solution, it is printed by the
function print_solution when the corresponding search
1It is a frugal approach to the problem, albeit not polynomial.
def choose_column():</p>
      <p>return R[h]
def cover_column(c):</p>
      <p>L[R[c]] = L[c]
R[L[c]] = R[c]
i = D[c]
while i != c:
j = R[i]
while j != i:</p>
      <p>U[D[j]] = U[j]
D[U[j]] = D[j]
j = R[j]
i = D[i]
return
def uncover_column(c):
i = U[c]
while i != c:
j = L[i]
while j != i:</p>
      <p>U[D[j]] = j
D[U[j]] = j
j = L[j]
i = U[i]
L[R[c]] = c
R[L[c]] = c
return
def print_solution():
s = []
for o in partial_solution:
row = [N[C[o]]]
p = R[o]
while p != o:
row.append(N[C[p]])
p = R[p]
s.append[row]
print(s)
return
def search(depth):
if R[h] == h:
print_solution()
return
else:
c = choose_column()
cover_column(c)
r = D[c]
while r != c:
partial_solution.append(r)
j = R[r]
while j != r:
cover_column(C[j])
j = R[j]
search(depth + 1)
r = partial_solution.pop()
c = C[r]
j = L[r]
while j != r:
uncover_column(C[j])
j = L[j]
r = D[r]
uncover_column(c)
return</p>
      <p>When the structure of 21 columns and 35 rows are
inputted, the dancing links algorithm finds 30 solutions
for the decomposition of 7 into 3, as expected.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Covering complete graphs using the dancing links algorithm</title>
      <p>The major challenge posed to the original dancing links
algorithm when considering the covering rather than
the decomposition of a complete graph is that a solution
may contain more than one row covering the same
column. This section suggests possible modifications to the
original algorithm in order to overcome this issue.</p>
      <sec id="sec-2-1">
        <title>2.1. Extra columns</title>
        <p>The decomposition of a complete graph  by copies
of a smaller complete graph  ( ≤ ) can be naturally
modelled as an exact cover problem, in which the edges
of  are treated as columns and the subgraphs of 
isomorphic to  serve as the rows: one row for every
choice of  vertices from the  with ones denoting the
edges contained in the particular choice.</p>
        <p>For example, consider the decomposition of 7 into such as 1,2 + 1,3 + 2,3 and 4,5 + 5,6 + 4,6, must
3, where 21 columns are given, each correspond- be doubled in the data structure, resulting in 32 rows
ing to an edge of 7, and there are (︀ 37)︀ = 35 rows instead of 20.
that represent the 35 3-subgraphs of 7. Denote Introducing extra columns does not only bring about
the vertices of 7 by 1, 2, · · · , 7, and let , := bloated data structure, but also redundant solutions. If
(0, · · · , 0, edg1e-, 0, · · · , 0), then, for instance, the row some solution contains a row that has been doubled when
corresponding to the triangle ∆123 has the form 1,2 + building the data structure, it would appear again as
1,3 + 2,3. Apparently, the rows 1,2 + 1,4 + 2,4, another solution including the clone of the same row.
2,3 + 2,5 + 3,5, 3,4 + 3,6 + 4,6, 4,5 + 4,7 + 5,7, For instance, solving the covering problem of 6 by 3
1,5 + 1,6 + 5,6, 2,6 + 2,7 + 6,7 and 1,7 + 1,3 + 3,7 with 3 extra columns as mentioned above using dancing
constitute a solution to the exact cover problem, which links yields 16 solutions, of which only 2 are genuinely
corresponds to the decomposition of the 7 into the diferent from each other.
following 7 copies of 3:
In graph coverings, the excess multigraph is often not
determined uniquely. When the excess is fully known,
it seems natural to add the edges in the excess as extra
columns, so that the covering problem is transformed to
a decomposition one.</p>
        <p>
          For example, consider the covering of 6 by 6 copies
of 3, of which the excess is known ([
          <xref ref-type="bibr" rid="ref5">5</xref>
          ], p. 371, Table
VI.11.41) to be a perfect matching of 6. Without loss of
generality, assume the doubled edges are 1-2, 3-4 and 5-6,
then the dancing links structure would contain 15 + 3 =
18 columns corresponding to the edges. However, notice
that the rows containing one of the three extra edges,
        </p>
      </sec>
      <sec id="sec-2-2">
        <title>2.2. Revisiting columns</title>
        <p>{∆124 , ∆235 , ∆346 , ∆457 , ∆156 , ∆267 , ∆137 }.</p>
        <p>To count the number of feasible coverings from a the- Besides introducing extra columns, the algorithm can be
oretical perspective, notice that fixing the triangle ∆123 steered to revisit a column as long as it is not “removed"
in the solution is equivalent to choosing 3 as the last from the structure during the last visit, which motivates
element in the triangle covering the edge 1-2 among 5 us to assign a multiplicity  [] to each column  in the
options: 3, 4, 5, 6, 7; fixing also ∆145 is equivalent to original data structure that equals 1 by default. When
choosing 5 as the last element in the triangle covering 1- an edge is in the excess of a covering problem, we raise
4 among 3 options: 5, 6, 7; then fixing ∆246 is equivalent the multiplicity of the corresponding column to match
to choosing 6 as the last element in the triangle covering the amount it needs to be covered. The  vector can be
2-4 among 2 options: 6, 7; and it is now apparent that the implemented as an additional field of the header elements.
remaining part of the solution is unique: ∆167 , ∆356 , For example, when covered by triangles, if we order the
∆257 and ∆347 .</p>
        <p>We modify the functions cover_column and
uncover_column accordingly so that the multiplicity is
always increased or decreased by 1 while the “removal"
or “restoration" of the column only happens when its
multiplicity is 1 or 0, respectively.</p>
        <p>This approach avoids the unnecessary expansion of
data structure, while continues to generate duplicate
solutions. Suppose two rows cover the same column and
sit in a feasible solution to a covering problem, the same
solution may reappear with the two rows included in the
reverse order. If the leftmost column has a high
multiplicity, the algorithm yields numerous duplicate solutions;
in comparison, if the column with higher multiplicity is
placed further to the right in the structure, as the data
matrix shrinks during the search, the algorithm tends to
generate fewer duplicate solutions.</p>
        <p>
          For example, consider the covering of 5 by 4 copies
of 3, of which the excess is known ([
          <xref ref-type="bibr" rid="ref5">5</xref>
          ], p. 371, Table
VI.11.41) to be a double edge. With the edges of 5
ordered lexicographically, assigning multiplicity 3 to the
        </p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>3. Eficiency considerations</title>
      <p>This section evaluates the dancing links algorithm
adapted to the covering problem in Section 2.2. Some
improvements to eliminate multiple counts are suggested.</p>
      <sec id="sec-3-1">
        <title>3.1. Ordered search of rows</title>
        <p>An apparent shortcoming of our algorithm is the
redundant search of rows covering the same column with
nontrivial multiplicity, which not only produces an
inaccurate number of solutions, if any exist, but also harms the
eficiency of the algorithm. To address the issue, when
covering such a column, the rows containing it should
be processed only in a certain order.</p>
        <p>One approach is to introduce an order on the elements
in each column. More specifically, we return the
currently processed row  in the search function, and start
the next search from the next valid row once the columns
concerned are properly “removed" by the cover_column
function. This idea is realised by introducing the
previously unused field [] to each data object : the objects
in a column  are assigned values 1, 2, · · · , [] from the
top row to the bottom. The modified search function (see
the lines 8–13 below) follows.
def search(depth, prev):
if R[h] == h:
print_solution()
return prev
else:
c = choose_column()
cover_column(c)
r = D[c]
if c == C[prev]:
while S[r] &lt; S[prev]:
if r == c:</p>
        <p>break
r = D[r]
while r != c:
partial_solution.append(r)
j = R[r]
while j != r:
cover_column(C[j])
j = R[j]
search(depth + 1, r)
r = partial_solution.pop()
c = C[r]
j = L[r]
while j != r:
uncover_column(C[j])
j = L[j]
r = D[r]
uncover_column(c)
return r
obj = L[obj]
if obj == L[r]:</p>
        <p>break
return</p>
        <p>For instance, with the following lines executed, the
algorithm finds only 2 decompositions of 7 into 3
containing the triangles ∆123 and ∆145 , as expected.</p>
      </sec>
      <sec id="sec-3-2">
        <title>3.2. Exploiting the symmetry</title>
        <p>In addition to the redundant solutions addressed in Sec- utilise_row('1, 2, 3')
tion 3.1, another factor that increases the size of output utilise_row('1, 4, 5')
is that some solutions are simply a permutation of ver- search(0)
tices applied to one another, such as the following two neutralise_row('1, 4, 5')
decompositions of 7 into 3: neutralise_row('1, 2, 3')
{∆124 , ∆235 , ∆346 , ∆457 , ∆156 , ∆267 , ∆137 },
{∆123 , ∆245 , ∆346 , ∆357 , ∆156 , ∆267 , ∆147 }.</p>
        <p>It is worth mentioning that some solutions, even
sometimes all, may be omitted when a search bears too many
ifxed rows. Further research can be carried out on the
maximal amount of (independent) rows one is able to fix
while preventing the algorithm from missing a solution.</p>
        <p>If we draw the vertices 1, 2, · · · , 7 of 7 cyclically, the
ifrst solution above is a cyclic decomposition into 3
while the second seems not to be cyclic. However, if we
swap the vertices 3 and 4, the second solution becomes 4. Computations
cyclic as well, which implies that the two solutions are
equivalent. To demonstrate the eficiency of the DLX algorithm for</p>
        <p>Multiple counts of equivalent solutions appeared al- the cover problem, we summarize computation times
ready in graph decompositions. Motivated by such con- for finding all solutions when covering  by  for
siderations, we can fix certain row(s) when searching  = 3, 4 along with the count of all possible covers.
solutions using the dancing links algorithm to omit equiv- Confirming the existence by finding the first solution,
alent solutions, provided that merely the existence of any provided it exists, for  in Tables 2 through 4 took less
solution interests us. The implementation follows. than 1 second in each of the cases. Table 1 compares
rundef utilise_row(r): ning times of the original dancing link algorithm with
partial_solution.append(r) the modified algorithm where decomposition (not cover)
obj = r is possible, since the DLX algorithm does not support
while True: covers. The times are essentially identical, since the
modicover_column(C[obj]) ifcation did not have much influence on the performance.
obj = R[obj] Tables 2 through 4 then compare running times of the
if obj == r: cover problem for diferent sizes of the covered graph.</p>
        <p>break Columns 3 and 4 give the counts and times when finding
return all possible covers using the modification of the DLX
algorithm described in Section 2.2, where some equivalent</p>
        <p>
          After the data setup, we may execute several lines solutions are counted multiple times. Columns 5 and
of utilise_row to restrict our attention to the solutions 6 give the counts and times when finding all possible
containing certain rows, before invoking search(0). For covers eliminating multiple counts (and thus reducing
the sake of conservation of the structure, it is advisable to the number of cases to traverse) using the modification
call the following neutralise_row function in the opposite described in Section 3.1.
order after the search of solutions, when the original data Other approaches have been used to find complete
structure is properly restored. graph decompositions using a brute force search. In [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ]
were graph decompositions found via a SAT solver. The
authors say that to produce a 6 decomposition of 31
took about 100 seconds. Using our implementation of
the DLX algorithm it took about 25 seconds to set up the
data structure described in Section 1.2 for the 6
decomposition of 31 (465 columns and 736 281 rows). Then
however a decomposition was found in less than 1 second.
def neutralise_row(r):
if partial_solution.pop() != r:
        </p>
        <p>return -1
else:
obj = L[r]
while True:</p>
        <p>uncover_column(C[obj])</p>
        <p>5. Conclusion</p>
        <p>
          On the other hand, the nonexistence of a 6
decomposition of 16 was shown in less than a second by UNSAT
in [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ], while our algorithm gave the negative answer only
after traversing the whole search tree in 70 seconds. All
computations were performed on a notebook with an i5
core at 2.5 GHz.
        </p>
        <p>When running the DLX algorithm for  = 3 and  = 4
we include the positive answers only (Tables 2 and 3),
since the existence is known. When covering 
simultanously by 3 and 4 we provide running times of
the DLX algorithm even in some cases when no solution
exists (e.g. with excess 2), which was demonstrated by
a brute force search with negative outcome (Table 4).</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Acknowledgments</title>
      <p>This work is partially supported by Grant of SGS</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>D.</given-names>
            <surname>Lukáš</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Kovář</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Kovářová</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Merta</surname>
          </string-name>
          ,
          <article-title>A parallel fast boundary element method using cyclic graph decompositions</article-title>
          ,
          <source>Numerical Algorithms</source>
          <volume>70</volume>
          (
          <year>2015</year>
          )
          <fpage>807</fpage>
          -
          <lpage>824</lpage>
          . doi:
          <volume>10</volume>
          .1007/s11075-015-9974-9.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>H.</given-names>
            <surname>Hanani</surname>
          </string-name>
          ,
          <article-title>Balanced incomplete block designs and related designs</article-title>
          ,
          <source>Discrete Mathematics</source>
          <volume>11</volume>
          (
          <year>1975</year>
          )
          <fpage>255</fpage>
          -
          <lpage>369</lpage>
          . doi:
          <volume>10</volume>
          .1016/
          <fpage>0012</fpage>
          -
          <lpage>365X</lpage>
          (
          <issue>75</issue>
          )
          <fpage>90040</fpage>
          -
          <lpage>0</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>W.</given-names>
            <surname>Mills</surname>
          </string-name>
          ,
          <article-title>On the covering of pairs by quadruples i</article-title>
          ,
          <source>Journal of Combinatorial Theory, Series A</source>
          <volume>13</volume>
          (
          <year>1972</year>
          )
          <fpage>55</fpage>
          -
          <lpage>78</lpage>
          . doi:
          <volume>10</volume>
          .1016/
          <fpage>0097</fpage>
          -
          <lpage>3165</lpage>
          (
          <issue>72</issue>
          )
          <fpage>90008</fpage>
          -
          <lpage>8</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>W.</given-names>
            <surname>Mills</surname>
          </string-name>
          ,
          <article-title>On the covering of pairs by quadruples</article-title>
          . ii,
          <source>Journal of Combinatorial Theory, Series A</source>
          <volume>15</volume>
          (
          <year>1973</year>
          )
          <fpage>138</fpage>
          -
          <lpage>166</lpage>
          . doi:
          <volume>10</volume>
          .1016/S0097-
          <volume>3165</volume>
          (
          <issue>73</issue>
          )
          <fpage>80003</fpage>
          -
          <lpage>2</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>C. J.</given-names>
            <surname>Colbourn</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. H.</given-names>
            <surname>Dinitz</surname>
          </string-name>
          (Eds.),
          <source>Handbook of combinatorial designs</source>
          , 2nd. ed., CRC Press,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>D. E.</given-names>
            <surname>Knuth</surname>
          </string-name>
          , Dancing links,
          <year>2000</year>
          . arXiv:cs/0011047.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>W.</given-names>
            <surname>Zhao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Lifiton</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Jeavons</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Roberts</surname>
          </string-name>
          , Finding graph decompositions via sat,
          <source>2017 IEEE 29th International Conference on Tools with Artificial Intelligence (ICTAI)</source>
          (
          <year>2017</year>
          )
          <fpage>131</fpage>
          -
          <lpage>138</lpage>
          . doi:
          <volume>10</volume>
          .1109/ ICTAI.
          <year>2017</year>
          .
          <volume>00031</volume>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>