Unweighted KSG reduction of the independent set problem

This page contains examples from the paper, "Computer-Assisted Gadget Design and Problem Reduction of Unweighted Maximum Independent Set".

using UnitDiskMapping, Graphs # for mapping graphs to a King's subgraph (KSG)
using GenericTensorNetworks # for solving the maximum independent sets
using GenericTensorNetworks.ProblemReductions

Example 1: The 5-vertex graph

The five vertex demo graph in the paper.

Step 1: Prepare a source graph.

the demo graph in the main text

function demograph()
    g = SimpleGraph(5)
    for (i, j) in [(1, 2), (2, 4), (3, 4), (1, 3), (4, 5), (1, 5)]
        add_edge!(g, i, j)
    end
    return g
end

g5 = demograph()

show_graph(g5)

Step 2: Map the source graph to an unweighted King's subgraph (KSG)

The vertex order is optimized with the Branching path decomposition algorithm (MinhThi's Trick)

g5res = UnitDiskMapping.map_graph(g5; vertex_order=MinhThiTrick())
MappingResult{UnWeightedNode}(GridGraph{UnWeightedNode} (radius = 1.5)
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ● ● ● ⋅ ● ● ● ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ⋅ ● ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ , UnitDiskMapping.CopyLine[UnitDiskMapping.CopyLine 4: vslot → [1:1,1], hslot → [1,1:5], UnitDiskMapping.CopyLine 1: vslot → [2:2,2], hslot → [2,2:5], UnitDiskMapping.CopyLine 5: vslot → [1:3,3], hslot → [3,3:3], UnitDiskMapping.CopyLine 3: vslot → [1:3,4], hslot → [3,4:4], UnitDiskMapping.CopyLine 2: vslot → [1:3,5], hslot → [3,5:5]], 2, Tuple{Pattern, Int64, Int64}[(⋅ ◆ ⋅ ⋅ 
◆ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
● ⋅ ● ⋅ 
⋅ ● ⋅ ⋅ , 7, 18), (⋅ ◆ ⋅ 
◆ ◉ ● 
⋅ ● ⋅ 
  ↓
⋅ ● ⋅ 
● ● ● 
⋅ ● ⋅ , 7, 14), (⋅ ◆ ⋅ 
◆ ◉ ● 
⋅ ● ⋅ 
  ↓
⋅ ● ⋅ 
● ● ● 
⋅ ● ⋅ , 7, 10), (⋅ ● ⋅ ⋅ 
⋅ ● ● ⋅ 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ , 11, 18), (◆ ⋅ 
⋅ ◆ 
 ↓
● ⋅ 
⋅ ● , 4, 18), (⋅ ● ⋅ ⋅ 
⋅ ● ● ⋅ 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ , 11, 14), (⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
◆ ● ● 
⋅ ◆ ⋅ 
  ↓
⋅ ⋅ ⋅ 
⋅ ● ⋅ 
● ⋅ ● 
⋅ ● ⋅ , 2, 14), (⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
◆ ● ● 
⋅ ◆ ⋅ 
  ↓
⋅ ⋅ ⋅ 
⋅ ● ⋅ 
● ⋅ ● 
⋅ ● ⋅ , 2, 10), (⋅ ● ⋅ ⋅ 
⋅ ● ● ⋅ 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ , 11, 10), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 3), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 5), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 7), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 7, 7), (⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
  ↓
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ , 9, 10), (⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
  ↓
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ , 9, 14), (⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
  ↓
⋅ ● ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ , 9, 18)], 12)

Visualize the mapped KSG graph in terminal

print(g5res.grid_graph)
GridGraph{UnWeightedNode} (radius = 1.5)
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ● ● ● ⋅ ● ● ● ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ⋅ ● ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅

or in a plotting plane

show_graph(g5res.grid_graph)
Example block output

Step 3: Solve the MIS size of the mapped graph

The independent set size can be obtained by solving the SizeMax() property using the generic tensor network method.

missize_g5_ksg = solve(GenericTensorNetwork(IndependentSet(SimpleGraph(g5res.grid_graph))), SizeMax())[]
15.0ₜ

The predicted MIS size for the source graph is:

missize_g5_ksg.n - g5res.mis_overhead
3.0

One of the best solutions can be obtained by solving the SingleConfigMax() property.

mis_g5_ksg = solve(GenericTensorNetwork(IndependentSet(SimpleGraph(g5res.grid_graph))), SingleConfigMax())[].c.data
0011010100110011010100110010110

Plot the solution

show_config(g5res.grid_graph, mis_g5_ksg)
Example block output

Step 4: Map the KSG solution back

In the following, we will show how to obtain an MIS of the source graph from that of its KSG reduction.

mis_g5 = UnitDiskMapping.map_config_back(g5res, collect(mis_g5_ksg))
5-element Vector{Int64}:
 0
 1
 1
 0
 1

Show that the overhead in the MIS size is correct

Verify the result:

the extracted solution is an independent set

UnitDiskMapping.is_independent_set(g5, mis_g5)
true

and its size is maximized

count(isone, mis_g5)

solve(GenericTensorNetwork(IndependentSet(g5)), SizeMax())[].n
3.0

Example 2: The Petersen graph

We just quickly go through a second example, the Petersen graph.

petersen = smallgraph(:petersen)

show_graph(petersen)

We first map it to a grid graph (unweighted).

petersen_res = UnitDiskMapping.map_graph(petersen)
MappingResult{UnWeightedNode}(GridGraph{UnWeightedNode} (radius = 1.5)
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ● ● ● ⋅ ● ● ● ● ● ● ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ● ● ⋅ ● ● ● ● ● ● ● ⋅ ● ⋅ ⋅ ● ⋅ ● ● ⋅ ● ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ● ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ⋅ ⋅ ● ⋅ ⋅ ● ● ● ⋅ ● ● ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ⋅ ● ● ● ⋅ ● ● ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ⋅ ● ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ● ⋅ ● ● ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ● ⋅ ● ● ● ● ● ● ● ● ● ● ● ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ● ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ , UnitDiskMapping.CopyLine[UnitDiskMapping.CopyLine 10: vslot → [1:1,1], hslot → [1,1:6], UnitDiskMapping.CopyLine 9: vslot → [2:2,2], hslot → [2,2:7], UnitDiskMapping.CopyLine 8: vslot → [1:3,3], hslot → [3,3:8], UnitDiskMapping.CopyLine 7: vslot → [1:4,4], hslot → [4,4:9], UnitDiskMapping.CopyLine 6: vslot → [2:5,5], hslot → [5,5:10], UnitDiskMapping.CopyLine 5: vslot → [1:6,6], hslot → [6,6:10], UnitDiskMapping.CopyLine 4: vslot → [1:6,7], hslot → [1,7:8], UnitDiskMapping.CopyLine 3: vslot → [1:3,8], hslot → [2,8:9], UnitDiskMapping.CopyLine 2: vslot → [1:4,9], hslot → [1,9:10], UnitDiskMapping.CopyLine 1: vslot → [1:6,10], hslot → [2,10:10]], 2, Tuple{Pattern, Int64, Int64}[(⋅ ● ⋅ ⋅ 
⋅ ● ● ⋅ 
⋅ ● ● ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ , 7, 38), (◆ ⋅ 
⋅ ◆ 
 ↓
● ⋅ 
⋅ ● , 4, 38), (⋅ ◆ 
◆ ⋅ 
 ↓
⋅ ● 
● ⋅ , 23, 38), (⋅ ◆ ⋅ ⋅ 
◆ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
● ⋅ ● ⋅ 
⋅ ● ⋅ ⋅ , 19, 38), (⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ● ● 
⋅ ● ● ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ● ⋅ 
⋅ ● ⋅ ⋅ , 3, 34), (⋅ ◆ ⋅ ⋅ 
◆ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
● ⋅ ● ⋅ 
⋅ ● ⋅ ⋅ , 7, 34), (⋅ ◆ 
◆ ⋅ 
 ↓
⋅ ● 
● ⋅ , 15, 34), (⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
⋅ ● ● ● 
⋅ ● ● ⋅ 
⋅ ● ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ● ⋅ 
⋅ ● ⋅ ● 
⋅ ⋅ ● ⋅ 
⋅ ● ⋅ ⋅ , 6, 30), (◆ ⋅ 
⋅ ◆ 
 ↓
● ⋅ 
⋅ ● , 4, 30), (⋅ ◆ 
◆ ⋅ 
 ↓
⋅ ● 
● ⋅ , 11, 30)  …  (⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ● ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 14, 14), (⋅ ⋅ ● ⋅ ⋅ 
● ● ◉ ● ● 
⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ● ⋅ ⋅ 
    ↓
⋅ ⋅ ● ⋅ ⋅ 
● ● ● ● ● 
⋅ ● ● ● ⋅ 
⋅ ⋅ ● ⋅ ⋅ , 11, 13), (⋅ ◆ ⋅ 
◆ ◉ ● 
⋅ ● ⋅ 
  ↓
⋅ ● ⋅ 
● ● ● 
⋅ ● ⋅ , 7, 14), (⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
◆ ● ● 
⋅ ◆ ⋅ 
  ↓
⋅ ⋅ ⋅ 
⋅ ● ⋅ 
● ⋅ ● 
⋅ ● ⋅ , 2, 14), (⋅ ● ⋅ ⋅ 
⋅ ● ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ● ⋅ ⋅ 
⋅ ⋅ ● ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 10, 10), (⋅ ⋅ ● ⋅ ⋅ 
● ● ◉ ● ● 
⋅ ⋅ ● ⋅ ⋅ 
⋅ ⋅ ● ⋅ ⋅ 
    ↓
⋅ ⋅ ● ⋅ ⋅ 
● ● ● ● ● 
⋅ ● ● ● ⋅ 
⋅ ⋅ ● ⋅ ⋅ , 7, 9), (⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ 
◆ ● ● 
⋅ ◆ ⋅ 
  ↓
⋅ ⋅ ⋅ 
⋅ ● ⋅ 
● ⋅ ● 
⋅ ● ⋅ , 2, 10), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 3), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 5), (⋅ ⋅ ⋅ ⋅ 
⋅ ● ● ● 
⋅ ⋅ ⋅ ⋅ 
   ↓
⋅ ⋅ ⋅ ⋅ 
⋅ ⋅ ⋅ ● 
⋅ ⋅ ⋅ ⋅ , 3, 7)], 88)

The MIS size of the petersen graph is 4.

missize_petersen = solve(GenericTensorNetwork(IndependentSet(petersen)), SizeMax())[]
4.0ₜ

The MIS size of the mapped KSG graph is much larger

missize_petersen_ksg = solve(GenericTensorNetwork(IndependentSet(SimpleGraph(petersen_res.grid_graph))), SizeMax())[]
92.0ₜ

The difference in the MIS size is:

petersen_res.mis_overhead
88

Find an MIS of the mapped KSG and map it back an MIS on the source graph.

mis_petersen_ksg = solve(GenericTensorNetwork(IndependentSet(SimpleGraph(petersen_res.grid_graph))), SingleConfigMax())[].c.data

mis_petersen = UnitDiskMapping.map_config_back(petersen_res, collect(mis_petersen_ksg))
10-element Vector{Int64}:
 1
 0
 0
 1
 0
 0
 1
 1
 0
 0

The obtained solution is an independent set and its size is maximized.

UnitDiskMapping.is_independent_set(petersen, mis_petersen)

count(isone, mis_petersen)
4

The number printed should be consistent with the MIS size of the petersen graph.

Extension: ProblemReductions

Unit-disk mapping implements the unified interface for reduction in package ProblemReductions.jl as an extension.

Step 1: perform the problem reduction.

source_problem = IndependentSet(smallgraph(:petersen))
ProblemReductions.IndependentSet{Graphs.SimpleGraphs.SimpleGraph{Int64}, Int64, ProblemReductions.UnitWeight}(Graphs.SimpleGraphs.SimpleGraph{Int64}(15, [[2, 5, 6], [1, 3, 7], [2, 4, 8], [3, 5, 9], [1, 4, 10], [1, 8, 9], [2, 9, 10], [3, 6, 10], [4, 6, 7], [5, 7, 8]]), [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

the Independent set problem with 2D GridGraph topology, unweighted.

target_problem_type = IndependentSet{ProblemReductions.GridGraph{2}, Int, UnitWeight}
ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int64, ProblemReductions.UnitWeight}

the result not only contains the target problem, but also the intermediate information

reduction_result = reduceto(target_problem_type, source_problem)

target_problem(reduction_result)
ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int64, ProblemReductions.UnitWeight}(ProblemReductions.GridGraph{2}([(8, 8), (8, 9), (4, 10), (8, 10), (9, 10), (3, 11), (5, 11), (6, 11), (7, 11), (8, 11)  …  (14, 39), (15, 39), (16, 39), (17, 39), (18, 39), (19, 39), (21, 39), (22, 39), (23, 39), (20, 40)], 1.5), [1, 1, 1, 1, 1, 1, 1, 1, 1, 1  …  1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

Step 2: solve the target problem.

get single maximum independent set of the mapped problem

config = solve(GenericTensorNetwork(target_problem(reduction_result)), SingleConfigMax())[].c.data
01000110100100001110000110101010100000111100000111101010100000001111100000000101101010101010001000000001011010001001010110010101000100010001001010111000001111000100011111000011110001010100011110001110101010101010100101

Step 3. Extract the solution back

extracted_config = extract_solution(reduction_result, config)
10-element Vector{Int64}:
 0
 0
 1
 0
 1
 1
 1
 0
 0
 0

finally, we check the validity of the solution.

UnitDiskMapping.is_independent_set(source_problem.graph, extracted_config)
true

This page was generated using Literate.jl.