Skip to content

Commit

Permalink
Add QUBOTools support
Browse files Browse the repository at this point in the history
  • Loading branch information
pedromxavier committed Nov 3, 2022
1 parent 40d4889 commit 001ed9f
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
align_assignment = true
align_pair_arrow = true
align_matrix = true
align_matrix = true
2 changes: 1 addition & 1 deletion src/analysis/analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function QUBOTools.backend(model::VirtualQUBOModel{T}) where {T}
c = a.coefficient
x = a.variable

L[x] = get(L, x, zero(T)) + c
L[x] = get(L, x, zero(T)) + c
end

offset = f.constant
Expand Down
7 changes: 6 additions & 1 deletion src/compiler/objective.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
function toqubo_sense!(model::VirtualQUBOModel, ::AbstractArchitecture)
MOI.set(model.target_model, MOI.ObjectiveSense(), MOI.get(model, MOI.ObjectiveSense()))
if MOI.get(model, MOI.ObjectiveSense()) === MOI.MAX_SENSE
MOI.set(model.target_model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
else
# Feasibility is interpreted as minimization
MOI.set(model.target_model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
end

return nothing
end
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/penalties.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function toqubo_penalties!(model::VirtualQUBOModel{T}, ::AbstractArchitecture) where {T}
# -*- :: Invert Sign:: -*- #
# -*- :: Invert Sign :: -*- #
s = MOI.get(model, MOI.ObjectiveSense()) === MOI.MAX_SENSE ? -1 : 1

β = one(T) # TODO: This should be made a parameter too? Yes!
Expand Down
4 changes: 2 additions & 2 deletions src/model/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ MOIU.@model(PreQUBOModel, # Name of model
# :: Drop Automatic Constraint Support :: #
MOI.supports_constraint(
::PreQUBOModel{T},
::Type{<:Union{SAF, SQF}},
::Type{<:Union{MOI.Integer, MOI.ZeroOne, GT}},
::Type{<:Union{SAF{T}, SQF{T}}},
::Type{<:Union{GT{T}}},
) where {T} = false

# -*- Model: QUBOModel -*-
Expand Down
6 changes: 4 additions & 2 deletions src/model/virtual.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct VirtualQUBOModel{T} <: VM.AbstractVirtualModel{T}
f::PBO.PBF{VI, T} # Objective Function
g::Dict{CI, PBO.PBF{VI, T}} # Problem Constraints
h::Dict{VI, PBO.PBF{VI, T}} # Variable Encoding Constraints
ρ::Dict{Union{CI, VI}, T} # Penalties
ρ::Dict{Union{CI, VI}, T} # Penalties

# -*- Attributes -*-
attrs::VirtualQUBOModelAttributes{T}
Expand Down Expand Up @@ -67,9 +67,11 @@ end
MOI.get(model::VirtualQUBOModel, ::VM.Source) = model.source
MOI.get(model::VirtualQUBOModel, ::VM.Source, x::VI) = model.source[x]
MOI.set(model::VirtualQUBOModel{T}, ::VM.Source, x::VI, v::VM.VV{<:Any, T}) where T = (model.source[x] = v)

MOI.get(model::VirtualQUBOModel, ::VM.Target) = model.target
MOI.get(model::VirtualQUBOModel, ::VM.Target, y::VI) = model.target[y]
MOI.set(model::VirtualQUBOModel{T}, ::VM.Target, y::VI, v::VM.VV{<:Any, T}) where T = (model.target[y] = v)
MOI.get(model::VirtualQUBOModel, ::VM.Variables) = model.variables

MOI.get(model::VirtualQUBOModel, ::VM.Variables) = model.variables
MOI.get(model::VirtualQUBOModel, ::VM.SourceModel) = model.source_model
MOI.get(model::VirtualQUBOModel, ::VM.TargetModel) = model.target_model
44 changes: 28 additions & 16 deletions src/model/wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ function MOI.optimize!(model::VirtualQUBOModel)

source_model = MOI.get(model, VM.SourceModel())
target_model = MOI.get(model, VM.TargetModel())
index_map = MOIU.identity_index_map(source_model)

MOI.optimize!(model.optimizer, target_model)

index_map = MOIU.identity_index_map(source_model)

return (index_map, false)
end

Expand All @@ -42,14 +41,14 @@ function MOI.copy_to(model::VirtualQUBOModel{T}, source::MOI.ModelLike) where {T
error("QUBO Model is not empty")
end

# -*- Copy to PreQUBOModel + Trigger Bridges -*-
# -*- Copy to PreQUBOModel + Add Bridges -*- #
source_model = MOI.get(model, VM.SourceModel())
bridge_model = MOIB.full_bridge_optimizer(source_model, T)

index_map = MOI.copy_to(
MOIB.full_bridge_optimizer(source_model, T),
source,
)
# -*- Copy to source using bridges - *- #
index_map = MOI.copy_to(bridge_model, source)

# -*- JuMP to QUBO Compilation -*- #
ToQUBO.toqubo!(model)

return index_map
Expand All @@ -64,13 +63,19 @@ MOI.supports(
# -*- :: Constraint Support :: -*- #
MOI.supports_constraint(
::VirtualQUBOModel{T},
::Type{<:VI},
::Type{<:Union{MOI.ZeroOne,MOI.Integer,MOI.Interval{T}}},
::Type{VI},
::Type{<:Union{
MOI.ZeroOne,
MOI.Integer,
MOI.Interval{T},
MOI.LessThan{T},
MOI.GreaterThan{T},
}},
) where {T} = true

MOI.supports_constraint(
::VirtualQUBOModel{T},
::Type{<:Union{VI,SAF{T},SQF{T}}},
::Type{<:Union{SAF{T},SQF{T}}},
::Type{<:Union{MOI.EqualTo{T},MOI.LessThan{T}}},
) where {T} = true

Expand All @@ -82,7 +87,13 @@ MOI.supports_constraint(

MOI.supports_add_constrained_variable(
::VirtualQUBOModel{T},
::Type{<:Union{MOI.ZeroOne,MOI.Integer,MOI.Interval{T}}},
::Type{<:Union{
MOI.ZeroOne,
MOI.Integer,
MOI.Interval{T},
MOI.LessThan{T},
MOI.GreaterThan{T},
}},
) where {T} = true

function MOI.get(
Expand Down Expand Up @@ -140,9 +151,10 @@ function MOI.get(model::VirtualQUBOModel{T}, vp::MOI.VariablePrimal, x::VI) wher
if isnothing(model.optimizer)
return zero(T)
else
v = MOI.get(model, VM.Source(), x)
s = zero(T)
for (ω, c) in VM.expansion(MOI.get(model, VM.Source(), x))

for (ω, c) in VM.expansion(v)
for y in ω
c *= MOI.get(model.optimizer, vp, y)
end
Expand All @@ -154,11 +166,11 @@ function MOI.get(model::VirtualQUBOModel{T}, vp::MOI.VariablePrimal, x::VI) wher
end
end

MOI.get(::VirtualQUBOModel, ::MOI.SolverName) = "Virtual QUBO Model"
MOI.get(::VirtualQUBOModel, ::MOI.SolverVersion) = PROJECT_VERSION
MOI.get(::VirtualQUBOModel, ::MOI.SolverName) = "Virtual QUBO Model"
MOI.get(::VirtualQUBOModel, ::MOI.SolverVersion) = PROJECT_VERSION
MOI.get(model::VirtualQUBOModel, rs::MOI.RawSolver) = MOI.get(model.optimizer, rs)

PBO.showvar(x::VI) = PBO.showvar(x.value)
PBO.showvar(x::VI) = PBO.showvar(x.value)
PBO.varcmp(x::VI, y::VI) = PBO.varcmp(x.value, y.value)

const Optimizer{T} = VirtualQUBOModel{T}
8 changes: 7 additions & 1 deletion src/virtual/encoding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,13 @@ function encode!(E::Type{<:Binary}, model::AbstractVirtualModel{T}, x::Union{VI,
M = trunc(Int, β - α)
N = ceil(Int, log2(M + 1))

encode!(E, model, x, T[[2^i for i = 0:N-2];[M - 2^(N-1) + 1]], α)
γ = if N == 0
T[M + 1/2]
else
T[[2^i for i = 0:N-2];[M - 2^(N-1) + 1]]
end

encode!(E, model, x, γ, α)
end

function encode!(E::Type{<:Binary}, model::AbstractVirtualModel{T}, x::Union{VI, Nothing}, a::T, b::T, n::Integer) where T
Expand Down

0 comments on commit 001ed9f

Please sign in to comment.