Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# GraphTensorNetworks

[![Build Status](https://github.com/Happy-Diode/GraphTensorNetworks.jl/workflows/CI/badge.svg)](https://github.com/Happy-Diode/GraphTensorNetworks.jl/actions)
[![Coverage Status](https://coveralls.io/repos/github/Happy-Diode/GraphTensorNetworks.jl/badge.svg?branch=fix-test-coverage&t=rIJIK2)](https://coveralls.io/github/Happy-Diode/GraphTensorNetworks.jl?branch=fix-test-coverage)
[![Coverage Status](https://coveralls.io/repos/github/Happy-Diode/GraphTensorNetworks.jl/badge.svg?branch=master&t=rIJIK2)](https://coveralls.io/github/Happy-Diode/GraphTensorNetworks.jl?branch=master)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://psychic-meme-f4d866f8.pages.github.io/dev/)

## Installation
Expand Down
13 changes: 11 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ CurrentModule = GraphTensorNetworks

# GraphTensorNetworks

This package uses generic tensor network to compute properties of combinatorial problems defined on graph.
The properties includes the size of the maximum set size, the number of sets of a given size and the enumeration of configurations of a given set size.

## Background knowledge

Please check our paper ["Computing properties of independent sets by generic programming tensor networks"]().
If you find our paper or software useful in your work, please cite us.
If you find our paper or software useful in your work, please cite us:

```bibtex
(bibtex to be added)
```

## Quick start

You can find a good installation guide and a quick start in our [README](https://github.com/Happy-Diode/GraphTensorNetworks.jl).
You can find a good installation guide and a quick start in our [README](https://github.com/Happy-Diode/GraphTensorNetworks.jl).

A good example to start with is the [Independent set problem](@ref).
19 changes: 14 additions & 5 deletions docs/src/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,25 @@ set_packing

#### Graph Problem Interfaces
```@docs
generate_tensors
GraphTensorNetworks.generate_tensors
symbols
flavors
get_weights
nflavor
```

To subtype [`GraphProblem`](@ref), the new type must contain a `code` field to represent the (optimized) tensor network.
Interfaces [`generate_tensors`](@ref), [`symbols`](@ref), [`flavors`](@ref) and [`get_weights`] are required.
Interfaces [`GraphTensorNetworks.generate_tensors`](@ref), [`symbols`](@ref), [`flavors`](@ref) and [`get_weights`] are required.
[`nflavor`] is optimal.

#### Graph Problem Utilities
```@docs
is_independent_set
mis_compactify!

cut_size
cut_assign
```

## Properties
```@docs
Expand Down Expand Up @@ -81,13 +89,14 @@ MergeGreedy
## Others
#### Graph
```@docs
is_independent_set
mis_compactify!
show_graph

diagonal_coupled_graph
square_lattice_graph
unitdisk_graph
unit_disk_graph

random_diagonal_coupled_graph
random_square_lattice_graph
```

One can also use `random_regular_graph` and `smallgraph` in [Graphs](https://github.com/JuliaGraphs/Graphs.jl) to build special graphs.
Expand Down
31 changes: 31 additions & 0 deletions examples/Coloring/main.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# # Coloring problem

# !!! note
# This tutorial only covers the coloring problem specific features,
# It is recommended to read the [Independent set problem](@ref) tutorial too to know more about
# * how to optimize the tensor network contraction order,
# * what are the other graph properties computable,
# * how to select correct method to compute graph properties,
# * how to compute weighted graphs and handle open vertices.

# ## Introduction
using GraphTensorNetworks, Graphs

# Please check the docstring of [`Coloring`](@ref) for the definition of the vertex cutting problem.
@doc Coloring

# In the following, we are going to defined a 3-coloring problem for the Petersen graph.

graph = Graphs.smallgraph(:petersen)

# We can visualize this graph using the following function
rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a

locations = [[rot15(0.0, 1.0, i) for i=0:4]..., [rot15(0.0, 0.6, i) for i=0:4]...]

show_graph(graph; locs=locations)

# Then we define the cutting problem as
problem = Coloring{3}(graph);

# ## Solving properties
56 changes: 51 additions & 5 deletions examples/IndependentSet/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,36 @@ problem = Independence(graph; optimizer=TreeSA(sc_weight=1.0, ntrials=10,
βs=0.01:0.1:15.0, niters=20, rw_weight=0.2),
simplifier=MergeGreedy());

# The `optimizer` is for optimizing the contraction orders.
# Here we use the local search based optimizer in [arXiv:2108.05665](https://arxiv.org/abs/2108.05665).
# If no optimizer is specified, the default fast (in terms of the speed of searching contraction order)
# but worst (in term of contraction complexity) [`GreedyMethod`](@ref) will be used.
# `simplifier` is a preprocessing routine to speed up the `optimizer`.
# Please check section [Tensor Network](@ref) for more details.
# One can check the time, space and read-write complexity with the following function.

timespacereadwrite_complexity(problem)

# The return values are `log2` of the the number of iterations, the number elements in the max tensor and the number of read-write operations to tensor elements.


# ## Solving properties

# ### Maximum independent set size ``\alpha(G)``
maximum_independent_set_size = solve(problem, SizeMax())
maximum_independent_set_size = solve(problem, SizeMax())[]

# ### Counting properties
# ##### counting all independent sets
count_all_independent_sets = solve(problem, CountingAll())
count_all_independent_sets = solve(problem, CountingAll())[]

# ##### counting independent sets with sizes ``\alpha(G)`` and ``\alpha(G)-1``
count_max2_independent_sets = solve(problem, CountingMax(2))
count_max2_independent_sets = solve(problem, CountingMax(2))[]

# ##### independence polynomial
# For the definition of independence polynomial, please check the docstring of [`Independence`](@ref) or this [wiki page](https://mathworld.wolfram.com/IndependencePolynomial.html).
# There are 3 methods to compute a graph polynomial, `:finitefield`, `:fft` and `:polynomial`.
# These methods are introduced in the docstring of [`GraphPolynomial`](@ref).
independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))
independence_polynomial = solve(problem, GraphPolynomial(; method=:finitefield))[]

# ### Configuration properties
# ##### finding one maximum independent set (MIS)
Expand Down Expand Up @@ -72,4 +84,38 @@ imgs = ntuple(k->(context((k-1)/m, 0.0, 1.2/m, 1.0), show_graph(graph;
Compose.set_default_graphic_size(18cm, 4cm); Compose.compose(context(), imgs...)

# ##### enumeration of all IS configurations
all_independent_sets = solve(problem, ConfigsAll())[]
all_independent_sets = solve(problem, ConfigsAll())[]

# To save/read a set of configuration to disk, one can type the following
filename = tempname()

save_configs(filename, all_independent_sets; format=:binary)

loaded_sets = load_configs(filename; format=:binary, bitlength=10)

# !!! note
# When loading data, one needs to provide the `bitlength` if the data is saved in binary format.
# Because the bitstring length is not stored.

# ## Weights and open vertices
# [`Independence`] accepts weights as a key word argument.
# The following code computes the weighted MIS problem.
problem = Independence(graph; weights=collect(1:10))

max_config_weighted = solve(problem, SingleConfigMax())[]

show_graph(graph; locs=locations, colors=
[iszero(max_config_weighted.c.data[i]) ? "white" : "red" for i=1:nv(graph)])

# The following code computes the MIS tropical tensor (reference to be added) with open vertices 1 and 2.
problem = Independence(graph; openvertices=[1,2,3])

mis_tropical_tensor = solve(problem, SizeMax())

# The MIS tropical tensor shows the MIS size under different configuration of open vertices.
# It is useful in MIS tropical tensor analysis.
# One can compatify this MIS-Tropical tensor by typing

mis_compactify!(mis_tropical_tensor)

# It will eliminate some entries having no contribution to the MIS size when embeding this local graph into a larger one.
31 changes: 31 additions & 0 deletions examples/Matching/main.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# # Vertex matching problem

# !!! note
# This tutorial only covers the vertex matching problem specific features,
# It is recommended to read the [Independent set problem](@ref) tutorial too to know more about
# * how to optimize the tensor network contraction order,
# * what are the other graph properties computable,
# * how to select correct method to compute graph properties,
# * how to compute weighted graphs and handle open vertices.

# ## Introduction
using GraphTensorNetworks, Graphs

# Please check the docstring of [`Matching`](@ref) for the definition of the vertex matching problem.
@doc Matching

# In the following, we are going to defined a matching problem for the Petersen graph.

graph = Graphs.smallgraph(:petersen)

# We can visualize this graph using the following function
rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a

locations = [[rot15(0.0, 1.0, i) for i=0:4]..., [rot15(0.0, 0.6, i) for i=0:4]...]

show_graph(graph; locs=locations)

# Then we define the matching problem as
problem = Matching(graph);

# ## Solving properties
53 changes: 50 additions & 3 deletions examples/MaxCut/main.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,54 @@
# # Max-Cut problem
# # Cutting problem (Spin-glass problem)

# ## Problem definition
# !!! note
# This tutorial only covers the cutting problem specific features,
# It is recommended to read the [Independent set problem](@ref) tutorial too to know more about
# * how to optimize the tensor network contraction order,
# * what are the other graph properties computable,
# * how to select correct method to compute graph properties,
# * how to compute weighted graphs and handle open vertices.

# ## Introduction
using GraphTensorNetworks, Graphs

# Please check the docstring of [`MaxCut`](@ref) for the definition of the vertex cutting problem.
@doc MaxCut

# In the following, we are going to defined an cutting problem for the Petersen graph.

graph = Graphs.smallgraph(:petersen)

# We can visualize this graph using the following function
rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a

locations = [[rot15(0.0, 1.0, i) for i=0:4]..., [rot15(0.0, 0.6, i) for i=0:4]...]

show_graph(graph; locs=locations)

# Then we define the cutting problem as
problem = MaxCut(graph);

# ## Solving properties
using GraphTensorNetworks, Graphs

# ### Maximum cut size ``\gamma(G)``
max_cut_size = solve(problem, SizeMax())[]

# ### Counting properties
# ##### graph polynomial
# Since the variable ``x`` is defined on edges,
# hence the coefficients of the polynomial is the number of configurations having different number of anti-parallel edges.
max_config = solve(problem, GraphPolynomial())[]

# ### Configuration properties
# ##### finding one max cut solution
max_edge_config = solve(problem, SingleConfigMax())[]

# These configurations are defined on edges, we need to find a valid assignment on vertices
max_vertex_config = cut_assign(graph, max_edge_config.c.data)

max_cut_size_verify = cut_size(graph, max_vertex_config)

# You should see a consistent result as above `max_cut_size`.

show_graph(graph; locs=locations, colors=[
iszero(max_vertex_config[i]) ? "white" : "red" for i=1:nv(graph)])
50 changes: 50 additions & 0 deletions examples/MaxinalIndependence/main.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# # Maximal independent set problem

# !!! note
# This tutorial only covers the maximal independent set problem specific features,
# It is recommended to read the [Independent set problem](@ref) tutorial too to know more about
# * how to optimize the tensor network contraction order,
# * what are the other graph properties computable,
# * how to select correct method to compute graph properties,
# * how to compute weighted graphs and handle open vertices.

# ## Introduction
using GraphTensorNetworks, Graphs

# Please check the docstring of [`MaximalIndependence`](@ref) for the definition of the maximal independence problem.
@doc MaximalIndependence

# In the following, we are going to defined an cutting problem for the Petersen graph.

graph = Graphs.smallgraph(:petersen)

# We can visualize this graph using the following function
rot15(a, b, i::Int) = cos(2i*π/5)*a + sin(2i*π/5)*b, cos(2i*π/5)*b - sin(2i*π/5)*a

locations = [[rot15(0.0, 1.0, i) for i=0:4]..., [rot15(0.0, 0.6, i) for i=0:4]...]

show_graph(graph; locs=locations)

# Then we define the maximal independent set problem as
problem = MaximalIndependence(graph);

# The tensor network structure is different from that of [`Independence`](@ref),
# Its tensor is defined on a vertex and its neighbourhood,
# and it makes the contraction of [`MaximalIndependence`](@ref) much harder.

# ## Solving properties

# ### Counting properties
# ##### maximal independence polynomial
max_config = solve(problem, GraphPolynomial())[]

# Since it only counts the maximal independent sets, the first several coefficients are 0.

# ### Configuration properties
# ##### finding all maximal independent set
max_edge_config = solve(problem, ConfigsAll())[]

# This result should be consistent with that given by the [Bron Kerbosch algorithm](https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm) on the complement of Petersen graph.
maximal_cliques = maximal_cliques(complement(graph))

# For sparse graphs, the generic tensor network approach is usually much faster and memory efficient.
5 changes: 1 addition & 4 deletions examples/Others/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,4 @@
# A vertex cover is a complement of an independent set.

# ### Maximal clique problem
# The maximal clique of graph ``G`` is a maximal clique of ``G``'s complement graph.

# ### Spin-glass problem
# It is another way of saying the Max-Cut problem.
# The maximal clique of graph ``G`` is a maximal clique of ``G``'s complement graph.
19 changes: 19 additions & 0 deletions examples/PaintShop/main.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# # Binary paint shop problem

# !!! note
# This tutorial only covers the binary paint shop problem specific features,
# It is recommended to read the [Independent set problem](@ref) tutorial too to know more about
# * how to optimize the tensor network contraction order,
# * what are the other graph properties computable,
# * how to select correct method to compute graph properties,
# * how to compute weighted graphs and handle open vertices.

# ## Introduction
using GraphTensorNetworks, Graphs

# Please check the docstring of [`PaintShop`](@ref) for the definition of the binary paint shop problem.
@doc PaintShop

# In the following, we are going to defined a binary paint shop problem for the following string

sequence = "abaccb"
2 changes: 1 addition & 1 deletion notebooks/tropicalwidget_simple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ locs = let
end

# ╔═╡ 9d0ba8b7-5a34-418d-97cf-863f376f8453
graph = unitdisk_graph(locs, 0.23) # SimpleGraph
graph = unit_disk_graph(locs, 0.23) # SimpleGraph

# ╔═╡ 78ee8772-83e4-40fb-8151-0123370481d9
vizconfig(graph; locs=locs, config=rand(Bool, 12), graphsize=8cm)
Expand Down
2 changes: 1 addition & 1 deletion notebooks/tutorial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ md"## High level interfaces"
locs = [rand(2) for i=1:70];

# ╔═╡ 1522938d-d60b-4133-8625-5a09615a7b26
g = unitdisk_graph(locs, 0.2)
g = unit_disk_graph(locs, 0.2)

# ╔═╡ 05ac5610-4a1d-4433-ba0d-1d13fd8a6733
vizconfig(g; locs=locs, unit=0.5)
Expand Down
Loading