diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 4590822c..8fdf1407 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-09-25T19:14:44","documenter_version":"1.0.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-09-25T20:20:03","documenter_version":"1.0.1"}} \ No newline at end of file diff --git a/dev/generated/Coloring/48da499f.svg b/dev/generated/Coloring/562ae81f.svg similarity index 95% rename from dev/generated/Coloring/48da499f.svg rename to dev/generated/Coloring/562ae81f.svg index fd22cab1..322090fa 100644 --- a/dev/generated/Coloring/48da499f.svg +++ b/dev/generated/Coloring/562ae81f.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/Coloring/e6ffa2e3.svg b/dev/generated/Coloring/beec6420.svg similarity index 95% rename from dev/generated/Coloring/e6ffa2e3.svg rename to dev/generated/Coloring/beec6420.svg index 73c23ee9..1d20316b 100644 --- a/dev/generated/Coloring/e6ffa2e3.svg +++ b/dev/generated/Coloring/beec6420.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -86,69 +86,69 @@ - + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/dev/generated/Coloring/6948b7a5.svg b/dev/generated/Coloring/c2dd93f2.svg similarity index 89% rename from dev/generated/Coloring/6948b7a5.svg rename to dev/generated/Coloring/c2dd93f2.svg index 3a129db8..06136c5f 100644 --- a/dev/generated/Coloring/6948b7a5.svg +++ b/dev/generated/Coloring/c2dd93f2.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -54,46 +54,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/Coloring/index.html b/dev/generated/Coloring/index.html index 5cf44349..6fb3f464 100644 --- a/dev/generated/Coloring/index.html +++ b/dev/generated/Coloring/index.html @@ -5,7 +5,7 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the 3-coloring problem as

problem = Coloring{3}(graph);

Theory (can skip)

Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex $v$, we define the degrees of freedom $c_v\in\{1,2,3\}$ and a vertex tensor labelled by it as

\[W(v) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the 3-coloring problem as

problem = Coloring{3}(graph);

Theory (can skip)

Type Coloring can be used for constructing the tensor network with optimized contraction order for a coloring problem. Let us use 3-coloring problem defined on vertices as an example. For a vertex $v$, we define the degrees of freedom $c_v\in\{1,2,3\}$ and a vertex tensor labelled by it as

\[W(v) = \left(\begin{matrix} 1\\ 1\\ 1 @@ -20,9 +20,9 @@ vertex_color_map = Dict(0=>"red", 1=>"green", 2=>"blue") show_graph(graph; locs=locations, format=:svg, vertex_colors=[vertex_color_map[Int(c)] - for c in single_solution.c.data])Example block output

Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

linegraph = line_graph(graph)
+     for c in single_solution.c.data])
Example block output

Let us try to solve the same issue on its line graph, a graph that generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

linegraph = line_graph(graph)
 
 show_graph(linegraph; locs=[0.5 .* (locations[e.src] .+ locations[e.dst])
-     for e in edges(graph)], format=:svg)
Example block output

Let us construct the tensor network and see if there are solutions.

lineproblem = Coloring{3}(linegraph);
+     for e in edges(graph)], format=:svg)
Example block output

Let us construct the tensor network and see if there are solutions.

lineproblem = Coloring{3}(linegraph);
 
-num_of_coloring = solve(lineproblem, CountingMax())[]
(28.0, 1800.0)โ‚œ

You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.


This page was generated using Literate.jl.

+num_of_coloring = solve(lineproblem, CountingMax())[]
(28.0, 1800.0)โ‚œ

You will see the maximum size 28 is smaller than the number of edges in the linegraph, meaning no solution for the 3-coloring on edges of a Petersen graph.


This page was generated using Literate.jl.

diff --git a/dev/generated/DominatingSet/9991bfd3.svg b/dev/generated/DominatingSet/97999130.svg similarity index 95% rename from dev/generated/DominatingSet/9991bfd3.svg rename to dev/generated/DominatingSet/97999130.svg index 05d9b9d5..ee5ccce7 100644 --- a/dev/generated/DominatingSet/9991bfd3.svg +++ b/dev/generated/DominatingSet/97999130.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/DominatingSet/798804bf.svg b/dev/generated/DominatingSet/a050b03b.svg similarity index 81% rename from dev/generated/DominatingSet/798804bf.svg rename to dev/generated/DominatingSet/a050b03b.svg index 6f11fd82..f8481350 100644 --- a/dev/generated/DominatingSet/798804bf.svg +++ b/dev/generated/DominatingSet/a050b03b.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -54,46 +54,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -110,46 +110,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -168,44 +168,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -222,46 +222,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -280,44 +280,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -334,46 +334,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -392,44 +392,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -448,44 +448,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -504,44 +504,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -560,44 +560,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/DominatingSet/index.html b/dev/generated/DominatingSet/index.html index 268744ab..bcc33e0c 100644 --- a/dev/generated/DominatingSet/index.html +++ b/dev/generated/DominatingSet/index.html @@ -5,7 +5,7 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use DominatingSet to construct the tensor network for solving the dominating set problem as

problem = DominatingSet(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on a vertex and its neighboring vertices $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use DominatingSet to construct the tensor network for solving the dominating set problem as

problem = DominatingSet(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on a vertex and its neighboring vertices $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} 0 & s_1=s_2=\ldots=s_{|N(v)|}=s_v=0,\\ 1 & s_v=0,\\ x_v^{w_v} & \text{otherwise}, @@ -13,4 +13,4 @@ Space complexity: 2^8.0 Read-write complexity: 2^11.129926933510392

Solving properties

Counting properties

Domination polynomial

The graph polynomial for the dominating set problem is known as the domination polynomial (see arXiv:0905.2251). It is defined as

\[D(G, x) = \sum_{k=0}^{\gamma(G)} d_k x^k,\]

where $d_k$ is the number of dominating sets of size $k$ in graph $G=(V, E)$.

domination_polynomial = solve(problem, GraphPolynomial())[]
10∙x3 + 75∙x4 + 192∙x5 + 200∙x6 + 120∙x7 + 45∙x8 + 10∙x9 + x10

The domination number $\gamma(G)$ can be computed with the SizeMin property:

domination_number = solve(problem, SizeMin())[]
3.0โ‚œ

Similarly, we have its counting CountingMin:

counting_min_dominating_set = solve(problem, CountingMin())[]
(3.0, 10.0)โ‚œ

Configuration properties

finding minimum dominating set

One can enumerate all minimum dominating sets with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
 
-all(c->is_dominating_set(graph, c), min_configs)
true
show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+all(c->is_dominating_set(graph, c), min_configs)
true
show_gallery(graph, (2, 5); locs=locations, vertex_configs=min_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum dominating sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/HyperSpinGlass/index.html b/dev/generated/HyperSpinGlass/index.html index bfd8c4be..82eb7418 100644 --- a/dev/generated/HyperSpinGlass/index.html +++ b/dev/generated/HyperSpinGlass/index.html @@ -19,4 +19,4 @@ \end{cases}\]

and the vertex tensor $W^{(v)}$ (used to carry labels) is defined as

\[W^{(v)} = \left(\begin{matrix}1_v\\ 1_v\end{matrix}\right)\]

Solving properties

Minimum and maximum energies

Its ground state energy is -8.

Emin = solve(problem, SizeMin())[]
-8.0โ‚œ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
8.0โ‚œ

In this example, the spin configurations can be chosen to make all hyperedges having even or odd spin parity.

Counting properties

partition function and graph polynomial

The graph polynomial defined for the hyper-spin-glass problem is a Laurent polynomial

\[Z(G, w, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let the inverse temperature $\beta = 2$, the partition function is

ฮฒ = 2.0
 Z = solve(problem, PartitionFunction(ฮฒ))[]
1.315167258498167e9

The infinite temperature partition function is the counting of all feasible configurations

solve(problem, PartitionFunction(0.0))[]
32768.0

Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

poly = solve(problem, GraphPolynomial())[]
128.0∙xโปโธ + 1024.0∙xโปโถ + 3584.0∙xโปโด + 7168.0∙xโปยฒ + 8960.0 + 7168.0∙xยฒ + 3584.0∙xโด + 1024.0∙xโถ + 128.0∙xโธ

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
 
-Emin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)
-8

You should see a consistent result as above Emin.


This page was generated using Literate.jl.

+Emin_verify = hyperspinglass_energy(hyperedges, ground_state; weights)
-8

You should see a consistent result as above Emin.


This page was generated using Literate.jl.

diff --git a/dev/generated/IndependentSet/863bb5fa.svg b/dev/generated/IndependentSet/863bb5fa.svg new file mode 100644 index 00000000..226250af --- /dev/null +++ b/dev/generated/IndependentSet/863bb5fa.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/generated/IndependentSet/b0c9ec80.svg b/dev/generated/IndependentSet/c140c961.svg similarity index 81% rename from dev/generated/IndependentSet/b0c9ec80.svg rename to dev/generated/IndependentSet/c140c961.svg index 0c66e220..4731038c 100644 --- a/dev/generated/IndependentSet/b0c9ec80.svg +++ b/dev/generated/IndependentSet/c140c961.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + @@ -112,44 +112,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -166,46 +166,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -222,46 +222,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -280,44 +280,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaxCut/697af474.svg b/dev/generated/IndependentSet/c7dd602c.svg similarity index 90% rename from dev/generated/MaxCut/697af474.svg rename to dev/generated/IndependentSet/c7dd602c.svg index 7d437e43..b44d4415 100644 --- a/dev/generated/MaxCut/697af474.svg +++ b/dev/generated/IndependentSet/c7dd602c.svg @@ -2,42 +2,42 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/IndependentSet/index.html b/dev/generated/IndependentSet/index.html index 42a3f138..50c807db 100644 --- a/dev/generated/IndependentSet/index.html +++ b/dev/generated/IndependentSet/index.html @@ -6,52 +6,52 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

The graphical display is available in the following editors

Generic tensor network representation

The generic tensor network representation of the independent set problem can be constructed with IndependentSet.

problem = IndependentSet(graph; optimizer=TreeSA());

Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.

Theory (can skip)

Let $G=(V, E)$ be a graph with each vertex $v\in V$ associated with a weight $w_v$. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex $v\in V$ to a label $s_v \in \{0, 1\}$ of dimension $2$, where we use $0$ ($1$) to denote a vertex absent (present) in the set. For each vertex $v$, we defined a parameterized rank-one tensor indexed by $s_v$ as

\[W(x_v^{w_v}) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)Example block output

The graphical display is available in the following editors

Generic tensor network representation

The generic tensor network representation of the independent set problem can be constructed with IndependentSet.

problem = IndependentSet(graph; optimizer=TreeSA());

Here, the key word argument optimizer specifies the tensor network contraction order optimizer as a local search based optimizer TreeSA. The resulting contraction order optimized tensor network is contained in the code field of problem.

Theory (can skip)

Let $G=(V, E)$ be a graph with each vertex $v\in V$ associated with a weight $w_v$. To reduce the independent set problem on it to a tensor network contraction, we first map a vertex $v\in V$ to a label $s_v \in \{0, 1\}$ of dimension $2$, where we use $0$ ($1$) to denote a vertex absent (present) in the set. For each vertex $v$, we defined a parameterized rank-one tensor indexed by $s_v$ as

\[W(x_v^{w_v}) = \left(\begin{matrix} 1 \\ x_v^{w_v} \end{matrix}\right)\]

where $x_v$ is a variable associated with $v$. Similarly, for each edge $(u, v) \in E$, we define a matrix $B$ indexed by $s_u$ and $s_v$ as

\[B = \left(\begin{matrix} 1 & 1\\ 1 & 0 -\end{matrix}\right).\]

Ideally, an optimal contraction order has a space complexity $2^{{\rm tw}(G)}$, where ${\rm tw(G)}$ is the tree-width of $G$ (or graph in the code). We can check the time, space and read-write complexities by typing

contraction_complexity(problem)
Time complexity: 2^7.965784284662088
+\end{matrix}\right).\]

Ideally, an optimal contraction order has a space complexity $2^{{\rm tw}(G)}$, where ${\rm tw(G)}$ is the tree-width of $G$ (or graph in the code). We can check the time, space and read-write complexities by typing

contraction_complexity(problem)
Time complexity: 2^7.965784284662087
 Space complexity: 2^4.0
 Read-write complexity: 2^8.661778097771986

For more information about how to improve the contraction order, please check the Performance Tips.

Solution space properties

Maximum independent set size $\alpha(G)$

We can compute solution space properties with the solve function, which takes two positional arguments, the problem instance and the wanted property.

maximum_independent_set_size = solve(problem, SizeMax())[]
4.0โ‚œ

Here SizeMax means finding the solution with maximum set size. The return value has Tropical type. We can get its content by typing

maximum_independent_set_size.n
4.0

Counting properties

Count all solutions and best several solutions

We can count all independent sets with the CountingAll property.

count_all_independent_sets = solve(problem, CountingAll())[]
76.0

The return value has type Float64. The counting of all independent sets is equivalent to the infinite temperature partition function

solve(problem, PartitionFunction(0.0))[]
76.0

We can count the maximum independent sets with CountingMax.

count_maximum_independent_sets = solve(problem, CountingMax())[]
(4.0, 5.0)โ‚œ

The return value has type CountingTropical, which contains two fields. They are n being the maximum independent set size and c being the number of the maximum independent sets.

count_maximum_independent_sets.c
5.0

Similarly, we can count independent sets of sizes $\alpha(G)$ and $\alpha(G)-1$ by feeding an integer positional argument to CountingMax.

count_max2_independent_sets = solve(problem, CountingMax(2))[]
30.0*x^3 + 5.0*x^4

The return value has type TruncatedPoly, which contains two fields. They are maxorder being the maximum independent set size and coeffs being the number of independent sets having sizes $\alpha(G)-1$ and $\alpha(G)$.

count_max2_independent_sets.coeffs
(30.0, 5.0)
Find the graph polynomial

We can count the number of independent sets at any size, which is equivalent to finding the coefficients of an independence polynomial that defined as

\[I(G, x) = \sum_{k=0}^{\alpha(G)} a_k x^k,\]

where $\alpha(G)$ is the maximum independent set size, $a_k$ is the number of independent sets of size $k$. The total number of independent sets is thus equal to $I(G, 1)$. There are 3 methods to compute a graph polynomial, :finitefield, :fft and :polynomial. These methods are introduced in the docstring of GraphPolynomial.

independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))[]
1 + 10∙x + 30∙x2 + 30∙x3 + 5∙x4

The return type is Polynomial.

independence_polynomial.coeffs
5-element Vector{BigInt}:
   1
  10
  30
  30
-  5

Configuration properties

Find one best solution

We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).

max_config = solve(problem, SingleConfigMax(; bounded=false))[]
(4.0, ConfigSampler{10, 1, 1}(0100100110))โ‚œ

The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution

single_solution = max_config.c.data
0100100110

This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.

show_graph(graph; locs=locations, format=:svg, vertex_colors=
-    [iszero(single_solution[i]) ? "white" : "red" for i=1:nv(graph)])
Example block output
Enumerate all solutions and best several solutions

We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.

all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]
(4.0, {1001001100, 0101010001, 1010000011, 0010111000, 0100100110})โ‚œ

The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.

all_max_configs.c.data
5-element Vector{StaticBitVector{10, 1}}:
+  5

Configuration properties

Find one best solution

We can use the bounded or unbounded SingleConfigMax to find one of the solutions with largest size. The unbounded (default) version uses a joint type of CountingTropical and ConfigSampler in computation, where CountingTropical finds the maximum size and ConfigSampler samples one of the best solutions. The bounded version uses the binary gradient back-propagation (see our paper) to compute the gradients. It requires caching intermediate states, but is often faster (on CPU) because it can use TropicalGEMM (see Performance Tips).

max_config = solve(problem, SingleConfigMax(; bounded=false))[]
(4.0, ConfigSampler{10, 1, 1}(0010111000))โ‚œ

The return value has type CountingTropical with its counting field having ConfigSampler type. The data field of ConfigSampler is a bit string that corresponds to the solution

single_solution = max_config.c.data
0010111000

This bit string should be read from left to right, with the i-th bit being 1 (0) to indicate the i-th vertex is present (absent) in the set. We can visualize this MIS with the following function.

show_graph(graph; locs=locations, format=:svg, vertex_colors=
+    [iszero(single_solution[i]) ? "white" : "red" for i=1:nv(graph)])
Example block output
Enumerate all solutions and best several solutions

We can use bounded or unbounded ConfigsMax to find all solutions with largest-K set sizes. In most cases, the bounded (default) version is preferred because it can reduce the memory usage significantly.

all_max_configs = solve(problem, ConfigsMax(; bounded=true))[]
(4.0, {1001001100, 0100100110, 0101010001, 1010000011, 0010111000})โ‚œ

The return value has type CountingTropical, while its counting field having type ConfigEnumerator. The data field of a ConfigEnumerator instance contains a vector of bit strings.

all_max_configs.c.data
5-element Vector{StaticBitVector{10, 1}}:
  1001001100
+ 0100100110
  0101010001
  1010000011
- 0010111000
- 0100100110

These solutions can be visualized with the show_gallery function.

show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)
Example block output

We can use ConfigsAll to enumerate all sets satisfying the independence constraint.

all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0000010000, 0000000010, 0100000000, 0100010000, 0100000010, 0010000000, 0010010000, 0010000010, 0001000000, 0001010000, 0101000000, 0101010000, 1000000000, 1000000010, 1010000000, 1010000010, 1001000000, 0000001000, 0000011000, 0010001000, 0010011000, 0001001000, 0001011000, 1000001000, 1010001000, 1001001000, 0000000100, 0000000110, 0100000100, 0100000110, 0001000100, 0101000100, 1000000100, 1000000110, 1001000100, 0000001100, 0001001100, 1000001100, 1001001100, 0000000001, 0000010001, 0000000011, 0100000001, 0100010001, 0100000011, 0010000001, 0010010001, 0010000011, 0001000001, 0001010001, 0101000001, 0101010001, 1000000001, 1000000011, 1010000001, 1010000011, 1001000001, 0000100000, 0000110000, 0000100010, 0100100000, 0100110000, 0100100010, 0010100000, 0010110000, 0010100010, 0000101000, 0000111000, 0010101000, 0010111000, 0000100100, 0000100110, 0100100100, 0100100110, 0000101100}

The return value has type ConfigEnumerator.

Sample solutions

It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+ (count = 76.0)
+ 0010111000

These solutions can be visualized with the show_gallery function.

show_gallery(graph, (1, length(all_max_configs.c)); locs=locations, vertex_configs=all_max_configs.c, format=:svg)
Example block output

We can use ConfigsAll to enumerate all sets satisfying the independence constraint.

all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0000000100, 0000010000, 0000100000, 0000100100, 0000110000, 0001000000, 0001000100, 0001010000, 0000000010, 0000000110, 0000100010, 0000100110, 0000000001, 0000010001, 0001000001, 0001010001, 0000000011, 1000000000, 1000000100, 1001000000, 1001000100, 1000000010, 1000000110, 1000000001, 1001000001, 1000000011, 0000001000, 0000001100, 0000011000, 0000101000, 0000101100, 0000111000, 0001001000, 0001001100, 0001011000, 1000001000, 1000001100, 1001001000, 1001001100, 0100000000, 0100000100, 0100010000, 0100100000, 0100100100, 0100110000, 0101000000, 0101000100, 0101010000, 0100000010, 0100000110, 0100100010, 0100100110, 0100000001, 0100010001, 0101000001, 0101010001, 0100000011, 0010000000, 0010010000, 0010100000, 0010110000, 0010000010, 0010100010, 0010000001, 0010010001, 0010000011, 1010000000, 1010000010, 1010000001, 1010000011, 0010001000, 0010011000, 0010101000, 0010111000, 1010001000}

The return value has type ConfigEnumerator.

Sample solutions

It is often difficult to store all configurations in a vector. A more clever way to store the data is using the sum product tree format.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+ (count = 76.0)
 โ”œโ”€ + (count = 58.0)
 โ”‚  โ”œโ”€ + (count = 40.0)
-โ”‚  โ”‚  โ”œโ”€ + (count = 27.0)
-โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 18.0)
-โ”‚  โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 17.0)
+โ”‚  โ”‚  โ”œโ”€ + (count = 36.0)
+โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 27.0)
+โ”‚  โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 18.0)
 โ”‚  โ”‚  โ”‚  โ”‚  โ”‚  โ‹ฎ
 โ”‚  โ”‚  โ”‚  โ”‚  โ”‚  
-โ”‚  โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 1.0)
+โ”‚  โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 9.0)
 โ”‚  โ”‚  โ”‚  โ”‚     โ‹ฎ
 โ”‚  โ”‚  โ”‚  โ”‚     
-โ”‚  โ”‚  โ”‚  โ””โ”€ + (count = 9.0)
-โ”‚  โ”‚  โ”‚     โ”œโ”€ + (count = 8.0)
-โ”‚  โ”‚  โ”‚     โ”‚  โ‹ฎ
-โ”‚  โ”‚  โ”‚     โ”‚  
-โ”‚  โ”‚  โ”‚     โ””โ”€ * (count = 1.0)
+โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 9.0)
+โ”‚  โ”‚  โ”‚     โ”œโ”€ OnehotVec{10, 2}(7, 1)
+โ”‚  โ”‚  โ”‚     โ””โ”€ * (count = 9.0)
 โ”‚  โ”‚  โ”‚        โ‹ฎ
 โ”‚  โ”‚  โ”‚        
-โ”‚  โ”‚  โ””โ”€ * (count = 13.0)
-โ”‚  โ”‚     โ”œโ”€ + (count = 13.0)
-โ”‚  โ”‚     โ”‚  โ”œโ”€ + (count = 9.0)
-โ”‚  โ”‚     โ”‚  โ”‚  โ‹ฎ
-โ”‚  โ”‚     โ”‚  โ”‚  
-โ”‚  โ”‚     โ”‚  โ””โ”€ + (count = 4.0)
-โ”‚  โ”‚     โ”‚     โ‹ฎ
-โ”‚  โ”‚     โ”‚     
-โ”‚  โ”‚     โ””โ”€ OnehotVec{10, 2}(8, 1)
+โ”‚  โ”‚  โ””โ”€ * (count = 4.0)
+โ”‚  โ”‚     โ”œโ”€ * (count = 1.0)
+โ”‚  โ”‚     โ”‚  โ”œโ”€ OnehotVec{10, 2}(1, 1)
+โ”‚  โ”‚     โ”‚  โ””โ”€ OnehotVec{10, 2}(7, 1)
+โ”‚  โ”‚     โ””โ”€ * (count = 4.0)
+โ”‚  โ”‚        โ”œโ”€ + (count = 2.0)
+โ”‚  โ”‚        โ”‚  โ‹ฎ
+โ”‚  โ”‚        โ”‚  
+โ”‚  โ”‚        โ””โ”€ + (count = 2.0)
+โ”‚  โ”‚           โ‹ฎ
+โ”‚  โ”‚           
 โ”‚  โ””โ”€ * (count = 18.0)
 โ”‚     โ”œโ”€ + (count = 18.0)
 โ”‚     โ”‚  โ”œโ”€ + (count = 17.0)
@@ -62,44 +62,38 @@
 โ”‚     โ”‚  โ”‚     โ‹ฎ
 โ”‚     โ”‚  โ”‚     
 โ”‚     โ”‚  โ””โ”€ * (count = 1.0)
-โ”‚     โ”‚     โ”œโ”€ OnehotVec{10, 2}(4, 1)
-โ”‚     โ”‚     โ””โ”€ OnehotVec{10, 2}(1, 1)
-โ”‚     โ””โ”€ OnehotVec{10, 2}(10, 1)
+โ”‚     โ”‚     โ”œโ”€ OnehotVec{10, 2}(10, 1)
+โ”‚     โ”‚     โ””โ”€ OnehotVec{10, 2}(9, 1)
+โ”‚     โ””โ”€ OnehotVec{10, 2}(2, 1)
 โ””โ”€ * (count = 18.0)
-   โ”œโ”€ OnehotVec{10, 2}(5, 1)
+   โ”œโ”€ OnehotVec{10, 2}(3, 1)
    โ””โ”€ + (count = 18.0)
-      โ”œโ”€ + (count = 13.0)
-      โ”‚  โ”œโ”€ * (count = 9.0)
-      โ”‚  โ”‚  โ”œโ”€ + (count = 3.0)
+      โ”œโ”€ + (count = 17.0)
+      โ”‚  โ”œโ”€ + (count = 13.0)
+      โ”‚  โ”‚  โ”œโ”€ + (count = 9.0)
       โ”‚  โ”‚  โ”‚  โ‹ฎ
       โ”‚  โ”‚  โ”‚  
-      โ”‚  โ”‚  โ””โ”€ + (count = 3.0)
+      โ”‚  โ”‚  โ””โ”€ * (count = 4.0)
       โ”‚  โ”‚     โ‹ฎ
       โ”‚  โ”‚     
       โ”‚  โ””โ”€ * (count = 4.0)
-      โ”‚     โ”œโ”€ + (count = 2.0)
-      โ”‚     โ”‚  โ‹ฎ
-      โ”‚     โ”‚  
-      โ”‚     โ””โ”€ + (count = 2.0)
+      โ”‚     โ”œโ”€ OnehotVec{10, 2}(7, 1)
+      โ”‚     โ””โ”€ * (count = 4.0)
       โ”‚        โ‹ฎ
       โ”‚        
-      โ””โ”€ * (count = 5.0)
-         โ”œโ”€ + (count = 5.0)
-         โ”‚  โ”œโ”€ * (count = 4.0)
-         โ”‚  โ”‚  โ‹ฎ
-         โ”‚  โ”‚  
-         โ”‚  โ””โ”€ OnehotVec{10, 2}(7, 1)
-         โ””โ”€ OnehotVec{10, 2}(8, 1)
+      โ””โ”€ * (count = 1.0)
+         โ”œโ”€ OnehotVec{10, 2}(1, 1)
+         โ””โ”€ OnehotVec{10, 2}(7, 1)
 

The return value has the SumProductTree type. Its length corresponds to the number of configurations.

length(all_independent_sets_tree)
76.0

We can use Base.collect function to create a ConfigEnumerator or use generate_samples to generate samples from it.

collect(all_independent_sets_tree)
 
 generate_samples(all_independent_sets_tree, 10)
10-element Vector{StaticBitVector{10, 1}}:
  0001000000
- 0001010000
- 0001010000
- 0001011000
- 0001011000
- 0101000100
- 0010000001
- 0000010001
- 1000000001
- 0100100100

This page was generated using Literate.jl.

+ 0000000100 + 0001000001 + 0001000001 + 1000000000 + 0000101000 + 0000011000 + 1001001100 + 0101010001 + 0010100000

This page was generated using Literate.jl.

diff --git a/dev/generated/Matching/880396a0.svg b/dev/generated/Matching/7c793104.svg similarity index 94% rename from dev/generated/Matching/880396a0.svg rename to dev/generated/Matching/7c793104.svg index 175ef295..b9529924 100644 --- a/dev/generated/Matching/880396a0.svg +++ b/dev/generated/Matching/7c793104.svg @@ -2,98 +2,98 @@ - + - + - + - + - + - + - + - + - + - + - + - - + + - + - - - - + + + + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/Matching/23812c50.svg b/dev/generated/Matching/c9a3dba2.svg similarity index 95% rename from dev/generated/Matching/23812c50.svg rename to dev/generated/Matching/c9a3dba2.svg index ee9bf85a..bb1bded5 100644 --- a/dev/generated/Matching/23812c50.svg +++ b/dev/generated/Matching/c9a3dba2.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/Matching/index.html b/dev/generated/Matching/index.html index ac032ba7..8a63032a 100644 --- a/dev/generated/Matching/index.html +++ b/dev/generated/Matching/index.html @@ -3,11 +3,11 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the matching problem by typing

problem = Matching(graph);

Theory (can skip)

Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge $(u, v) \in E$ to a label $\langle u, v\rangle \in \{0, 1\}$ in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank $d(v) = |N(v)|$ on vertex $v$ such that,

\[W_{\langle v, n_1\rangle, \langle v, n_2 \rangle, \ldots, \langle v, n_{d(v)}\rangle} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We construct the tensor network for the matching problem by typing

problem = Matching(graph);

Theory (can skip)

Type Matching can be used for constructing the tensor network with optimized contraction order for a matching problem. We map an edge $(u, v) \in E$ to a label $\langle u, v\rangle \in \{0, 1\}$ in a tensor network, where 1 means two vertices of an edge are matched, 0 means otherwise. Then we define a tensor of rank $d(v) = |N(v)|$ on vertex $v$ such that,

\[W_{\langle v, n_1\rangle, \langle v, n_2 \rangle, \ldots, \langle v, n_{d(v)}\rangle} = \begin{cases} 1, & \sum_{i=1}^{d(v)} \langle v, n_i \rangle \leq 1,\\ 0, & \text{otherwise}, \end{cases}\]

and a tensor of rank 1 on the bond

\[B_{\langle v, w\rangle} = \begin{cases} 1, & \langle v, w \rangle = 0 \\ x, & \langle v, w \rangle = 1, -\end{cases}\]

where label $\langle v, w \rangle$ is equivalent to $\langle w,v\rangle$.

Solving properties

Maximum matching

Configuration properties

max_matching = solve(problem, SizeMax())[]
5.0โ‚œ

The largest number of matching is 5, which means we have a perfect matching (vertices are all paired).

matching polynomial

The graph polynomial defined for the matching problem is known as the matching polynomial. Here, we adopt the first definition in the wiki page.

\[M(G, x) = \sum\limits_{k=1}^{|V|/2} c_k x^k,\]

where $k$ is the number of matches, and coefficients $c_k$ are the corresponding counting.

matching_poly = solve(problem, GraphPolynomial())[]
1 + 15∙x + 75∙x2 + 145∙x3 + 90∙x4 + 6∙x5

Configuration properties

one of the perfect matches
match_config = solve(problem, SingleConfigMax())[]
(5.0, ConfigSampler{15, 1, 1}(100001000110100))โ‚œ

Let us show the result by coloring the matched edges to red

show_graph(graph; locs=locations, format=:svg, edge_colors=
-    [isone(match_config.c.data[i]) ? "red" : "black" for i=1:ne(graph)])
Example block output

where we use edges with red color to related pairs of matched vertices.


This page was generated using Literate.jl.

+\end{cases}\]

where label $\langle v, w \rangle$ is equivalent to $\langle w,v\rangle$.

Solving properties

Maximum matching

Configuration properties

max_matching = solve(problem, SizeMax())[]
5.0โ‚œ

The largest number of matching is 5, which means we have a perfect matching (vertices are all paired).

matching polynomial

The graph polynomial defined for the matching problem is known as the matching polynomial. Here, we adopt the first definition in the wiki page.

\[M(G, x) = \sum\limits_{k=1}^{|V|/2} c_k x^k,\]

where $k$ is the number of matches, and coefficients $c_k$ are the corresponding counting.

matching_poly = solve(problem, GraphPolynomial())[]
1 + 15∙x + 75∙x2 + 145∙x3 + 90∙x4 + 6∙x5

Configuration properties

one of the perfect matches
match_config = solve(problem, SingleConfigMax())[]
(5.0, ConfigSampler{15, 1, 1}(010011000001001))โ‚œ

Let us show the result by coloring the matched edges to red

show_graph(graph; locs=locations, format=:svg, edge_colors=
+    [isone(match_config.c.data[i]) ? "red" : "black" for i=1:ne(graph)])
Example block output

where we use edges with red color to related pairs of matched vertices.


This page was generated using Literate.jl.

diff --git a/dev/generated/IndependentSet/c267cbc2.svg b/dev/generated/MaxCut/97eceb8a.svg similarity index 90% rename from dev/generated/IndependentSet/c267cbc2.svg rename to dev/generated/MaxCut/97eceb8a.svg index 9f969932..01739a34 100644 --- a/dev/generated/IndependentSet/c267cbc2.svg +++ b/dev/generated/MaxCut/97eceb8a.svg @@ -2,42 +2,42 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -54,46 +54,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaxCut/5e9d8cc7.svg b/dev/generated/MaxCut/bfcbaa5b.svg similarity index 95% rename from dev/generated/MaxCut/5e9d8cc7.svg rename to dev/generated/MaxCut/bfcbaa5b.svg index 10de2853..2971429a 100644 --- a/dev/generated/MaxCut/5e9d8cc7.svg +++ b/dev/generated/MaxCut/bfcbaa5b.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaxCut/index.html b/dev/generated/MaxCut/index.html index 8efdd0db..0feb481b 100644 --- a/dev/generated/MaxCut/index.html +++ b/dev/generated/MaxCut/index.html @@ -3,7 +3,7 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We define the cutting problem as

problem = MaxCut(graph);

Theory (can skip)

We associated a vertex $v\in V$ with a boolean degree of freedom $s_v\in\{0, 1\}$. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge $(i,j)\in E$ to an edge matrix labelled by $s_i$ and $s_j$

\[B(x_i, x_j, w_{ij}) = \left(\begin{matrix} +show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We define the cutting problem as

problem = MaxCut(graph);

Theory (can skip)

We associated a vertex $v\in V$ with a boolean degree of freedom $s_v\in\{0, 1\}$. Then the maximum cutting problem can be encoded to tensor networks by mapping an edge $(i,j)\in E$ to an edge matrix labelled by $s_i$ and $s_j$

\[B(x_i, x_j, w_{ij}) = \left(\begin{matrix} 1 & x_{i}^{w_{ij}}\\ x_{j}^{w_{ij}} & 1 \end{matrix}\right),\]

where $w_{ij}$ is a real number associated with edge $(i, j)$ as the edge weight. If and only if the bipartition cuts on edge $(i, j)$, this tensor contributes a factor $x_{i}^{w_{ij}}$ or $x_{j}^{w_{ij}}$. Similarly, one can assign weights to vertices, which corresponds to the onsite energy terms in the spin glass. The vertex tensor is

\[W(x_i, w_i) = \left(\begin{matrix} @@ -12,4 +12,4 @@ \end{matrix}\right),\]

where $w_i$ is a real number associated with vertex $i$ as the vertex weight.

Its contraction time space complexity is $2^{{\rm tw}(G)}$, where ${\rm tw(G)}$ is the tree-width of $G$.

Solving properties

Maximum cut size $\gamma(G)$

max_cut_size = solve(problem, SizeMax())[]
12.0โ‚œ

Counting properties

graph polynomial

The graph polynomial defined for the cutting problem is

\[C(G, x) = \sum_{k=0}^{\gamma(G)} c_k x^k,\]

where $\gamma(G)$ is the maximum cut size, $c_k/2$ is the number of cuts of size $k$ in graph $G=(V,E)$. Since the variable $x$ is defined on edges, the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.

max_config = solve(problem, GraphPolynomial())[]
2 + 20∙x3 + 30∙x4 + 72∙x5 + 200∙x6 + 240∙x7 + 150∙x8 + 120∙x9 + 120∙x10 + 60∙x11 + 10∙x12

Configuration properties

finding one max cut solution
max_vertex_config = solve(problem, SingleConfigMax())[].c.data
 
 max_cut_size_verify = cut_size(graph, max_vertex_config)
0x000000000000000c

You should see a consistent result as above max_cut_size.

show_graph(graph; locs=locations, vertex_colors=[
-        iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
Example block output

where red vertices and white vertices are separated by the cut.


This page was generated using Literate.jl.

+ iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)Example block output

where red vertices and white vertices are separated by the cut.


This page was generated using Literate.jl.

diff --git a/dev/generated/IndependentSet/ef721240.svg b/dev/generated/MaximalIS/678e44d9.svg similarity index 95% rename from dev/generated/IndependentSet/ef721240.svg rename to dev/generated/MaximalIS/678e44d9.svg index c5311660..68685110 100644 --- a/dev/generated/IndependentSet/ef721240.svg +++ b/dev/generated/MaximalIS/678e44d9.svg @@ -2,42 +2,42 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaximalIS/8866adc8.svg b/dev/generated/MaximalIS/8866adc8.svg deleted file mode 100644 index ee1edc02..00000000 --- a/dev/generated/MaximalIS/8866adc8.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/generated/MaximalIS/7a34fe75.svg b/dev/generated/MaximalIS/dded1bba.svg similarity index 76% rename from dev/generated/MaximalIS/7a34fe75.svg rename to dev/generated/MaximalIS/dded1bba.svg index aaecc0ce..c4c508f7 100644 --- a/dev/generated/MaximalIS/7a34fe75.svg +++ b/dev/generated/MaximalIS/dded1bba.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -110,46 +110,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -168,44 +168,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -224,44 +224,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -280,44 +280,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -334,46 +334,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -392,44 +392,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -446,46 +446,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -504,44 +504,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -558,46 +558,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -616,44 +616,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -670,46 +670,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -726,46 +726,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -784,44 +784,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -840,44 +840,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaximalIS/1b3e25d4.svg b/dev/generated/MaximalIS/f9ff3e5a.svg similarity index 79% rename from dev/generated/MaximalIS/1b3e25d4.svg rename to dev/generated/MaximalIS/f9ff3e5a.svg index fca5240e..b18bf5ba 100644 --- a/dev/generated/MaximalIS/1b3e25d4.svg +++ b/dev/generated/MaximalIS/f9ff3e5a.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -110,46 +110,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -168,44 +168,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -224,44 +224,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -278,46 +278,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -336,44 +336,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -390,46 +390,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -448,44 +448,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -502,46 +502,46 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -560,44 +560,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/MaximalIS/index.html b/dev/generated/MaximalIS/index.html index 8a9a53bd..2198e11e 100644 --- a/dev/generated/MaximalIS/index.html +++ b/dev/generated/MaximalIS/index.html @@ -5,14 +5,14 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as

problem = MaximalIS(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on its neighborhood $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} +show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We can use MaximalIS to construct the tensor network for solving the maximal independent set problem as

problem = MaximalIS(graph; optimizer=TreeSA());

Theory (can skip)

Let $G=(V,E)$ be the target graph that we want to solve. The tensor network representation map a vertex $v\in V$ to a boolean degree of freedom $s_v\in\{0, 1\}$. We defined the restriction on its neighborhood $N(v)$:

\[T(x_v)_{s_1,s_2,\ldots,s_{|N(v)|},s_v} = \begin{cases} s_vx_v^{w_v} & s_1=s_2=\ldots=s_{|N(v)|}=0,\\ 1-s_v& \text{otherwise}. \end{cases}\]

The first case corresponds to all the neighborhood vertices of $v$ are not in $I_{m}$, then $v$ must be in $I_{m}$ and contribute a factor $x_{v}^{w_v}$, where $w_v$ is the weight of vertex $v$. Otherwise, if any of the neighboring vertices of $v$ is in $I_{m}$, $v$ must not be in $I_{m}$ by the independence requirement.

Its contraction time space complexity of a MaximalIS instance is no longer determined by the tree-width of the original graph $G$. It is often harder to contract this tensor network than to contract the one for regular independent set problem.

contraction_complexity(problem)
Time complexity: 2^11.011227255423254
 Space complexity: 2^8.0
 Read-write complexity: 2^11.129926933510392

Solving properties

Counting properties

maximal independence polynomial

The graph polynomial defined for the maximal independent set problem is

\[I_{\rm max}(G, x) = \sum_{k=0}^{\alpha(G)} b_k x^k,\]

where $b_k$ is the number of maximal independent sets of size $k$ in graph $G=(V, E)$.

maximal_indenpendence_polynomial = solve(problem, GraphPolynomial())[]
10∙x3 + 5∙x4

One can see the first several coefficients are 0, because it only counts the maximal independent sets, The minimum maximal independent set size is also known as the independent domination number. It can be computed with the SizeMin property:

independent_domination_number = solve(problem, SizeMin())[]
3.0โ‚œ

Similarly, we have its counting CountingMin:

counting_min_maximal_independent_set = solve(problem, CountingMin())[]
(3.0, 10.0)โ‚œ

Configuration properties

finding all maximal independent set
maximal_configs = solve(problem, ConfigsAll())[]
 
-all(c->is_maximal_independent_set(graph, c), maximal_configs)
true
show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)
Example block output

This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.

cliques = maximal_cliques(complement(graph))
15-element Vector{Vector{Int64}}:
+all(c->is_maximal_independent_set(graph, c), maximal_configs)
true
show_gallery(graph, (3, 5); locs=locations, vertex_configs=maximal_configs, format=:svg)
Example block output

This result should be consistent with that given by the Bron Kerbosch algorithm on the complement of Petersen graph.

cliques = maximal_cliques(complement(graph))
15-element Vector{Vector{Int64}}:
  [5, 6, 7, 3]
  [5, 6, 2]
  [5, 9, 2, 8]
@@ -29,4 +29,4 @@
  [1, 9, 8]
  [1, 3, 7]

For sparse graphs, the generic tensor network approach is usually much faster and memory efficient than the Bron Kerbosch algorithm.

finding minimum maximal independent set

It is the ConfigsMin property in the program.

minimum_maximal_configs = solve(problem, ConfigsMin())[].c
 
-show_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)
Example block output

Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+show_gallery(graph, (2, 5); locs=locations, vertex_configs=minimum_maximal_configs, format=:svg)Example block output

Similarly, if one is only interested in computing one of the minimum sets, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/PaintShop/d94cb6e0.svg b/dev/generated/PaintShop/3be843ef.svg similarity index 95% rename from dev/generated/PaintShop/d94cb6e0.svg rename to dev/generated/PaintShop/3be843ef.svg index 6dcd818a..0e5cbc57 100644 --- a/dev/generated/PaintShop/d94cb6e0.svg +++ b/dev/generated/PaintShop/3be843ef.svg @@ -2,34 +2,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -63,75 +63,75 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/dev/generated/PaintShop/251118e7.svg b/dev/generated/PaintShop/fe3874dd.svg similarity index 95% rename from dev/generated/PaintShop/251118e7.svg rename to dev/generated/PaintShop/fe3874dd.svg index 6f29c37b..a800afae 100644 --- a/dev/generated/PaintShop/251118e7.svg +++ b/dev/generated/PaintShop/fe3874dd.svg @@ -2,34 +2,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -63,75 +63,75 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/dev/generated/PaintShop/index.html b/dev/generated/PaintShop/index.html index 21c7a2b6..7b089c14 100644 --- a/dev/generated/PaintShop/index.html +++ b/dev/generated/PaintShop/index.html @@ -30,7 +30,7 @@ end show_graph(graph; locs=locations, texts=string.(sequence), format=:svg, edge_colors= - [sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)])Example block output

Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.

Generic tensor network representation

Let us construct the problem instance as bellow.

problem = PaintShop(sequence);

Theory (can skip)

Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car $c_i$ (the $i$-th character in our example) with a degree of freedom $s_{c_i} \in \{0, 1\}$, where we use $0$ to denote the first appearance of a car is colored red and $1$ to denote the first appearance of a car is colored blue. For each black edges $(i, i+1)$, we define an edge tensor labeled by $(s_{c_i}, s_{c_{i+1}})$ as follows: If both cars on this edge are their first or second appearance

\[B^{\rm parallel} = \left(\begin{matrix} + [sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)])Example block output

Vertices connected by blue edges must have different colors, and the goal becomes a min-cut problem defined on black edges.

Generic tensor network representation

Let us construct the problem instance as bellow.

problem = PaintShop(sequence);

Theory (can skip)

Type PaintShop can be used for constructing the tensor network with optimized contraction order for solving a binary paint shop problem. To obtain its tensor network representation, we associating car $c_i$ (the $i$-th character in our example) with a degree of freedom $s_{c_i} \in \{0, 1\}$, where we use $0$ to denote the first appearance of a car is colored red and $1$ to denote the first appearance of a car is colored blue. For each black edges $(i, i+1)$, we define an edge tensor labeled by $(s_{c_i}, s_{c_{i+1}})$ as follows: If both cars on this edge are their first or second appearance

\[B^{\rm parallel} = \left(\begin{matrix} x & 1 \\ 1 & x \\ \end{matrix}\right),\]

otherwise,

\[B^{\rm anti-parallel} = \left(\begin{matrix} @@ -40,4 +40,4 @@ show_graph(graph; locs=locations, format=:svg, texts=string.(sequence), edge_colors=[sequence[e.src] == sequence[e.dst] ? "blue" : "black" for e in edges(graph)], - vertex_colors=[isone(c) ? "red" : "black" for c in painting1], vertex_text_color="white")Example block output

Since we have different choices of initial color, the number of best solution is 2.

The following function will check the solution and return you the number of color switches

num_paint_shop_color_switch(sequence, painting1)
4

This page was generated using Literate.jl.

+ vertex_colors=[isone(c) ? "red" : "black" for c in painting1], vertex_text_color="white")Example block output

Since we have different choices of initial color, the number of best solution is 2.

The following function will check the solution and return you the number of color switches

num_paint_shop_color_switch(sequence, painting1)
4

This page was generated using Literate.jl.

diff --git a/dev/generated/Satisfiability/index.html b/dev/generated/Satisfiability/index.html index a9d005f5..f719905a 100644 --- a/dev/generated/Satisfiability/index.html +++ b/dev/generated/Satisfiability/index.html @@ -14,4 +14,4 @@ x & x \\ 1 & x \end{matrix}\right) -\end{matrix}\right).\]

There is only one entry $(s_x, s_y, s_z) = (1, 0, 1)$ that makes this clause unsatisfied.

Solving properties

Satisfiability and its counting

The size of a satisfiability problem is defined by the number of satisfiable clauses.

num_satisfiable = solve(problem, SizeMax())[]
4.0โ‚œ

The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.

num_satisfiable_count = solve(problem, GraphPolynomial())[]
12∙x2 + 56∙x3 + 60∙x4

Find one of the solutions

single_config = solve(problem, SingleConfigMax())[].c.data
0111011

One will see a bit vector printed. One can create an assignment and check the validity with the following statement:

satisfiable(cnf, Dict(zip(labels(problem), single_config)))
true

This page was generated using Literate.jl.

+\end{matrix}\right).\]

There is only one entry $(s_x, s_y, s_z) = (1, 0, 1)$ that makes this clause unsatisfied.

Solving properties

Satisfiability and its counting

The size of a satisfiability problem is defined by the number of satisfiable clauses.

num_satisfiable = solve(problem, SizeMax())[]
4.0โ‚œ

The GraphPolynomial of a satisfiability problem counts the number of solutions that k clauses satisfied.

num_satisfiable_count = solve(problem, GraphPolynomial())[]
12∙x2 + 56∙x3 + 60∙x4

Find one of the solutions

single_config = solve(problem, SingleConfigMax())[].c.data
0111111

One will see a bit vector printed. One can create an assignment and check the validity with the following statement:

satisfiable(cnf, Dict(zip(labels(problem), single_config)))
true

This page was generated using Literate.jl.

diff --git a/dev/generated/SetCovering/index.html b/dev/generated/SetCovering/index.html index b0ec5101..73d45af5 100644 --- a/dev/generated/SetCovering/index.html +++ b/dev/generated/SetCovering/index.html @@ -17,4 +17,4 @@ 1 & \text{otherwise}. \end{cases}\]

This tensor means if none of the sets containing element $a$ are included, then this configuration is forbidden, One can check the contraction time space complexity of a SetCovering instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.820178962415188
 Space complexity: 2^4.0
-Read-write complexity: 2^10.109830654278793

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set covering problem is defined as

\[P(S, x) = \sum_{k=0}^{|S|} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets.

covering_polynomial = solve(problem, GraphPolynomial())[]
2∙x4 + 11∙x5 + 13∙x6 + 6∙x7 + x8

The minimum number of sets that covering the set of elements can be computed with the SizeMin property:

min_cover_size = solve(problem, SizeMin())[]
4.0โ‚œ

Similarly, we have its counting CountingMin:

counting_minimum_setcovering = solve(problem, CountingMin())[]
(4.0, 2.0)โ‚œ

Configuration properties

Finding minimum set covering

One can enumerate all minimum set covering with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
{10101100, 01111000}

Hence the two optimal solutions are $\{z_1, z_3, z_5, z_6\}$ and $\{z_2, z_3, z_4, z_5\}$. The correctness of this result can be checked with the is_set_covering function.

all(c->is_set_covering(sets, c), min_configs)
true

Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

+Read-write complexity: 2^10.109830654278793

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set covering problem is defined as

\[P(S, x) = \sum_{k=0}^{|S|} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets.

covering_polynomial = solve(problem, GraphPolynomial())[]
2∙x4 + 11∙x5 + 13∙x6 + 6∙x7 + x8

The minimum number of sets that covering the set of elements can be computed with the SizeMin property:

min_cover_size = solve(problem, SizeMin())[]
4.0โ‚œ

Similarly, we have its counting CountingMin:

counting_minimum_setcovering = solve(problem, CountingMin())[]
(4.0, 2.0)โ‚œ

Configuration properties

Finding minimum set covering

One can enumerate all minimum set covering with the ConfigsMin property in the program.

min_configs = solve(problem, ConfigsMin())[].c
{10101100, 01111000}

Hence the two optimal solutions are $\{z_1, z_3, z_5, z_6\}$ and $\{z_2, z_3, z_4, z_5\}$. The correctness of this result can be checked with the is_set_covering function.

all(c->is_set_covering(sets, c), min_configs)
true

Similarly, if one is only interested in computing one of the minimum set coverings, one can use the graph property SingleConfigMin.


This page was generated using Literate.jl.

diff --git a/dev/generated/SetPacking/index.html b/dev/generated/SetPacking/index.html index a3baa68a..83cbe8cb 100644 --- a/dev/generated/SetPacking/index.html +++ b/dev/generated/SetPacking/index.html @@ -15,6 +15,6 @@ \end{matrix}\right)\]

where $x_s$ is a variable associated with $s$. For each unique element $a$, we defined the constraint over all sets containing it $N(a) = \{s | s \in S \land a\in s\}$:

\[B_{s_1,s_2,\ldots,s_{|N(a)|}} = \begin{cases} 0 & s_1+s_2+\ldots+s_{|N(a)|} > 1,\\ 1 & \text{otherwise}. -\end{cases}\]

This tensor means if in a configuration, two sets contain the element $a$, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.20945336562895
+\end{cases}\]

This tensor means if in a configuration, two sets contain the element $a$, then this configuration is forbidden, One can check the contraction time space complexity of a SetPacking instance by typing:

contraction_complexity(problem)
Time complexity: 2^8.169925001442312
 Space complexity: 2^4.0
-Read-write complexity: 2^9.090112419664289

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set packing problem is defined as

\[P(S, x) = \sum_{k=0}^{\alpha(S)} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets, and $\alpha(S)$ is the maximum size of the packing.

packing_polynomial = solve(problem, GraphPolynomial())[]
1 + 8∙x + 8∙x2 + x3

The maximum number of sets that packing the set of elements can be computed with the SizeMax property:

max_packing_size = solve(problem, SizeMax())[]
3.0โ‚œ

Similarly, we have its counting CountingMax:

counting_maximum_set_packing = solve(problem, CountingMax())[]
(3.0, 1.0)โ‚œ

Configuration properties

Finding maximum set packing

One can enumerate all maximum set packing with the ConfigsMax property in the program.

max_configs = solve(problem, ConfigsMax())[].c
{10100100}

Hence the only optimal solution is $\{z_1, z_3, z_6\}$ that has size 3. The correctness of this result can be checked with the is_set_packing function.

all(c->is_set_packing(sets, c), max_configs)
true

Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.


This page was generated using Literate.jl.

+Read-write complexity: 2^9.047123912114026

Solving properties

Counting properties

The "graph" polynomial

The graph polynomial for the set packing problem is defined as

\[P(S, x) = \sum_{k=0}^{\alpha(S)} c_k x^k,\]

where $c_k$ is the number of configurations having $k$ sets, and $\alpha(S)$ is the maximum size of the packing.

packing_polynomial = solve(problem, GraphPolynomial())[]
1 + 8∙x + 8∙x2 + x3

The maximum number of sets that packing the set of elements can be computed with the SizeMax property:

max_packing_size = solve(problem, SizeMax())[]
3.0โ‚œ

Similarly, we have its counting CountingMax:

counting_maximum_set_packing = solve(problem, CountingMax())[]
(3.0, 1.0)โ‚œ

Configuration properties

Finding maximum set packing

One can enumerate all maximum set packing with the ConfigsMax property in the program.

max_configs = solve(problem, ConfigsMax())[].c
{10100100}

Hence the only optimal solution is $\{z_1, z_3, z_6\}$ that has size 3. The correctness of this result can be checked with the is_set_packing function.

all(c->is_set_packing(sets, c), max_configs)
true

Similarly, if one is only interested in computing one of the maximum set packing, one can use the graph property SingleConfigMax.


This page was generated using Literate.jl.

diff --git a/dev/generated/SpinGlass/cd292e02.svg b/dev/generated/SpinGlass/726b1976.svg similarity index 90% rename from dev/generated/SpinGlass/cd292e02.svg rename to dev/generated/SpinGlass/726b1976.svg index 95142c76..c92cd514 100644 --- a/dev/generated/SpinGlass/cd292e02.svg +++ b/dev/generated/SpinGlass/726b1976.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/SpinGlass/e16052cb.svg b/dev/generated/SpinGlass/dc38b2b2.svg similarity index 95% rename from dev/generated/SpinGlass/e16052cb.svg rename to dev/generated/SpinGlass/dc38b2b2.svg index 55267c60..671a32ba 100644 --- a/dev/generated/SpinGlass/e16052cb.svg +++ b/dev/generated/SpinGlass/dc38b2b2.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/SpinGlass/index.html b/dev/generated/SpinGlass/index.html index ee98d4fc..d34a193e 100644 --- a/dev/generated/SpinGlass/index.html +++ b/dev/generated/SpinGlass/index.html @@ -3,7 +3,7 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] -show_graph(graph; locs=locations, format=:svg)Example block output

Generic tensor network representation

We define an anti-ferromagnetic spin glass problem as

problem = SpinGlass(graph; J=fill(-1, ne(graph)));

Theory (can skip)

The spin glass problem is reduced to the Cutting problem for solving. Let $G=(V,E)$ be a graph, the cutting problem can also be described by the following energy model

\[H^c = \sum_{ij \in E} C_{ij} ((1 - n_i) n_j + (1 - n_j) n_i) + \sum_{i \in V} w_i n_i,\]

where $n_i$ is the same as the partition index in the cutting problem, $C_{ij} = 2J_{ij}$ are edge weights and $w_i = -2h_i$ are vertex weights. The total energy is shifted by $-\sum_{ij\in E}J_{ij} + \sum_{i \in V} h_i$.

Solving properties

Minimum and maximum energies

Its ground state energy is -9.

Emin = solve(problem, SizeMin())[]
-9.0โ‚œ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
15.0โ‚œ

Counting properties

graph polynomial

The graph polynomial defined for the spin glass problem is a Laurent polynomial

\[Z(G, J, h, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

partition_function = solve(problem, GraphPolynomial())[]
10∙xโปโน + 60∙xโปโท + 120∙xโปโต + 120∙xโปยณ + 150∙xโปยน + 240∙x + 200∙xยณ + 72∙xโต + 30∙xโท + 20∙xโน + 2∙xยนโต

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
+show_graph(graph; locs=locations, format=:svg)
Example block output

Generic tensor network representation

We define an anti-ferromagnetic spin glass problem as

problem = SpinGlass(graph; J=fill(-1, ne(graph)));

Theory (can skip)

The spin glass problem is reduced to the Cutting problem for solving. Let $G=(V,E)$ be a graph, the cutting problem can also be described by the following energy model

\[H^c = \sum_{ij \in E} C_{ij} ((1 - n_i) n_j + (1 - n_j) n_i) + \sum_{i \in V} w_i n_i,\]

where $n_i$ is the same as the partition index in the cutting problem, $C_{ij} = 2J_{ij}$ are edge weights and $w_i = -2h_i$ are vertex weights. The total energy is shifted by $-\sum_{ij\in E}J_{ij} + \sum_{i \in V} h_i$.

Solving properties

Minimum and maximum energies

Its ground state energy is -9.

Emin = solve(problem, SizeMin())[]
-9.0โ‚œ

While the state correspond to the highest energy has the ferromagnetic order.

Emax = solve(problem, SizeMax())[]
15.0โ‚œ

Counting properties

graph polynomial

The graph polynomial defined for the spin glass problem is a Laurent polynomial

\[Z(G, J, h, x) = \sum_{k=E_{\rm min}}^{E_{\rm max}} c_k x^k,\]

where $E_{\rm min}$ and $E_{\rm max}$ are minimum and maximum energies, $c_k$ is the number of spin configurations with energy $k$. Let $x = e^\beta$, it corresponds to the partition function of a spin glass at temperature $\beta^{-1}$.

partition_function = solve(problem, GraphPolynomial())[]
10∙xโปโน + 60∙xโปโท + 120∙xโปโต + 120∙xโปยณ + 150∙xโปยน + 240∙x + 200∙xยณ + 72∙xโต + 30∙xโท + 20∙xโน + 2∙xยนโต

Configuration properties

finding a ground state
ground_state = solve(problem, SingleConfigMin())[].c.data
 
 Emin_verify = spinglass_energy(graph, ground_state)
9

You should see a consistent result as above Emin.

show_graph(graph; locs=locations, vertex_colors=[
-        iszero(ground_state[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)
Example block output

where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.


This page was generated using Literate.jl.

+ iszero(ground_state[i]) ? "white" : "red" for i=1:nv(graph)], format=:svg)Example block output

where a red vertex and a white vertex correspond to a spin having value 1 and 0 respectively.


This page was generated using Literate.jl.

diff --git a/dev/generated/open/index.html b/dev/generated/open/index.html index aefcc76d..0e913680 100644 --- a/dev/generated/open/index.html +++ b/dev/generated/open/index.html @@ -26,4 +26,4 @@ [:, :, 2] = 4.0โ‚œ -Infโ‚œ - 4.0โ‚œ -Infโ‚œ

One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.


This page was generated using Literate.jl.

+ 4.0โ‚œ -Infโ‚œ

One can easily check this one also gets the correct marginal on vertices 1, 2 and 3. As a reminder, their computational hardness can be different, because the contraction order optimization program can optimize over open degrees of freedom.


This page was generated using Literate.jl.

diff --git a/dev/generated/saveload/index.html b/dev/generated/saveload/index.html index 8702d9a6..ad4cec73 100644 --- a/dev/generated/saveload/index.html +++ b/dev/generated/saveload/index.html @@ -3,75 +3,49 @@ problem = IndependentSet(Graphs.smallgraph(:petersen)) -all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0000010000, 0000001000, 0000011000, 0100000000, 0100010000, 0001000000, 0001010000, 0001001000, 0001011000, 0101000000, 0101010000, 0000100000, 0000110000, 0000101000, 0000111000, 0100100000, 0100110000, 1000000000, 1000001000, 1001000000, 1001001000, 0000000010, 0100000010, 0000100010, 0100100010, 1000000010, 0000000100, 0000001100, 0100000100, 0001000100, 0001001100, 0101000100, 0000100100, 0000101100, 0100100100, 1000000100, 1000001100, 1001000100, 1001001100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000110, 0010000000, 0010010000, 0010001000, 0010011000, 0010100000, 0010110000, 0010101000, 0010111000, 1010000000, 1010001000, 0010000010, 0010100010, 1010000010, 0000000001, 0000010001, 0100000001, 0100010001, 0001000001, 0001010001, 0101000001, 0101010001, 1000000001, 1001000001, 0000000011, 0100000011, 1000000011, 0010000001, 0010010001, 1010000001, 0010000011, 1010000011}

The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.

filename = tempname()
+all_independent_sets = solve(problem, ConfigsAll())[]
{0000000000, 0100000000, 0010000000, 0000100000, 0100100000, 0010100000, 0000000001, 0100000001, 0010000001, 0000010000, 0100010000, 0010010000, 0000110000, 0100110000, 0010110000, 0000010001, 0100010001, 0010010001, 0000000010, 0100000010, 0010000010, 0000100010, 0100100010, 0010100010, 0000000011, 0100000011, 0010000011, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 0000001000, 0010001000, 0000101000, 0010101000, 0000011000, 0010011000, 0000111000, 0010111000, 1000001000, 1010001000, 0001000000, 0101000000, 0001000001, 0101000001, 0001010000, 0101010000, 0001010001, 0101010001, 1001000000, 1001000001, 0001001000, 0001011000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000100, 1000000110, 0000001100, 0000101100, 1000001100, 0001000100, 0101000100, 1001000100, 0001001100, 1001001100}

The return value has type ConfigEnumerator. We can use save_configs and load_configs to save and read a ConfigEnumerator instance to the disk.

filename = tempname()
 
 save_configs(filename, all_independent_sets; format=:binary)
 
-loaded_sets = load_configs(filename; format=:binary, bitlength=10)
{0000000000, 0000010000, 0000001000, 0000011000, 0100000000, 0100010000, 0001000000, 0001010000, 0001001000, 0001011000, 0101000000, 0101010000, 0000100000, 0000110000, 0000101000, 0000111000, 0100100000, 0100110000, 1000000000, 1000001000, 1001000000, 1001001000, 0000000010, 0100000010, 0000100010, 0100100010, 1000000010, 0000000100, 0000001100, 0100000100, 0001000100, 0001001100, 0101000100, 0000100100, 0000101100, 0100100100, 1000000100, 1000001100, 1001000100, 1001001100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000110, 0010000000, 0010010000, 0010001000, 0010011000, 0010100000, 0010110000, 0010101000, 0010111000, 1010000000, 1010001000, 0010000010, 0010100010, 1010000010, 0000000001, 0000010001, 0100000001, 0100010001, 0001000001, 0001010001, 0101000001, 0101010001, 1000000001, 1001000001, 0000000011, 0100000011, 1000000011, 0010000001, 0010010001, 1010000001, 0010000011, 1010000011}
Note

When loading the data in the binary format, bit string length information bitlength is required.

For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
+loaded_sets = load_configs(filename; format=:binary, bitlength=10)
{0000000000, 0100000000, 0010000000, 0000100000, 0100100000, 0010100000, 0000000001, 0100000001, 0010000001, 0000010000, 0100010000, 0010010000, 0000110000, 0100110000, 0010110000, 0000010001, 0100010001, 0010010001, 0000000010, 0100000010, 0010000010, 0000100010, 0100100010, 0010100010, 0000000011, 0100000011, 0010000011, 1000000000, 1010000000, 1000000001, 1010000001, 1000000010, 1010000010, 1000000011, 1010000011, 0000001000, 0010001000, 0000101000, 0010101000, 0000011000, 0010011000, 0000111000, 0010111000, 1000001000, 1010001000, 0001000000, 0101000000, 0001000001, 0101000001, 0001010000, 0101010000, 0001010001, 0101010001, 1001000000, 1001000001, 0001001000, 0001011000, 1001001000, 0000000100, 0100000100, 0000100100, 0100100100, 0000000110, 0100000110, 0000100110, 0100100110, 1000000100, 1000000110, 0000001100, 0000101100, 1000001100, 0001000100, 0101000100, 1001000100, 0001001100, 1001001100}
Note

When loading the data in the binary format, bit string length information bitlength is required.

For the SumProductTree type output, we can use save_sumproduct and load_sumproduct to save and load serialized data.

all_independent_sets_tree = solve(problem, ConfigsAll(; tree_storage=true))[]
 
 save_sumproduct(filename, all_independent_sets_tree)
 
 loaded_sets_tree = load_sumproduct(filename)
+ (count = 76.0)
-โ”œโ”€ + (count = 71.0)
-โ”‚  โ”œโ”€ + (count = 58.0)
-โ”‚  โ”‚  โ”œโ”€ + (count = 45.0)
-โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 27.0)
-โ”‚  โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 26.0)
+โ”œโ”€ + (count = 75.0)
+โ”‚  โ”œโ”€ + (count = 74.0)
+โ”‚  โ”‚  โ”œโ”€ + (count = 73.0)
+โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 71.0)
+โ”‚  โ”‚  โ”‚  โ”‚  โ”œโ”€ + (count = 70.0)
 โ”‚  โ”‚  โ”‚  โ”‚  โ”‚  โ‹ฎ
 โ”‚  โ”‚  โ”‚  โ”‚  โ”‚  
 โ”‚  โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 1.0)
 โ”‚  โ”‚  โ”‚  โ”‚     โ‹ฎ
 โ”‚  โ”‚  โ”‚  โ”‚     
-โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 18.0)
-โ”‚  โ”‚  โ”‚     โ”œโ”€ + (count = 18.0)
+โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 2.0)
+โ”‚  โ”‚  โ”‚     โ”œโ”€ + (count = 2.0)
 โ”‚  โ”‚  โ”‚     โ”‚  โ‹ฎ
 โ”‚  โ”‚  โ”‚     โ”‚  
-โ”‚  โ”‚  โ”‚     โ””โ”€ OnehotVec{10, 2}(8, 1)
-โ”‚  โ”‚  โ””โ”€ + (count = 13.0)
-โ”‚  โ”‚     โ”œโ”€ + (count = 12.0)
-โ”‚  โ”‚     โ”‚  โ”œโ”€ + (count = 10.0)
-โ”‚  โ”‚     โ”‚  โ”‚  โ‹ฎ
-โ”‚  โ”‚     โ”‚  โ”‚  
-โ”‚  โ”‚     โ”‚  โ””โ”€ * (count = 2.0)
-โ”‚  โ”‚     โ”‚     โ‹ฎ
-โ”‚  โ”‚     โ”‚     
+โ”‚  โ”‚  โ”‚     โ””โ”€ * (count = 1.0)
+โ”‚  โ”‚  โ”‚        โ‹ฎ
+โ”‚  โ”‚  โ”‚        
+โ”‚  โ”‚  โ””โ”€ * (count = 1.0)
+โ”‚  โ”‚     โ”œโ”€ OnehotVec{10, 2}(1, 1)
 โ”‚  โ”‚     โ””โ”€ * (count = 1.0)
-โ”‚  โ”‚        โ”œโ”€ OnehotVec{10, 2}(1, 1)
-โ”‚  โ”‚        โ””โ”€ * (count = 1.0)
-โ”‚  โ”‚           โ‹ฎ
-โ”‚  โ”‚           
-โ”‚  โ””โ”€ * (count = 13.0)
-โ”‚     โ”œโ”€ + (count = 13.0)
-โ”‚     โ”‚  โ”œโ”€ + (count = 12.0)
-โ”‚     โ”‚  โ”‚  โ”œโ”€ + (count = 10.0)
-โ”‚     โ”‚  โ”‚  โ”‚  โ‹ฎ
-โ”‚     โ”‚  โ”‚  โ”‚  
-โ”‚     โ”‚  โ”‚  โ””โ”€ + (count = 2.0)
-โ”‚     โ”‚  โ”‚     โ‹ฎ
-โ”‚     โ”‚  โ”‚     
-โ”‚     โ”‚  โ””โ”€ * (count = 1.0)
-โ”‚     โ”‚     โ”œโ”€ OnehotVec{10, 2}(1, 1)
-โ”‚     โ”‚     โ””โ”€ OnehotVec{10, 2}(9, 1)
-โ”‚     โ””โ”€ OnehotVec{10, 2}(10, 1)
-โ””โ”€ * (count = 5.0)
-   โ”œโ”€ + (count = 5.0)
-   โ”‚  โ”œโ”€ + (count = 4.0)
-   โ”‚  โ”‚  โ”œโ”€ + (count = 3.0)
-   โ”‚  โ”‚  โ”‚  โ”œโ”€ * (count = 2.0)
-   โ”‚  โ”‚  โ”‚  โ”‚  โ‹ฎ
-   โ”‚  โ”‚  โ”‚  โ”‚  
-   โ”‚  โ”‚  โ”‚  โ””โ”€ * (count = 1.0)
-   โ”‚  โ”‚  โ”‚     โ‹ฎ
-   โ”‚  โ”‚  โ”‚     
-   โ”‚  โ”‚  โ””โ”€ * (count = 1.0)
-   โ”‚  โ”‚     โ”œโ”€ OnehotVec{10, 2}(9, 1)
-   โ”‚  โ”‚     โ””โ”€ OnehotVec{10, 2}(3, 1)
-   โ”‚  โ””โ”€ * (count = 1.0)
-   โ”‚     โ”œโ”€ OnehotVec{10, 2}(1, 1)
-   โ”‚     โ””โ”€ * (count = 1.0)
-   โ”‚        โ”œโ”€ OnehotVec{10, 2}(9, 1)
-   โ”‚        โ””โ”€ OnehotVec{10, 2}(3, 1)
-   โ””โ”€ OnehotVec{10, 2}(10, 1)
+โ”‚  โ”‚        โ”œโ”€ OnehotVec{10, 2}(4, 1)
+โ”‚  โ”‚        โ””โ”€ OnehotVec{10, 2}(8, 1)
+โ”‚  โ””โ”€ * (count = 1.0)
+โ”‚     โ”œโ”€ OnehotVec{10, 2}(4, 1)
+โ”‚     โ””โ”€ * (count = 1.0)
+โ”‚        โ”œโ”€ OnehotVec{10, 2}(7, 1)
+โ”‚        โ””โ”€ OnehotVec{10, 2}(8, 1)
+โ””โ”€ * (count = 1.0)
+   โ”œโ”€ OnehotVec{10, 2}(1, 1)
+   โ””โ”€ * (count = 1.0)
+      โ”œโ”€ OnehotVec{10, 2}(4, 1)
+      โ””โ”€ * (count = 1.0)
+         โ”œโ”€ OnehotVec{10, 2}(7, 1)
+         โ””โ”€ OnehotVec{10, 2}(8, 1)
 

Loading solutions to python

The following python script loads and unpacks the solutions as a numpy array from a :binary format file.

import numpy as np
 
 def loadfile(filename:str, bitlength:int):
@@ -83,4 +57,4 @@
     print("number of solutions = %d"%(len(res)))
     return res  # in big endian format
 
-res = loadfile(filename, 10)
Note

Check section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:


This page was generated using Literate.jl.

+res = loadfile(filename, 10)
Note

Check section Maximal independent set problem for solution space properties related the maximal independent sets. That example also contains using cases of finding solution space properties related to minimum sizes:


This page was generated using Literate.jl.

diff --git a/dev/generated/weighted/f1011ec4.svg b/dev/generated/weighted/273e3eea.svg similarity index 86% rename from dev/generated/weighted/f1011ec4.svg rename to dev/generated/weighted/273e3eea.svg index 495e696d..5a75e727 100644 --- a/dev/generated/weighted/f1011ec4.svg +++ b/dev/generated/weighted/273e3eea.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -112,44 +112,44 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + @@ -168,44 +168,44 @@ - + - + - + - + - + - + - + - + - + - - + + @@ -224,44 +224,44 @@ - + - + - + - + - + - + - + - + - + - - + + @@ -280,44 +280,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/weighted/9d336146.svg b/dev/generated/weighted/b95f3e0a.svg similarity index 95% rename from dev/generated/weighted/9d336146.svg rename to dev/generated/weighted/b95f3e0a.svg index 49ba98c0..7f9973c8 100644 --- a/dev/generated/weighted/9d336146.svg +++ b/dev/generated/weighted/b95f3e0a.svg @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -56,44 +56,44 @@ - + - + - + - + - + - + - + - + - + - - + + diff --git a/dev/generated/weighted/index.html b/dev/generated/weighted/index.html index 4b1edbca..fa8bd850 100644 --- a/dev/generated/weighted/index.html +++ b/dev/generated/weighted/index.html @@ -6,7 +6,7 @@ locations = [[rot15(0.0, 2.0, i) for i=0:4]..., [rot15(0.0, 1.0, i) for i=0:4]...] show_graph(graph; locs=locations, format=:svg, vertex_colors= - [iszero(max_config_weighted.c.data[i]) ? "white" : "red" for i=1:nv(graph)])Example block output

The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.

For the weighted MIS problem, a useful solution space property is the "energy spectrum", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.

spectrum = solve(problem, SizeMax(10))[]
ExtendedTropical{10, Tropical{Float64}}(Tropical{Float64}[20.0โ‚œ, 20.0โ‚œ, 20.0โ‚œ, 21.0โ‚œ, 21.0โ‚œ, 22.0โ‚œ, 22.0โ‚œ, 22.0โ‚œ, 23.0โ‚œ, 24.0โ‚œ])

The return value has type ExtendedTropical, which contains one field orders.

spectrum.orders
10-element Vector{Tropical{Float64}}:
+          [iszero(max_config_weighted.c.data[i]) ? "white" : "red" for i=1:nv(graph)])
Example block output

The only solution space property that can not be defined for general real-weighted (not including integer-weighted) graphs is the GraphPolynomial.

For the weighted MIS problem, a useful solution space property is the "energy spectrum", i.e. the largest several configurations and their weights. We can use the solution space property is SizeMax(10) to compute the largest 10 weights.

spectrum = solve(problem, SizeMax(10))[]
ExtendedTropical{10, Tropical{Float64}}(Tropical{Float64}[20.0โ‚œ, 20.0โ‚œ, 20.0โ‚œ, 21.0โ‚œ, 21.0โ‚œ, 22.0โ‚œ, 22.0โ‚œ, 22.0โ‚œ, 23.0โ‚œ, 24.0โ‚œ])

The return value has type ExtendedTropical, which contains one field orders.

spectrum.orders
10-element Vector{Tropical{Float64}}:
  20.0โ‚œ
  20.0โ‚œ
  20.0โ‚œ
@@ -16,9 +16,9 @@
  22.0โ‚œ
  22.0โ‚œ
  23.0โ‚œ
- 24.0โ‚œ

We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.

max5_configs = solve(problem, SingleConfigMax(5))[]
ExtendedTropical{5, CountingTropical{Float64, ConfigSampler{10, 1, 1}}}(CountingTropical{Float64, ConfigSampler{10, 1, 1}}[(22.0, ConfigSampler{10, 1, 1}(0000100110))โ‚œ, (22.0, ConfigSampler{10, 1, 1}(0101010001))โ‚œ, (22.0, ConfigSampler{10, 1, 1}(0010000011))โ‚œ, (23.0, ConfigSampler{10, 1, 1}(1010000011))โ‚œ, (24.0, ConfigSampler{10, 1, 1}(0100100110))โ‚œ])

The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.

max5_configs.orders
5-element Vector{CountingTropical{Float64, ConfigSampler{10, 1, 1}}}:
- (22.0, ConfigSampler{10, 1, 1}(0000100110))โ‚œ
+ 24.0โ‚œ

We can see the order is a vector of Tropical numbers. Similarly, we can get weighted independent sets with maximum 5 sizes as follows.

max5_configs = solve(problem, SingleConfigMax(5))[]
ExtendedTropical{5, CountingTropical{Float64, ConfigSampler{10, 1, 1}}}(CountingTropical{Float64, ConfigSampler{10, 1, 1}}[(22.0, ConfigSampler{10, 1, 1}(0101010001))โ‚œ, (22.0, ConfigSampler{10, 1, 1}(0000100110))โ‚œ, (22.0, ConfigSampler{10, 1, 1}(0010000011))โ‚œ, (23.0, ConfigSampler{10, 1, 1}(1010000011))โ‚œ, (24.0, ConfigSampler{10, 1, 1}(0100100110))โ‚œ])

The return value also has type ExtendedTropical, but this time the element type of orders has been changed to CountingTropical{Float64,ConfigSampler}.

max5_configs.orders
5-element Vector{CountingTropical{Float64, ConfigSampler{10, 1, 1}}}:
  (22.0, ConfigSampler{10, 1, 1}(0101010001))โ‚œ
+ (22.0, ConfigSampler{10, 1, 1}(0000100110))โ‚œ
  (22.0, ConfigSampler{10, 1, 1}(0010000011))โ‚œ
  (23.0, ConfigSampler{10, 1, 1}(1010000011))โ‚œ
- (24.0, ConfigSampler{10, 1, 1}(0100100110))โ‚œ

Let us visually check these configurations

show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])
Example block output

This page was generated using Literate.jl.

+ (24.0, ConfigSampler{10, 1, 1}(0100100110))โ‚œ

Let us visually check these configurations

show_gallery(graph, (1, 5); locs=locations, format=:svg, vertex_configs=[max5_configs.orders[k].c.data for k=1:5])
Example block output

This page was generated using Literate.jl.

diff --git a/dev/gist/index.html b/dev/gist/index.html index 96915d02..9cd9b7d1 100644 --- a/dev/gist/index.html +++ b/dev/gist/index.html @@ -112,4 +112,4 @@ println("one of the optimal configurations is $(mis_config(optimized_code; all=false)[].c.data)") # direct enumeration of configurations can be very slow; please check the bounding version in our Github repo. -println("all optimal configurations are $(mis_config(optimized_code; all=true)[].c)") +println("all optimal configurations are $(mis_config(optimized_code; all=true)[].c)") diff --git a/dev/index.html b/dev/index.html index 2acc3a88..0bbc5269 100644 --- a/dev/index.html +++ b/dev/index.html @@ -17,4 +17,4 @@ 0-dimensional Array{Polynomial{BigInt, :x}, 0}: Polynomial(1 + 20*x + 160*x^2 + 659*x^3 + 1500*x^4 + 1883*x^5 + 1223*x^6 + 347*x^7 + 25*x^8)

Here the main function solve takes three input arguments, the problem instance of type IndependentSet, the property instance of type GraphPolynomial and an optional key word argument usecuda to decide use GPU or not. If one wants to use GPU to accelerate the computation, the using CUDA statement must uncommented.

The problem instance takes four arguments to initialize, the only positional argument is the graph instance that one wants to solve, the key word argument optimizer is for specifying the tensor network optimization algorithm, the key word argument weights is for specifying the weights of vertices as either a vector or NoWeight(). The keyword argument openvertices is a tuple of labels for specifying the degrees of freedom not summed over, and fixedvertices is a label-value dictionary for specifying the fixed values of the degree of freedoms. Here, we use TreeSA method as the tensor network optimizer, and leave weights and openvertices the default values. The TreeSA method finds the best contraction order in most of our applications, while the default GreedyMethod runs the fastest.

The first execution of this function will be a bit slow due to Julia's just in time compiling. The subsequent runs will be fast. The following diagram lists possible combinations of input arguments, where functions in the Graph are mainly defined in the package Graphs, and the rest can be found in this package.

-

โ € You can find many examples in this documentation, a good one to start with is Independent set problem.

+

โ € You can find many examples in this documentation, a good one to start with is Independent set problem.

diff --git a/dev/performancetips/index.html b/dev/performancetips/index.html index b1611ad1..9485fab0 100644 --- a/dev/performancetips/index.html +++ b/dev/performancetips/index.html @@ -80,4 +80,4 @@ julia> solve(problem, SizeMax(), usecuda=true) 0-dimensional CuArray{TropicalF64, 0, CUDA.Mem.DeviceBuffer}: -53.0โ‚œ

Solution space properties computable on GPU includes

Benchmarks

We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.

benchmark-independent-set This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.

The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than $|V|/6$. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.

Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than $2^{27}$ (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only $\sim150$ on a device with 32GB main memory.

We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs

benchmark-maximal-independent-set

In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.

Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.

+53.0โ‚œ

Solution space properties computable on GPU includes

Benchmarks

We run a single thread benchmark on central processing units (CPU) Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz, and its CUDA version on a GPU Tesla V100-SXM2 16G. The results are summarized in the following plot. The benchmark code can be found in our paper repository.

benchmark-independent-set This benchmark results is for computing different solution space properties of independent sets of random three-regular graphs with different tensor element types. The time in these plots only includes tensor network contraction, without taking into account the contraction order finding and just-in-time compilation time. Legends are properties, algebra, and devices that we used in the computation; one can find the corresponding computed solution space property in Table 1 in the paper.

The graphs in all benchmarks are random three-regular graphs, which have treewidth that is asymptotically smaller than $|V|/6$. In this benchmark, we do not include traditional algorithms for finding the MIS sizes such as branching or dynamic programming. To the best of our knowledge, these algorithms are not suitable for computing most of the solution space properties mentioned in this paper. The main goal of this section is to show the relative computation time for calculating different solution space properties.

Panel (a) shows the time and space complexity of tensor network contraction for different graph sizes. The contraction order is obtained using the TreeSA algorithm that implemented in OMEinsumContractionOrders. If we assume our contraction-order finding program has found the optimal treewidth, which is very likely to be true, the space complexity is the same as the treewidth of the problem graph. Slicing technique has been used for graphs with space complexity greater than $2^{27}$ (above the yellow dashed line) to fit the computation into a 16GB memory. One can see that all the computation times in panels (b), (c), and (d) have a strong correlation with the predicted time and space complexity. While in panel (d), the computation time of configuration enumeration also strongly correlates with other factors such as the configuration space size. Among these benchmarks, computational tasks with data types real numbers, complex numbers, or Tropical numbers (CPU only) can utilize fast basic linear algebra subprograms (BLAS) functions. These tasks usually compute much faster than ones with other element types in the same category. Immutable data types with no reference to other values can be compiled to GPU devices that run much faster than CPUs in all cases when the problem scale is big enough. These data types do not include those defined in Polynomial, ConfigEnumerator, ExtendedTropical and SumProductTree or a data type containing them as a part. In panel (c), one can see the Fourier transformation-based method is the fastest in computing the independence polynomial, but it may suffer from round-off errors. The finite field (GF(p)) approach is the only method that does not have round-off errors and can be run on a GPU. In panel (d), one can see the technique to bound the enumeration space (see paper) improves the performance for more than one order of magnitude in enumerating the MISs. The bounding technique can also reduce the memory usage significantly, without which the largest computable graph size is only $\sim150$ on a device with 32GB main memory.

We show the benchmark of computing the maximal independent set properties on 3-regular graphs in the following plot, including a comparison to the Bron-Kerbosch algorithm from Julia package Graphs

benchmark-maximal-independent-set

In this plot, benchmarks of computing different solution space properties of the maximal independent sets (ISs) problem on random three regular graphs at different sizes.

Panel (a) shows the space and time complexities of tensor contraction, which are typically larger than those for the independent set problem. In panel (b), one can see counting maximal independent sets are much more efficient than enumerating them, while our generic tensor network approach runs slightly faster than the Bron-Kerbosch approach in enumerating all maximal independent sets.

diff --git a/dev/ref/index.html b/dev/ref/index.html index 12c165d7..e5e3c6f6 100644 --- a/dev/ref/index.html +++ b/dev/ref/index.html @@ -1,5 +1,5 @@ -References ยท GenericTensorNetworks.jl

References

Graph problems

GenericTensorNetworks.solve โ€” Function
solve(problem, property; usecuda=false, T=Float64)

Solving a certain property of a graph problem.

Positional Arguments

  • problem is the graph problem with tensor network information,

  • property is string specifying the task. Using the maximum independent set problem as an example, it can be one of

    • PartitionFunction() for computing the partition function,

    • SizeMax(k=Single) for finding maximum-$k$ set sizes,

    • SizeMin(k=Single) for finding minimum-$k$ set sizes,

    • CountingMax(k=Single) for counting configurations with maximum-$k$ sizes,

    • CountingMin(k=Single) for counting configurations with minimum-$k$ sizes,

    • CountingAll() for counting all configurations,

    • PartitionFunction() for counting all configurations,

    • GraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,

    • SingleConfigMax(k=Single; bounded=false) for finding one maximum-$k$ configuration for each size,

    • SingleConfigMin(k=Single; bounded=false) for finding one minimum-$k$ configuration for each size,

    • ConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-$k$ sizes,

    • ConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-$k$ sizes,

    • ConfigsAll(; tree_storage=false) for enumerating all configurations,

Keyword arguments

  • usecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.
  • T is the "base" element type, sometimes can be used to reduce the memory cost.
source
GenericTensorNetworks.IndependentSet โ€” Type
IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+References ยท GenericTensorNetworks.jl

References

Graph problems

GenericTensorNetworks.solve โ€” Function
solve(problem, property; usecuda=false, T=Float64)

Solving a certain property of a graph problem.

Positional Arguments

  • problem is the graph problem with tensor network information,

  • property is string specifying the task. Using the maximum independent set problem as an example, it can be one of

    • PartitionFunction() for computing the partition function,

    • SizeMax(k=Single) for finding maximum-$k$ set sizes,

    • SizeMin(k=Single) for finding minimum-$k$ set sizes,

    • CountingMax(k=Single) for counting configurations with maximum-$k$ sizes,

    • CountingMin(k=Single) for counting configurations with minimum-$k$ sizes,

    • CountingAll() for counting all configurations,

    • PartitionFunction() for counting all configurations,

    • GraphPolynomial(; method=:finitefield, kwargs...) for evaluating the graph polynomial,

    • SingleConfigMax(k=Single; bounded=false) for finding one maximum-$k$ configuration for each size,

    • SingleConfigMin(k=Single; bounded=false) for finding one minimum-$k$ configuration for each size,

    • ConfigsMax(k=Single; bounded=true, tree_storage=false) for enumerating configurations with maximum-$k$ sizes,

    • ConfigsMin(k=Single; bounded=true, tree_storage=false) for enumerating configurations with minimum-$k$ sizes,

    • ConfigsAll(; tree_storage=false) for enumerating all configurations,

Keyword arguments

  • usecuda is a switch to use CUDA (if possible), user need to call statement using CUDA before turning on this switch.
  • T is the "base" element type, sometimes can be used to reduce the memory cost.
source
GenericTensorNetworks.IndependentSet โ€” Type
IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 IndependentSet(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -9,32 +9,32 @@
 
 julia> solve(problem, ConfigsMax())
 0-dimensional Array{CountingTropical{Float64, ConfigEnumerator{10, 1, 1}}, 0}:
-(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})โ‚œ
source
GenericTensorNetworks.MaximalIS โ€” Type
MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+(4.0, {0101010001, 1010000011, 0100100110, 0010111000, 1001001100})โ‚œ
source
GenericTensorNetworks.MaximalIS โ€” Type
MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 MaximalIS(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The maximal independent set problem. In the constructor, weights are the weights of vertices.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.Matching โ€” Type
Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem
+    )

The maximal independent set problem. In the constructor, weights are the weights of vertices.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.Matching โ€” Type
Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem
 Matching(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The Vertex matching problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.Coloring โ€” Type
Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem
+    )

The Vertex matching problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on edges, where a value can be 0 (not matched) or 1 (mathced).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.Coloring โ€” Type
Coloring{K,CT<:AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem
 Coloring{K}(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The Vertex Coloring problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in $0,...,K-1$ (different colors).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.DominatingSet โ€” Type
DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
+    )

The Vertex Coloring problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the edges of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be in $0,...,K-1$ (different colors).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.DominatingSet โ€” Type
DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 DominatingSet(graph; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The dominating set problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.SpinGlass โ€” Type
SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem
+    )

The dominating set problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms on vertices, where a value can be 0 (absent in the set) or 1 (present in the set).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.SpinGlass โ€” Type
SpinGlass{TT<:MaxCut,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: ReducedProblem
 SpinGlass(graph; J=NoWeight(), h=ZeroWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
     )
-SpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)

The spin glass problem (or cutting problem). In the output, the spin โ†‘ is mapped to configuration 0, while spin โ†“ is mapped to configuration 1.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • M is a symmetric matrix of the coupling strengths.
  • J is a vector of coupling strengths associated with the edges of the graph.
  • h is a vector of onsite energy terms associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.HyperSpinGlass โ€” Type
struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem

The hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.

Positional arguments

  • n is the number of spins.
  • cliques is a vector of cliques, each being a vector of vertices (integers).

Keyword arguments

  • weights are associated with the cliques.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MaxCut โ€” Type
MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem
+SpinGlass(M::AbstractMatrix, h::AbstractVector; kwargs...)

The spin glass problem (or cutting problem). In the output, the spin โ†‘ is mapped to configuration 0, while spin โ†“ is mapped to configuration 1.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • M is a symmetric matrix of the coupling strengths.
  • J is a vector of coupling strengths associated with the edges of the graph.
  • h is a vector of onsite energy terms associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.HyperSpinGlass โ€” Type
struct HyperSpinGlass{CT<:OMEinsum.AbstractEinsum, WT<:Union{NoWeight, Vector}} <: GraphProblem

The hyper-spin-glass problem is a generalization of the spin-glass problem to hypergraphs.

Positional arguments

  • n is the number of spins.
  • cliques is a vector of cliques, each being a vector of vertices (integers).

Keyword arguments

  • weights are associated with the cliques.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.MaxCut โ€” Type
MaxCut{CT<:AbstractEinsum,WT1<:Union{NoWeight, Vector},WT2<:Union{ZeroWeight, Vector}} <: GraphProblem
 MaxCut(graph; edge_weights=NoWeight(), vertex_weights=ZeroWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
-    )

The cutting problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • edge_weights are associated with the edges of the graph.
  • vertex_weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.PaintShop โ€” Type
PaintShop{CT<:AbstractEinsum} <: GraphProblem
+    )

The cutting problem.

Positional arguments

  • graph is the problem graph.

Keyword arguments

  • edge_weights are associated with the edges of the graph.
  • vertex_weights are associated with the vertices of the graph.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of degree of freedoms, where a value can be 0 (in one side of the cut) or 1 (in the other side of the cut).
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.
source
GenericTensorNetworks.PaintShop โ€” Type
PaintShop{CT<:AbstractEinsum} <: GraphProblem
 PaintShop(sequence::AbstractVector; openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -48,7 +48,7 @@
 julia> solve(pb, ConfigsMin())[].c.data
 2-element Vector{StaticBitVector{3, 1}}:
  100
- 011

In our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two "colors" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.

source
GenericTensorNetworks.Satisfiability โ€” Type
Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem
+ 011

In our definition, we find the maximum number of unchanged color in this sequence, i.e. (n-1) - (minimum number of color changes) In the output of maximum configurations, the two configurations are defined on 5 bonds i.e. pairs of (i, i+1), 0 means color changed, while 1 means color not changed. If we denote two "colors" as r and b, then the optimal painting is rbbbrr or brrrbb, both change the colors twice.

source
GenericTensorNetworks.Satisfiability โ€” Type
Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: GraphProblem
 Satisfiability(cnf::CNF; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -72,7 +72,7 @@
 julia> gp = Satisfiability(cnf);
 
 julia> solve(gp, SizeMax())[]
-4.0โ‚œ
source
GenericTensorNetworks.SetCovering โ€” Type
SetCovering{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 SetCovering(sets; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -81,7 +81,7 @@
 julia> gp = SetCovering(sets);
 
 julia> res = solve(gp, ConfigsMin())[]
-(3.0, {10110, 10101})โ‚œ
source
GenericTensorNetworks.SetPacking โ€” Type
SetPacking{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
 SetPacking(sets; weights=NoWeight(), openvertices=(),
         optimizer=GreedyMethod(), simplifier=nothing,
         fixedvertices=Dict()
@@ -90,7 +90,7 @@
 julia> gp = SetPacking(sets);
 
 julia> res = solve(gp, ConfigsMax())[]
-(2.0, {00110, 10010, 01100})โ‚œ
source
GenericTensorNetworks.OpenPitMining โ€” Type
OpenPitMining{ET, CT<:AbstractEinsum} <: GraphProblem
 OpenPitMining(rewards; openvertices=(),
              optimizer=GreedyMethod(), simplifier=nothing,
              fixedvertices=Dict())

The open pit mining problem. This problem can be solved in polynomial time with the pseudoflow algorithm.

Positional arguments

  • rewards is a matrix of rewards.

Keyword arguments

  • openvertices specifies labels of the output tensor.
  • optimizer and simplifier are for tensor network optimization, check optimize_code for details.
  • fixedvertices is a dict to specify the values of labels, where a value can be 0 (not mined) or 1 (mined)
  • openvertices is a tuple of labels to specify the output tensor. Theses degree of freedoms will not be contracted.

Example

julia> rewards =  [-4  -7  -7  -17  -7  -26;
@@ -114,7 +114,7 @@
       โ—ผ       โ—ผ       1       8       โ—ผ       โ—ผ 
       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ 
       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ 
-      โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ

You will the the mining is printed as green in an colored REPL.

source

Graph Problem Interfaces

To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.

GenericTensorNetworks.generate_tensors โ€” Function
generate_tensors(func, problem::GraphProblem)

Generate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.

Example

The following code gives your the maximum independent set size

julia> using Graphs, GenericTensorNetworks
+      โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ       โ—ผ

You will the the mining is printed as green in an colored REPL.

source

Graph Problem Interfaces

To subtype GraphProblem, a new type must contain a code field to represent the (optimized) tensor network. Interfaces GenericTensorNetworks.generate_tensors, labels, flavors and get_weights are required. nflavor is optional.

GenericTensorNetworks.generate_tensors โ€” Function
generate_tensors(func, problem::GraphProblem)

Generate a vector of tensors as the inputs of the tensor network contraction code problem.code. func is a function to customize the tensors. func(symbol) returns a vector of elements, the length of which is same as the number of flavors.

Example

The following code gives your the maximum independent set size

julia> using Graphs, GenericTensorNetworks
 
 julia> gp = IndependentSet(smallgraph(:petersen));
 
@@ -143,10 +143,10 @@
 
 julia> gp.code(GenericTensorNetworks.generate_tensors(Tropical(1.0), gp)...)
 0-dimensional Array{Tropical{Float64}, 0}:
-4.0โ‚œ
source
GenericTensorNetworks.labels โ€” Function
labels(problem::GraphProblem) -> Vector

The labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.

source
GenericTensorNetworks.terms โ€” Function
terms(problem::GraphProblem) -> Vector

The terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.

source
GenericTensorNetworks.flavors โ€” Function
flavors(::Type{<:GraphProblem}) -> Vector

It returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.

source
GenericTensorNetworks.get_weights โ€” Function
get_weights(problem::GraphProblem, i::Int) -> Vector
-get_weights(problem::GraphProblem) -> Vector

The weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.chweights โ€” Function
chweights(problem::GraphProblem, weights) -> GraphProblem

Change the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.fixedvertices โ€” Function
fixedvertices(problem::GraphProblem) -> Dict

Fix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.

source
GenericTensorNetworks.extract_result โ€” Function
extract_result(p::ReducedProblem, output)
-extract_result(p::ReducedProblem)

Post process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.

source

Graph Problem Utilities

GenericTensorNetworks.is_vertex_coloring โ€” Function
is_vertex_coloring(graph::SimpleGraph, config)

Returns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.

source
GenericTensorNetworks.is_matching โ€” Function
is_matching(graph::SimpleGraph, config)

Returns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).

source
GenericTensorNetworks.cut_size โ€” Function
cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())

Compute the cut size for the vertex configuration config (an iterator).

source
GenericTensorNetworks.spinglass_energy โ€” Function
spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())

Compute the spin glass state energy for the vertex configuration config. In the configuration, the spin โ†‘ is mapped to configuration 0, while spin โ†“ is mapped to configuration 1. Let $G=(V,E)$ be the input graph, the hamiltonian is

\[H = - \sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,\]

where $s_i \in \{-1, 1\}$ stands for spin โ†“ and spin โ†‘.

source
GenericTensorNetworks.paint_shop_coloring_from_config โ€” Function
paint_shop_coloring_from_config(p::PaintShop, config)

Returns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.

source
GenericTensorNetworks.mis_compactify! โ€” Function
mis_compactify!(tropicaltensor)

Compactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).

source
GenericTensorNetworks.labels โ€” Function
labels(problem::GraphProblem) -> Vector

The labels of a graph problem is defined as the degrees of freedoms in the graph problem. e.g. for the maximum independent set problems, they are the indices of vertices: 1, 2, 3..., while for the max cut problem, they are the edges.

source
GenericTensorNetworks.terms โ€” Function
terms(problem::GraphProblem) -> Vector

The terms of a graph problem is defined as the tensor labels that defining local energies (or weights) in the graph problem. e.g. for the maximum independent set problems, they are the vertex-tensor labels: [1], [2], [3]... The weight of a term is same as the exponents in the graph polynomial.

source
GenericTensorNetworks.flavors โ€” Function
flavors(::Type{<:GraphProblem}) -> Vector

It returns a vector of integers as the flavors of a degree of freedom. Its size is the same as the degree of freedom on a single vertex/edge.

source
GenericTensorNetworks.get_weights โ€” Function
get_weights(problem::GraphProblem, i::Int) -> Vector
+get_weights(problem::GraphProblem) -> Vector

The weights for the problem or the weights for the degree of freedom specified by the i-th term if a second argument is provided. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.chweights โ€” Function
chweights(problem::GraphProblem, weights) -> GraphProblem

Change the weights for the problem and return a new problem instance. Weights are associated with terms in the graph problem. In graph polynomial, integer weights can be the exponents.

source
GenericTensorNetworks.fixedvertices โ€” Function
fixedvertices(problem::GraphProblem) -> Dict

Fix degree of freedoms in a graph problem to a certain value using a dict, where the key is a label, and the value should be in, e.g. [0, 1] in the indepenent set problem. When a degree of freedom is fixed, its size is 1. The optimal tensor network contraction order is then different from the default case.

source
GenericTensorNetworks.extract_result โ€” Function
extract_result(p::ReducedProblem, output)
+extract_result(p::ReducedProblem)

Post process the output of the target problem to get an output to the source problem. If the output is not provided, it will return a function instead. The result extraction rule is determined by the output type. e.g. If the output type is Tropical, it will be interpreted as the energy. If the output is a Vector, it will be interpreted as a configuration.

source

Graph Problem Utilities

GenericTensorNetworks.is_vertex_coloring โ€” Function
is_vertex_coloring(graph::SimpleGraph, config)

Returns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.

source
GenericTensorNetworks.is_matching โ€” Function
is_matching(graph::SimpleGraph, config)

Returns true if config is a valid matching on graph, and false if a vertex is double matched. config is a vector of boolean variables, which has one to one correspondence with edges(graph).

source
GenericTensorNetworks.cut_size โ€” Function
cut_size(g::SimpleGraph, config; edge_weights=NoWeight(), vertex_weights=ZeroWeight())

Compute the cut size for the vertex configuration config (an iterator).

source
GenericTensorNetworks.spinglass_energy โ€” Function
spinglass_energy(g::SimpleGraph, config; J=NoWeight(), h=ZeroWeight())

Compute the spin glass state energy for the vertex configuration config. In the configuration, the spin โ†‘ is mapped to configuration 0, while spin โ†“ is mapped to configuration 1. Let $G=(V,E)$ be the input graph, the hamiltonian is

\[H = - \sum_{ij \in E} J_{ij} s_i s_j + \sum_{i \in V} h_i s_i,\]

where $s_i \in \{-1, 1\}$ stands for spin โ†“ and spin โ†‘.

source
GenericTensorNetworks.paint_shop_coloring_from_config โ€” Function
paint_shop_coloring_from_config(p::PaintShop, config)

Returns a valid painting from the paint shop configuration (given by the configuration solvers). The config is a sequence of 0 and 1, where 0 means painting the first appearence of a car in blue, 1 otherwise.

source
GenericTensorNetworks.mis_compactify! โ€” Function
mis_compactify!(tropicaltensor)

Compactify tropical tensor for maximum independent set problem. It will eliminate some entries by setting them to zero, by the criteria that removing these entry does not change the MIS size of its parent graph (reference to be added).

source
GenericTensorNetworks.CNF โ€” Type
CNF{T}
 CNF(clauses)

Boolean expression in conjunctive normal form. clauses is a vector of CNFClause, if and only if all clauses are satisfied, this CNF is satisfied.

Example

julia> @bools x y z
 
 julia> cnf = (x โˆจ y) โˆง (ยฌy โˆจ z)
@@ -156,23 +156,23 @@
 true
 
 julia> satisfiable(cnf, Dict([:x=>false, :y=>false, :z=>true]))
-false
source
GenericTensorNetworks.@bools โ€” Macro
@bools(syms::Symbol...)

Create some boolean variables of type BoolVar in current scope that can be used in create a CNF.

Example

julia> @bools x y z
 
 julia> (x โˆจ y) โˆง (ยฌy โˆจ z)
-(x โˆจ y) โˆง (ยฌy โˆจ z)
source

Properties

GenericTensorNetworks.PartitionFunction โ€” Type
struct PartitionFunction{T} <: GenericTensorNetworks.AbstractProperty
  • beta

Compute the partition function for the target problem.

  • The corresponding tensor element type is T.
source
GenericTensorNetworks.SizeMax โ€” Type
SizeMax{K} <: AbstractProperty
-SizeMax(k::Int)

The maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.

  • The corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.
  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.SizeMin โ€” Type
SizeMin{K} <: AbstractProperty
-SizeMin(k::Int)

The minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.

  • The corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.

The inverted Tropical number emulates the min-plus tropical number.

  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.CountingAll โ€” Type
CountingAll <: AbstractProperty
-CountingAll()

Counting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.

  • The corresponding tensor element type is Base.Real.
  • The weights on graph does not have effect.
  • BLAS (GPU and CPU) and GPU are supported,
source
GenericTensorNetworks.CountingMax โ€” Type
CountingMax{K} <: AbstractProperty
-CountingMax(K=Single)

Counting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.CountingMin โ€” Type
CountingMin{K} <: AbstractProperty
-CountingMin(K=Single)

Counting the number of sets with smallest-K size.

  • The corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.GraphPolynomial โ€” Type
GraphPolynomial{METHOD} <: AbstractProperty
-GraphPolynomial(; method=:finitefield, kwargs...)

Compute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols

Method Argument

  • :finitefield, uses finite field algebra to fit the polynomial.
    • The corresponding tensor element type is Mods.Mod,
    • It does not have round-off error,
    • GPU is supported,
    • It accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).
  • :polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.
    • The corresponding tensor element types are Polynomial and LaurentPolynomial.
    • It might have small round-off error depending on the data type for storing the counting.
    • It has memory overhead that linear to the graph size.
  • :fft, use fast fourier transformation to fit the polynomial.
    • The corresponding tensor element type is Base.Complex.
    • It has (controllable) round-off error.
    • BLAS and GPU are supported.
    • It accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.
  • :fitting, fit the polynomial directly.
    • The corresponding tensor element type is floating point numbers like Base.Float64.
    • It has round-off error.
    • BLAS and GPU are supported, it is the fastest among all methods.

Graph polynomials are not defined for weighted graph problems.

source
GenericTensorNetworks.SingleConfigMax โ€” Type
SingleConfigMax{K, BOUNDED} <: AbstractProperty
-SingleConfigMax(k::Int; bounded=false)

Finding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.SingleConfigMin โ€” Type
SingleConfigMin{K, BOUNDED} <: AbstractProperty
-SingleConfigMin(k::Int; bounded=false)

Finding single solution with smallest-K size.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.ConfigsAll โ€” Type
ConfigsAll{TREESTORAGE} <:AbstractProperty
-ConfigsAll(; tree_storage=false)

Find all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.

Keyword Arguments

  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMax โ€” Type
ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty
-ConfigsMax(K=Single; bounded=true, tree_storage=true)

Find configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMin โ€” Type
ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty
-ConfigsMin(K=Single; bounded=true, tree_storage=false)

Find configurations with smallest-K sizes.

  • The corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source

Element Algebras

GenericTensorNetworks.is_commutative_semiring โ€” Function
is_commutative_semiring(a::T, b::T, c::T) where T

Check if elements a, b and c satisfied the commutative semiring requirements.

\[\begin{align*} +(x โˆจ y) โˆง (ยฌy โˆจ z)

source

Properties

GenericTensorNetworks.PartitionFunction โ€” Type
struct PartitionFunction{T} <: GenericTensorNetworks.AbstractProperty
  • beta

Compute the partition function for the target problem.

  • The corresponding tensor element type is T.
source
GenericTensorNetworks.SizeMax โ€” Type
SizeMax{K} <: AbstractProperty
+SizeMax(k::Int)

The maximum-K set sizes. e.g. the largest size of the IndependentSet problem is also know as the independence number.

  • The corresponding tensor element type are max-plus tropical number Tropical if K is Single and ExtendedTropical if K is an integer.
  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.SizeMin โ€” Type
SizeMin{K} <: AbstractProperty
+SizeMin(k::Int)

The minimum-K set sizes. e.g. the smallest size ofthe MaximalIS problem is also known as the independent domination number.

  • The corresponding tensor element type are inverted max-plus tropical number Tropical if K is Single and inverted ExtendedTropical K is an integer.

The inverted Tropical number emulates the min-plus tropical number.

  • It is compatible with weighted graph problems.
  • BLAS (on CPU) and GPU are supported only if K is Single,
source
GenericTensorNetworks.CountingAll โ€” Type
CountingAll <: AbstractProperty
+CountingAll()

Counting the total number of sets. e.g. for the IndependentSet problem, it counts the independent sets.

  • The corresponding tensor element type is Base.Real.
  • The weights on graph does not have effect.
  • BLAS (GPU and CPU) and GPU are supported,
source
GenericTensorNetworks.CountingMax โ€” Type
CountingMax{K} <: AbstractProperty
+CountingMax(K=Single)

Counting the number of sets with largest-K size. e.g. for IndependentSet problem, it counts independent sets of size $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding tensor element type is CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.CountingMin โ€” Type
CountingMin{K} <: AbstractProperty
+CountingMin(K=Single)

Counting the number of sets with smallest-K size.

  • The corresponding tensor element type is inverted CountingTropical if K is Single, and TruncatedPoly{K} if K is an integer.
  • Weighted graph problems is only supported if K is Single.
  • GPU is supported,
source
GenericTensorNetworks.GraphPolynomial โ€” Type
GraphPolynomial{METHOD} <: AbstractProperty
+GraphPolynomial(; method=:finitefield, kwargs...)

Compute the graph polynomial, e.g. for IndependentSet problem, it is the independence polynomial. The METHOD type parameter can be one of the following symbols

Method Argument

  • :finitefield, uses finite field algebra to fit the polynomial.
    • The corresponding tensor element type is Mods.Mod,
    • It does not have round-off error,
    • GPU is supported,
    • It accepts keyword arguments maxorder (optional, e.g. the MIS size in the IndependentSet problem).
  • :polynomial and :laurent, use (Laurent) polynomial numbers to solve the polynomial directly.
    • The corresponding tensor element types are Polynomial and LaurentPolynomial.
    • It might have small round-off error depending on the data type for storing the counting.
    • It has memory overhead that linear to the graph size.
  • :fft, use fast fourier transformation to fit the polynomial.
    • The corresponding tensor element type is Base.Complex.
    • It has (controllable) round-off error.
    • BLAS and GPU are supported.
    • It accepts keyword arguments maxorder (optional) and r, if r > 1, one has better precision for coefficients of large order, if r < 1, one has better precision for coefficients of small order.
  • :fitting, fit the polynomial directly.
    • The corresponding tensor element type is floating point numbers like Base.Float64.
    • It has round-off error.
    • BLAS and GPU are supported, it is the fastest among all methods.

Graph polynomials are not defined for weighted graph problems.

source
GenericTensorNetworks.SingleConfigMax โ€” Type
SingleConfigMax{K, BOUNDED} <: AbstractProperty
+SingleConfigMax(k::Int; bounded=false)

Finding single solution for largest-K sizes, e.g. for IndependentSet problem, it is one of the maximum independent sets.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.SingleConfigMin โ€” Type
SingleConfigMin{K, BOUNDED} <: AbstractProperty
+SingleConfigMin(k::Int; bounded=false)

Finding single solution with smallest-K size.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
source
GenericTensorNetworks.ConfigsAll โ€” Type
ConfigsAll{TREESTORAGE} <:AbstractProperty
+ConfigsAll(; tree_storage=false)

Find all valid configurations, e.g. for IndependentSet problem, it is finding all independent sets.

Keyword Arguments

  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMax โ€” Type
ConfigsMax{K, BOUNDED, TREESTORAGE} <:AbstractProperty
+ConfigsMax(K=Single; bounded=true, tree_storage=true)

Find configurations with largest-K sizes, e.g. for IndependentSet problem, it is finding all independent sets of sizes $\alpha(G), \alpha(G)-1, \ldots, \alpha(G)-K+1$.

  • The corresponding data type is CountingTropical{Float64,<:ConfigEnumerator} if K is Single and TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source
GenericTensorNetworks.ConfigsMin โ€” Type
ConfigsMin{K, BOUNDED, TREESTORAGE} <:AbstractProperty
+ConfigsMin(K=Single; bounded=true, tree_storage=false)

Find configurations with smallest-K sizes.

  • The corresponding data type is inverted CountingTropical{Float64,<:ConfigEnumerator} if K is Single and inverted TruncatedPoly{K,<:ConfigEnumerator} if K is an integer.
  • Weighted graph problems is only supported if K is Single.

Keyword Arguments

  • bounded, if it is true, use bounding trick (or boolean gradients) to reduce the working memory to store intermediate configurations.
  • tree_storage, if it is true, it uses more memory efficient tree-structure to store the configurations.
source

Element Algebras

GenericTensorNetworks.is_commutative_semiring โ€” Function
is_commutative_semiring(a::T, b::T, c::T) where T

Check if elements a, b and c satisfied the commutative semiring requirements.

\[\begin{align*} (a \oplus b) \oplus c = a \oplus (b \oplus c) & \hspace{5em}\triangleright\text{commutative monoid $\oplus$ with identity $\mathbb{0}$}\\ a \oplus \mathbb{0} = \mathbb{0} \oplus a = a &\\ a \oplus b = b \oplus a &\\ @@ -185,7 +185,7 @@ (a\oplus b) \odot c = a\odot c \oplus b\odot c &\\ &\\ a \odot \mathbb{0} = \mathbb{0} \odot a = \mathbb{0} -\end{align*}\]

source
TropicalNumbers.Tropical โ€” Type
TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring

TropicalMaxPlus is a semiring algebra, can be described by

  • Tropical (TropicalMaxPlus), (โ„, max, +, -Inf, 0).

It maps

  • + to max in regular algebra,
  • * to + in regular algebra,
  • 1 to 0 in regular algebra,
  • 0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).

Example

julia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)
+\end{align*}\]

source
TropicalNumbers.Tropical โ€” Type
TropicalMaxPlus{T} = Tropical{T} <: AbstractSemiring

TropicalMaxPlus is a semiring algebra, can be described by

  • Tropical (TropicalMaxPlus), (โ„, max, +, -Inf, 0).

It maps

  • + to max in regular algebra,
  • * to + in regular algebra,
  • 1 to 0 in regular algebra,
  • 0 to -Inf in regular algebra (for integer content types, this is chosen as a small integer).

Example

julia> TropicalMaxPlus(1.0) + TropicalMaxPlus(3.0)
 3.0โ‚œ
 
 julia> TropicalMaxPlus(1.0) * TropicalMaxPlus(3.0)
@@ -222,7 +222,7 @@
 ExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infโ‚œ, -Infโ‚œ, 0.0โ‚œ])
 
 julia> zero(x)
-ExtendedTropical{3, Tropical{Float64}}(Tropical{Float64}[-Infโ‚œ, -Infโ‚œ, -Infโ‚œ])
source
Mods.Mod โ€” Type

Mod{m}(v) creates a modular number in mod m with value mod(v,m).

source
Mods.Mod โ€” Type

Mod{m}(v) creates a modular number in mod m with value mod(v,m).

source
GenericTensorNetworks.TruncatedPoly โ€” Type
TruncatedPoly{K,T,TO} <: Number
 TruncatedPoly(coeffs::Tuple, maxorder)

Polynomial truncated to largest K orders. T is the coefficients type and TO is the orders type.

Fields

  • coeffs is the largest-K coefficients of a polynomial. In GenericTensorNetworks, it can be the counting or enumeration of solutions.
  • maxorder is the order of a polynomial.

Examples

julia> TruncatedPoly((1,2,3), 6)
 x^4 + 2*x^5 + 3*x^6
 
@@ -230,8 +230,8 @@
 20*x^7 + 8*x^8 + 3*x^9
 
 julia> TruncatedPoly((1,2,3), 6) + TruncatedPoly((5,2,1), 3)
-x^4 + 2*x^5 + 3*x^6
source
GenericTensorNetworks.ConfigEnumerator โ€” Type
ConfigEnumerator{N,S,C} <: AbstractSetNumber

Set algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Fields

Examples

julia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])
+x^4 + 2*x^5 + 3*x^6
source
GenericTensorNetworks.ConfigEnumerator โ€” Type
ConfigEnumerator{N,S,C} <: AbstractSetNumber

Set algebra for enumerating configurations, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Fields

Examples

julia> a = ConfigEnumerator([StaticBitVector([1,1,1,0,0]), StaticBitVector([1,0,0,0,1])])
 {11100, 10001}
 
 julia> b = ConfigEnumerator([StaticBitVector([0,0,0,0,0]), StaticBitVector([1,0,1,0,1])])
@@ -244,7 +244,7 @@
 {00000}
 
 julia> zero(a)
-{}
source
GenericTensorNetworks.SumProductTree โ€” Type
SumProductTree{ET} <: AbstractSetNumber

Configuration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.

Fields

  • tag is one of ZERO, ONE, LEAF, SUM, PROD.
  • data is the element stored in a LEAF node.
  • left and right are two operands of a SUM or PROD node.

Examples

julia> s = SumProductTree(bv"00111")
+{}
source
GenericTensorNetworks.SumProductTree โ€” Type
SumProductTree{ET} <: AbstractSetNumber

Configuration enumerator encoded in a tree, it is the most natural representation given by a sum-product network and is often more memory efficient than putting the configurations in a vector. One can use generate_samples to sample configurations from this tree structure efficiently.

Fields

  • tag is one of ZERO, ONE, LEAF, SUM, PROD.
  • data is the element stored in a LEAF node.
  • left and right are two operands of a SUM or PROD node.

Examples

julia> s = SumProductTree(bv"00111")
 00111
 
 
@@ -283,7 +283,7 @@
 julia> one(s)
 00000
 
-
source
GenericTensorNetworks.ConfigSampler โ€” Type
ConfigSampler{N,S,C} <: AbstractSetNumber
 ConfigSampler(elements::StaticElementVector)

The algebra for sampling one configuration, where N is the length of configurations, C is the size of storage in unit of UInt64, S is the bit width to store a single element in a configuration, i.e. log2(# of flavors), for bitstrings, it is 1`.

Note

ConfigSampler is a probabilistic commutative semiring, adding two config samplers do not give you deterministic results.

Fields

Examples

julia> ConfigSampler(StaticBitVector([1,1,1,0,0]))
 ConfigSampler{5, 1, 1}(11100)
 
@@ -297,7 +297,7 @@
 ConfigSampler{5, 1, 1}(00000)
 
 julia> zero(ConfigSampler{5, 1, 1})
-ConfigSampler{5, 1, 1}(11111)
source

GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.

GenericTensorNetworks also exports the Polynomial and LaurentPolynomial types defined in package Polynomials.

GenericTensorNetworks.StaticBitVector โ€” Type
StaticBitVector{N,C} = StaticElementVector{N,1,C}
 StaticBitVector(x::AbstractVector)

Examples

julia> sb = StaticBitVector([1,0,0,1,1])
 10011
 
@@ -310,7 +310,7 @@
  0
  0
  1
- 1
source
GenericTensorNetworks.StaticElementVector โ€” Type
StaticElementVector{N,S,C}
 StaticElementVector(nflavor::Int, x::AbstractVector)

N is the length of vector, C is the size of storage in unit of UInt64, S is the stride defined as the log2(# of flavors). When the number of flavors is 2, it is a StaticBitVector.

Fields

  • data is a tuple of UInt64 for storing the configuration of static elements.

Examples

julia> ev = StaticElementVector(3, [1,2,0,1,2])
 12012
 
@@ -323,9 +323,9 @@
  2
  0
  1
- 2
source
GenericTensorNetworks.load_configs โ€” Function
load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)

Load configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.

source
GenericTensorNetworks.onehotv โ€” Function
onehotv(::Type{<:StaticElementVector}, i, v)
-onehotv(::Type{<:StaticBitVector, i)

Returns a static element vector, with the value at location i being v (1 if not specified).

source
GenericTensorNetworks.load_configs โ€” Function
load_configs(filename; format=:binary, bitlength=nothing, nflavors=2)

Load configurations from file filename. The format is :binary or :text. If the format is :binary, the bitstring length bitlength must be specified, nflavors specifies the degree of freedom.

source
GenericTensorNetworks.onehotv โ€” Function
onehotv(::Type{<:StaticElementVector}, i, v)
+onehotv(::Type{<:StaticBitVector, i)

Returns a static element vector, with the value at location i being v (1 if not specified).

source
GenericTensorNetworks.generate_samples โ€” Function
generate_samples(t::SumProductTree, nsamples::Int)

Direct sampling configurations from a SumProductTree instance.

Examples

julia> using Graphs
 
 julia> g= smallgraph(:petersen)
 {10, 15} undirected simple Int64 graph
@@ -335,7 +335,7 @@
 julia> samples = generate_samples(t, 1000);
 
 julia> all(s->is_independent_set(g, s), samples)
-true
source
GenericTensorNetworks.hamming_distribution โ€” Function
hamming_distribution(S, T)

Compute the distribution of pair-wise Hamming distances, which is defined as:

\[c(k) := \sum_{\sigma\in S, \tau\in T} \delta({\rm dist}(\sigma, \tau), k)\]

where $\delta$ is a function that returns 1 if two arguments are equivalent, 0 otherwise, ${\rm dist}$ is the Hamming distance function.

Returns the counting as a vector.

source

Tensor Network

OMEinsumContractionOrders.optimize_code โ€” Function
optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode

Optimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are

  • eincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.
  • size is a dictionary of "edge label=>edge size" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.
  • optimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.
  • simplifier is one of MergeVectors or MergeGreedy.
  • optimize the permutation if permute is true.

Examples

julia> using OMEinsum
+true
source
GenericTensorNetworks.hamming_distribution โ€” Function
hamming_distribution(S, T)

Compute the distribution of pair-wise Hamming distances, which is defined as:

\[c(k) := \sum_{\sigma\in S, \tau\in T} \delta({\rm dist}(\sigma, \tau), k)\]

where $\delta$ is a function that returns 1 if two arguments are equivalent, 0 otherwise, ${\rm dist}$ is the Hamming distance function.

Returns the counting as a vector.

source

Tensor Network

OMEinsumContractionOrders.optimize_code โ€” Function
optimize_code(eincode, size_dict, optimizer = GreedyMethod(), simplifier=nothing, permute=true) -> optimized_eincode

Optimize the einsum contraction code and reduce the time/space complexity of tensor network contraction. Returns a NestedEinsum instance. Input arguments are

  • eincode is an einsum contraction code instance, one of DynamicEinCode, StaticEinCode or NestedEinsum.
  • size is a dictionary of "edge label=>edge size" that contains the size information, one can use uniformsize(eincode, 2) to create a uniform size.
  • optimizer is a CodeOptimizer instance, should be one of GreedyMethod, KaHyParBipartite, SABipartite or TreeSA. Check their docstrings for details.
  • simplifier is one of MergeVectors or MergeGreedy.
  • optimize the permutation if permute is true.

Examples

julia> using OMEinsum
 
 julia> code = ein"ij, jk, kl, il->"
 ij, jk, kl, il -> 
julia> optimize_code(code, uniformsize(code, 2), TreeSA())
@@ -357,7 +357,7 @@
     property::GenericTensorNetworks.AbstractProperty;
     T
 ) -> Any
-

Memory estimation in number of bytes to compute certain property of a problem. T is the base type.

source
OMEinsum.@ein_str โ€” Macro
ein"ij,jk -> ik"(A,B)

String macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and ฮฑ-ฯ‰.

example

julia> a, b, c = rand(10,10), rand(10,10), rand(10,1);
+

Memory estimation in number of bytes to compute certain property of a problem. T is the base type.

source
OMEinsum.@ein_str โ€” Macro
ein"ij,jk -> ik"(A,B)

String macro interface which understands numpy.einsum's notation. Translates strings into StaticEinCode-structs that can be called to evaluate an einsum. To control evaluation order, use parentheses - instead of an EinCode, a NestedEinsum is returned which evaluates the expression according to parens. The valid character ranges for index-labels are a-z and ฮฑ-ฯ‰.

example

julia> a, b, c = rand(10,10), rand(10,10), rand(10,1);
 
 julia> ein"ij,jk,kl -> il"(a,b,c) โ‰ˆ ein"(ij,jk),kl -> il"(a,b,c) โ‰ˆ a * b * c
 true
source
OMEinsumContractionOrders.GreedyMethod โ€” Type
GreedyMethod{MT}
@@ -425,7 +425,7 @@
     open_label_color="red",
     annotate_labels=true,
     kwargs...
-    )

Positional arguments

  • ein is an Einsum contraction code (provided by package OMEinsum).

Keyword arguments

  • tensor_locs is a vector of tuples for specifying the vertex locations.

  • label_locs is a vector of tuples for specifying the vertex locations.

  • spring is switch to use spring method to optimize the location.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • tensor_color is a string to specify the color of tensor nodes.

  • tensor_size is a real number to specify the size of tensor nodes.

  • tensor_text_color is a color strings to specify tensor text color.

  • annotate_tensors is a boolean switch for annotate different tensors by integers.

  • label_size is a real number to specify label text node size.

  • label_color is a color strings to specify label text color.

  • open_label_color is a color strings to specify open label text color.

  • annotate_labels is a boolean switch for annotate different labels.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
source
GenericTensorNetworks.line_graph โ€” Function
line_graph(g::SimpleGraph)

Returns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

source

One can also use random_regular_graph and smallgraph in Graphs to build special graphs.

Multiprocessing

GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run โ€” Function
multiprocess_run(func, inputs::AbstractVector)

Execute function func on inputs with multiple processing.

Example

Suppose we have a file run.jl with the following contents

using GenericTensorNetworks.SimpleMultiprocessing
+    )

Positional arguments

  • ein is an Einsum contraction code (provided by package OMEinsum).

Keyword arguments

  • tensor_locs is a vector of tuples for specifying the vertex locations.

  • label_locs is a vector of tuples for specifying the vertex locations.

  • spring is switch to use spring method to optimize the location.

  • optimal_distance is a optimal distance parameter for spring optimizer.

  • tensor_color is a string to specify the color of tensor nodes.

  • tensor_size is a real number to specify the size of tensor nodes.

  • tensor_text_color is a color strings to specify tensor text color.

  • annotate_tensors is a boolean switch for annotate different tensors by integers.

  • label_size is a real number to specify label text node size.

  • label_color is a color strings to specify label text color.

  • open_label_color is a color strings to specify open label text color.

  • annotate_labels is a boolean switch for annotate different labels.

  • format is the output format, which can be :svg, :png or :pdf.

  • filename is a string as the output filename.

Extra keyword arguments

  • general
    • xpad::Float64 = 1.0, the padding space in x direction
    • ypad::Float64 = 1.0, the padding space in y direction
    • xpad_right::Float64 = 1.0, the padding space in x direction (right side)
    • ypad_bottom::Float64 = 1.0, the padding space in y direction (bottom side)
    • background_color = DEFAULT_BACKGROUND_COLOR[], the background color
    • unit::Float64 = DEFAULT_UNIT[], the unit distance as the number of pixels
    • fontsize::Float64 = DEFAULT_FONTSIZE[], the font size
    • fontface::String = "", the font face, leave empty to follow system
  • vertex
    • vertex_text_color = DEFAULT_VERTEX_TEXT_COLOR[], the default text color
    • vertex_stroke_color = DEFAULT_VERTEX_STROKE_COLOR[], the default stroke color for vertices
    • vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR[], the default default fill color for vertices
    • vertex_size::Float64 = DEFAULT_VERTEX_SIZE[], the default vertex size
    • vertex_shape::String = "circle", the default vertex shape, which can be "circle" or "box"
    • vertex_line_width::Float64 = 1, the default vertex stroke line width
    • vertex_line_style::String = "solid", the line style of vertex stroke, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
  • edge
    • edge_color = DEFAULT_EDGE_COLOR[], the default edge color
    • edge_line_width::Float64 = 1, the default line width
    • edge_style::String = "solid", the line style of edges, which can be one of ["solid", "dotted", "dot", "dotdashed", "longdashed", "shortdashed", "dash", "dashed", "dotdotdashed", "dotdotdotdashed"]
source
GenericTensorNetworks.line_graph โ€” Function
line_graph(g::SimpleGraph)

Returns the line graph of g. The line graph is generated by mapping an edge to a vertex and two edges sharing a common vertex will be connected.

source

One can also use random_regular_graph and smallgraph in Graphs to build special graphs.

Multiprocessing

GenericTensorNetworks.SimpleMultiprocessing.multiprocess_run โ€” Function
multiprocess_run(func, inputs::AbstractVector)

Execute function func on inputs with multiple processing.

Example

Suppose we have a file run.jl with the following contents

using GenericTensorNetworks.SimpleMultiprocessing
 
 results = multiprocess_run(x->x^2, randn(8))

In an terminal, you may run the script with 4 processes by typing

$ julia -p4 run.jl
       From worker 2:	[ Info: running argument -0.17544008350172655 on device 2
@@ -435,4 +435,4 @@
       From worker 2:	[ Info: running argument 0.013132180639054629 on device 2
       From worker 3:	[ Info: running argument 0.9960101782201602 on device 3
       From worker 4:	[ Info: running argument -0.5613942832743966 on device 4
-      From worker 5:	[ Info: running argument 0.39460402723831134 on device 5
source
+ From worker 5: [ Info: running argument 0.39460402723831134 on device 5source diff --git a/dev/sumproduct/index.html b/dev/sumproduct/index.html index 5ac4a246..ed73b36b 100644 --- a/dev/sumproduct/index.html +++ b/dev/sumproduct/index.html @@ -24,4 +24,4 @@ โ”‚โ €โ €โ €โ €โ €โ €โ €โ €โข โ ‡โ €โ €โ €โ €โ €โ €โ €โขณโ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ”‚ 0 โ”‚โข€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โ Žโ €โ €โ €โ €โ €โ €โ €โ €โ €โ “โข„โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โฃ€โ €โ €โ €โ €โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ €0โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €80โ €

Here, the $x$-axis is the Hamming distance and the $y$-axis is the counting of pair-wise Hamming distances.

+ โ €0โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €80โ €

Here, the $x$-axis is the Hamming distance and the $y$-axis is the counting of pair-wise Hamming distances.