Skip to content

Commit b3cf8dc

Browse files
authored
[WIP] fix config feature add (#40)
* fix config feature add * vertices fixed feature for all graph problem
1 parent 2ebb1bf commit b3cf8dc

16 files changed

+135
-50
lines changed

docs/src/ref.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ terms
2828
flavors
2929
get_weights
3030
nflavor
31+
fixedvertices
3132
```
3233

3334
#### Graph Problem Utilities

src/GenericTensorNetworks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export line_graph
3030

3131
# Tensor Networks (Graph problems)
3232
export GraphProblem, optimize_code, NoWeight
33-
export flavors, labels, terms, nflavor, get_weights
33+
export flavors, labels, terms, nflavor, get_weights, fixedvertices
3434
export IndependentSet, mis_compactify!, is_independent_set
3535
export MaximalIS, is_maximal_independent_set
3636
export MaxCut, cut_size

src/networks/Coloring.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,29 @@ struct Coloring{K,CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProble
1010
code::CT
1111
graph::SimpleGraph{Int}
1212
weights::WT
13+
fixedvertices::Dict{Int,Int}
1314
end
14-
Coloring{K}(code::ET, graph::SimpleGraph, weights::Union{NoWeight, Vector}) where {K,ET<:AbstractEinsum} = Coloring{K,ET,typeof(weights)}(code, graph, weights)
15+
Coloring{K}(code::ET, graph::SimpleGraph, weights::Union{NoWeight, Vector}, fixedvertices::Dict{Int,Int}) where {K,ET<:AbstractEinsum} = Coloring{K,ET,typeof(weights)}(code, graph, weights, fixedvertices)
1516
# same network layout as independent set.
16-
function Coloring{K}(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing) where K
17+
function Coloring{K}(g::SimpleGraph; weights=NoWeight(), openvertices=(), fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing) where K
1718
@assert weights isa NoWeight || length(weights) == ne(g)
1819
rawcode = EinCode(([[i] for i in Graphs.vertices(g)]..., # labels for vertex tensors
1920
[[minmax(e.src,e.dst)...] for e in Graphs.edges(g)]...), collect(Int, openvertices)) # labels for edge tensors
20-
code = _optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier)
21-
Coloring{K}(code, g, weights)
21+
code = _optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier)
22+
Coloring{K}(code, g, weights, fixedvertices)
2223
end
2324

2425
flavors(::Type{<:Coloring{K}}) where K = collect(0:K-1)
2526
get_weights(c::Coloring{K}, i::Int) where K = fill(c.weights[i], K)
2627
terms(gp::Coloring) = getixsv(gp.code)[1:nv(gp.graph)]
2728
labels(gp::Coloring) = [1:nv(gp.graph)...]
29+
fixedvertices(gp::Coloring) = gp.fixedvertices
2830

2931
function generate_tensors(x::T, c::Coloring{K}) where {K,T}
3032
ixs = getixsv(c.code)
31-
return vcat(add_labels!([coloringv(T, K) for i=1:nv(c.graph)], ixs[1:nv(c.graph)], labels(c)), [coloringb(x, K) .^ get_weights(c, i) for i=1:ne(c.graph)])
33+
return select_dims(vcat(
34+
add_labels!([coloringv(T, K) for i=1:nv(c.graph)], ixs[1:nv(c.graph)], labels(c)), [coloringb(x, K) .^ get_weights(c, i) for i=1:ne(c.graph)]
35+
), ixs, fixedvertices(c))
3236
end
3337

3438
# coloring bond tensor

src/networks/DominatingSet.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,27 @@ struct DominatingSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphPro
1111
code::CT
1212
graph::SimpleGraph{Int}
1313
weights::WT
14+
fixedvertices::Dict{Int,Int}
1415
end
1516

16-
function DominatingSet(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
17+
function DominatingSet(g::SimpleGraph; weights=NoWeight(), openvertices=(), fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing)
1718
@assert weights isa NoWeight || length(weights) == nv(g)
1819
rawcode = EinCode(([[Graphs.neighbors(g, v)..., v] for v in Graphs.vertices(g)]...,), collect(Int, openvertices))
19-
DominatingSet(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), g, weights)
20+
DominatingSet(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), g, weights, fixedvertices)
2021
end
2122

2223
flavors(::Type{<:DominatingSet}) = [0, 1]
2324
get_weights(gp::DominatingSet, i::Int) = [0, gp.weights[i]]
2425
terms(gp::DominatingSet) = getixsv(gp.code)
2526
labels(gp::DominatingSet) = [1:length(getixsv(gp.code))...]
27+
fixedvertices(gp::DominatingSet) = gp.fixedvertices
2628

2729
function generate_tensors(x::T, mi::DominatingSet) where T
2830
ixs = getixsv(mi.code)
2931
isempty(ixs) && return []
30-
return add_labels!(map(enumerate(ixs)) do (i, ix)
32+
return select_dims(add_labels!(map(enumerate(ixs)) do (i, ix)
3133
dominating_set_tensor((Ref(x) .^ get_weights(mi, i))..., length(ix))
32-
end, ixs, labels(mi))
34+
end, ixs, labels(mi)), ixs, fixedvertices(mi))
3335
end
3436
function dominating_set_tensor(a::T, b::T, d::Int) where T
3537
t = zeros(T, fill(2, d)...)

src/networks/IndependentSet.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,31 @@ struct IndependentSet{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphPr
1212
code::CT
1313
graph::SimpleGraph{Int}
1414
weights::WT
15+
fixedvertices::Dict{Int,Int}
1516
end
1617

17-
function IndependentSet(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
18+
function IndependentSet(g::SimpleGraph; weights=NoWeight(), openvertices=(), fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing)
1819
@assert weights isa NoWeight || length(weights) == nv(g)
1920
rawcode = EinCode([[[i] for i in Graphs.vertices(g)]..., # labels for vertex tensors
2021
[[minmax(e.src,e.dst)...] for e in Graphs.edges(g)]...], collect(Int, openvertices)) # labels for edge tensors
21-
code = _optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier)
22-
IndependentSet(code, g, weights)
22+
code = _optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier)
23+
IndependentSet(code, g, weights, fixedvertices)
2324
end
2425

2526
flavors(::Type{<:IndependentSet}) = [0, 1]
2627
get_weights(gp::IndependentSet, i::Int) = [0, gp.weights[i]]
2728
terms(gp::IndependentSet) = getixsv(gp.code)[1:nv(gp.graph)]
2829
labels(gp::IndependentSet) = [1:nv(gp.graph)...]
30+
fixedvertices(gp::IndependentSet) = gp.fixedvertices
2931

3032
# generate tensors
3133
function generate_tensors(x::T, gp::IndependentSet) where T
3234
nv(gp.graph) == 0 && return []
3335
ixs = getixsv(gp.code)
3436
# we only add labels at vertex tensors
35-
return vcat(add_labels!([misv(Ref(x) .^ get_weights(gp, i)) for i=1:nv(gp.graph)], ixs[1:nv(gp.graph)], labels(gp)),
37+
return select_dims(vcat(add_labels!([misv(Ref(x) .^ get_weights(gp, i)) for i=1:nv(gp.graph)], ixs[1:nv(gp.graph)], labels(gp)),
3638
[misb(T, length(ix)) for ix in ixs[nv(gp.graph)+1:end]] # if n!=2, it corresponds to set packing problem.
37-
)
39+
), ixs, fixedvertices(gp))
3840
end
3941

4042
function misb(::Type{T}, n::Integer=2) where T

src/networks/Matching.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,23 @@ struct Matching{CT<:AbstractEinsum, WT<:Union{NoWeight,Vector}} <: GraphProblem
1010
code::CT
1111
graph::SimpleGraph{Int}
1212
weights::WT
13+
fixedvertices::Dict{Int,Int}
1314
end
1415

15-
function Matching(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
16+
function Matching(g::SimpleGraph; weights=NoWeight(), openvertices=(),fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing)
1617
@assert weights isa NoWeight || length(weights) == ne(g)
1718
edges = [minmax(e.src,e.dst) for e in Graphs.edges(g)]
1819
rawcode = EinCode(vcat([[s] for s in edges], # labels for edge tensors
1920
[[minmax(i,j) for j in neighbors(g, i)] for i in Graphs.vertices(g)]),
2021
collect(Tuple{Int,Int}, openvertices))
21-
Matching(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), g, weights)
22+
Matching(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), g, weights, fixedvertices)
2223
end
2324

2425
flavors(::Type{<:Matching}) = [0, 1]
2526
get_weights(m::Matching, i::Int) = [0, m.weights[i]]
2627
terms(gp::Matching) = getixsv(gp.code)[1:ne(gp.graph)]
2728
labels(gp::Matching) = getindex.(terms(gp))
29+
fixedvertices(gp::Matching) = gp.fixedvertices
2830

2931
function generate_tensors(x::T, m::Matching) where T
3032
ne(m.graph) == 0 && return []
@@ -40,7 +42,7 @@ function generate_tensors(x::T, m::Matching) where T
4042
end
4143
push!(tensors, t)
4244
end
43-
return add_labels!(tensors, ixs, labels(m))
45+
return select_dims(add_labels!(tensors, ixs, labels(m)), ixs, fixedvertices(m))
4446
end
4547

4648
function match_tensor(::Type{T}, n::Int) where T

src/networks/MaxCut.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,28 @@ struct MaxCut{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
1111
code::CT
1212
graph::SimpleGraph{Int}
1313
weights::WT
14+
fixedvertices::Dict{Int,Int}
1415
end
15-
function MaxCut(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
16+
function MaxCut(g::SimpleGraph; weights=NoWeight(), openvertices=(), fixedvertices=Dict{Int,Int}(), optimizer=GreedyMethod(), simplifier=nothing)
1617
@assert weights isa NoWeight || length(weights) == ne(g)
1718
rawcode = EinCode([[minmax(e.src,e.dst)...] for e in Graphs.edges(g)], collect(Int, openvertices)) # labels for edge tensors
18-
MaxCut(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), g, weights)
19+
MaxCut(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), g, weights, fixedvertices)
1920
end
2021

2122
flavors(::Type{<:MaxCut}) = [0, 1]
2223
get_weights(gp::MaxCut, i::Int) = [0, gp.weights[i]]
2324
terms(gp::MaxCut) = getixsv(gp.code)
2425
labels(gp::MaxCut) = [1:nv(gp.graph)...]
26+
fixedvertices(gp::MaxCut) = gp.fixedvertices
2527

2628
function generate_tensors(x::T, gp::MaxCut) where T
2729
ixs = getixsv(gp.code)
28-
return add_labels!(map(enumerate(ixs)) do (i, ix)
30+
tensors = map(enumerate(ixs)) do (i, ix)
2931
maxcutb((Ref(x) .^ get_weights(gp, i)) ...)
30-
end, ixs, labels(gp))
32+
end
33+
return select_dims(add_labels!(tensors, ixs, labels(gp)), ixs, fixedvertices(gp))
3134
end
35+
3236
function maxcutb(a, b)
3337
return [a b; b a]
3438
end

src/networks/MaximalIS.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,27 @@ struct MaximalIS{CT<:AbstractEinsum,WT<:Union{NoWeight, Vector}} <: GraphProblem
1010
code::CT
1111
graph::SimpleGraph
1212
weights::WT
13+
fixedvertices::Dict{Int,Int}
1314
end
1415

15-
function MaximalIS(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
16+
function MaximalIS(g::SimpleGraph; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing, fixedvertices=Dict{Int,Int}())
1617
@assert weights isa NoWeight || length(weights) == nv(g)
1718
rawcode = EinCode(([[Graphs.neighbors(g, v)..., v] for v in Graphs.vertices(g)]...,), collect(Int, openvertices))
18-
MaximalIS(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), g, weights)
19+
MaximalIS(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), g, weights, fixedvertices)
1920
end
2021

2122
flavors(::Type{<:MaximalIS}) = [0, 1]
2223
get_weights(gp::MaximalIS, i::Int) = [0, gp.weights[i]]
2324
terms(gp::MaximalIS) = getixsv(gp.code)
2425
labels(gp::MaximalIS) = [1:length(getixsv(gp.code))...]
26+
fixedvertices(gp::MaximalIS) = gp.fixedvertices
2527

2628
function generate_tensors(x::T, mi::MaximalIS) where T
2729
ixs = getixsv(mi.code)
2830
isempty(ixs) && return []
29-
return add_labels!(map(enumerate(ixs)) do (i, ix)
31+
return select_dims(add_labels!(map(enumerate(ixs)) do (i, ix)
3032
maximal_independent_set_tensor((Ref(x) .^ get_weights(mi, i))..., length(ix))
31-
end, ixs, labels(mi))
33+
end, ixs, labels(mi)), ixs, fixedvertices(mi))
3234
end
3335
function maximal_independent_set_tensor(a::T, b::T, d::Int) where T
3436
t = zeros(T, fill(2, d)...)

src/networks/PaintShop.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,39 @@ struct PaintShop{CT<:AbstractEinsum,LT} <: GraphProblem
3131
code::CT
3232
sequence::Vector{LT}
3333
isfirst::Vector{Bool}
34+
fixedvertices::Dict{LT,Int}
3435
end
3536

36-
function paintshop_from_pairs(pairs::AbstractVector{Tuple{Int,Int}}; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing)
37+
function paintshop_from_pairs(pairs::AbstractVector{Tuple{Int,Int}}; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing, fixedvertices=Dict{LT,Int}())
3738
n = length(pairs)
3839
@assert sort!(vcat(collect.(pairs)...)) == collect(1:2n)
3940
sequence = zeros(Int, 2*n)
4041
@inbounds for i=1:n
4142
sequence[pairs[i]] .= i
4243
end
43-
return PaintShop(pairs; openvertices, optimizer, simplifier)
44+
return PaintShop(pairs; openvertices, optimizer, simplifier, fixedvertices)
4445
end
45-
function PaintShop(sequence::AbstractVector{T}; openvertices=(), optimizer=GreedyMethod(), simplifier=nothing) where T
46+
function PaintShop(sequence::AbstractVector{T}; openvertices=(), fixedvertices=Dict{T,Int}(), optimizer=GreedyMethod(), simplifier=nothing) where T
4647
@assert all(l->count(==(l), sequence)==2, sequence)
4748
n = length(sequence)
4849
isfirst = [findfirst(==(sequence[i]), sequence) == i for i=1:n]
4950
rawcode = EinCode(vcat(
5051
[[sequence[i], sequence[i+1]] for i=1:n-1], # labels for edge tensors
5152
),
5253
collect(T, openvertices))
53-
PaintShop(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), sequence, isfirst)
54+
PaintShop(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), sequence, isfirst, fixedvertices)
5455
end
5556

5657
flavors(::Type{<:PaintShop}) = [0, 1]
5758
get_weights(::PaintShop, i::Int) = [0, 1]
5859
terms(gp::PaintShop) = getixsv(gp.code)
5960
labels(gp::PaintShop) = unique(gp.sequence)
61+
fixedvertices(gp::PaintShop) = gp.fixedvertices
6062

6163
function generate_tensors(x::T, c::PaintShop) where T
6264
ixs = getixsv(c.code)
6365
tensors = [paintshop_bond_tensor((Ref(x) .^ get_weights(c, i))...) for i=1:length(ixs)]
64-
return add_labels!([flip_labels(tensors[i], c.isfirst[i], c.isfirst[i+1]) for i=1:length(ixs)], ixs, labels(c))
66+
return select_dims(add_labels!([flip_labels(tensors[i], c.isfirst[i], c.isfirst[i+1]) for i=1:length(ixs)], ixs, labels(c)), ixs, fixedvertices(c))
6567
end
6668

6769
function paintshop_bond_tensor(a::T, b::T) where T

src/networks/Satisfiability.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,19 @@ struct Satisfiability{CT<:AbstractEinsum,T,WT<:Union{NoWeight, Vector}} <: Graph
120120
code::CT
121121
cnf::CNF{T}
122122
weights::WT
123+
fixedvertices::Dict{T,Int}
123124
end
124125

125-
function Satisfiability(cnf::CNF{T}; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing) where T
126+
function Satisfiability(cnf::CNF{T}; weights=NoWeight(), openvertices=(), optimizer=GreedyMethod(), simplifier=nothing, fixedvertices=Dict{T,Int}()) where T
126127
rawcode = EinCode([[getfield.(c.vars, :name)...] for c in cnf.clauses], collect(T, openvertices))
127-
Satisfiability(_optimize_code(rawcode, uniformsize(rawcode, 2), optimizer, simplifier), cnf, weights)
128+
Satisfiability(_optimize_code(rawcode, uniformsize_fix(rawcode, 2, fixedvertices), optimizer, simplifier), cnf, weights, fixedvertices)
128129
end
129130

130131
flavors(::Type{<:Satisfiability}) = [0, 1] # false, true
131132
get_weights(s::Satisfiability, i::Int) = [0, s.weights[i]]
132133
terms(gp::Satisfiability) = getixsv(gp.code)
133134
labels(gp::Satisfiability) = unique!(vcat(getixsv(gp.code)...))
135+
fixedvertices(gp::Satisfiability) = gp.fixedvertices
134136

135137
"""
136138
satisfiable(cnf::CNF, config::AbstractDict)
@@ -152,9 +154,14 @@ function generate_tensors(x::VT, sa::Satisfiability{CT,T}) where {CT,T,VT}
152154
cnf = sa.cnf
153155
ixs = getixsv(sa.code)
154156
isempty(cnf.clauses) && return []
155-
return add_labels!(map(1:length(cnf.clauses)) do i
156-
tensor_for_clause(cnf.clauses[i], (Ref(x) .^ get_weights(sa, i))...)
157-
end, ixs, labels(sa))
157+
return select_dims(
158+
add_labels!(
159+
map(1:length(cnf.clauses)) do i
160+
tensor_for_clause(cnf.clauses[i], (Ref(x) .^ get_weights(sa, i))...)
161+
end,
162+
ixs, labels(sa))
163+
, ixs, fixedvertices(sa)
164+
)
158165
end
159166

160167
function tensor_for_clause(c::CNFClause{T}, a, b) where T

0 commit comments

Comments
 (0)