feat: Add PATH-Algorithm feature for graph matching - #39
Conversation
bc5fc57 to
0532c10
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #39 +/- ##
===========================================
- Coverage 98.33% 80.18% -18.15%
===========================================
Files 8 11 +3
Lines 180 434 +254
===========================================
+ Hits 177 348 +171
- Misses 3 86 +83 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| function isPerm(P) | ||
| return all(x -> x == 0.0 || x == 1.0, P) | ||
| end |
There was a problem hiding this comment.
This function already exits in utils.jl see:
Line 41 in 507c91f
| function permMtV(P) | ||
| return [argmax(row) for row in eachrow(P)] | ||
| end | ||
|
|
||
| # returns the permutation matrix of a permutation vector P | ||
| function permVtM(P) | ||
| return Matrix{Float64}(I(length(P))[P, :]) | ||
| end | ||
|
|
| function sqd_frob(A) | ||
| val = norm(A, 2) | ||
| return val^2 | ||
| end |
| function diagonal_degree(G) | ||
| D = zeros(size(G)) | ||
| for j in 1:size(D, 1) | ||
| sum = 0.0 | ||
| for i in 1:size(D, 1) | ||
| sum += G[i, j] | ||
| end | ||
| D[j, j] = sum | ||
| end | ||
| return D | ||
| end |
| function laplacian(G) | ||
| return diagonal_degree(G) .- G | ||
| end |
| 0.1, | ||
| ) | ||
| @test P == [1, 2] | ||
|
|
There was a problem hiding this comment.
Add tesst also for smaller functions
| using MathOptInterface: OPTIMAL | ||
| using SparseArrays: sparse | ||
| using OptimalTransport: sinkhorn | ||
| using FrankWolfe |
There was a problem hiding this comment.
import just the function you are using
| - `log_string::Union{String, Nothing}`: Formatted summary string if `return_log=true`, otherwise `nothing`. | ||
| - `dataPoints::Union{NamedTuple, Nothing}`: `NamedTuple` containing `λ_list`, `f0_list`, `f1_list`, and `fλ_list` if `return_dataPoints=true`, otherwise `nothing`. | ||
| """ | ||
| function pathAlgorithm( |
There was a problem hiding this comment.
Break this function in little blocks
| log_stream = IOBuffer() | ||
| if return_log | ||
| function write_log(msg) | ||
| return println(log_stream, msg) # Schreibt in den Buffer | ||
| end | ||
|
|
||
| write_log("="^60) | ||
| write_log("Results for Graph Matching/QAP") | ||
| write_log("="^60) | ||
| write_log("") | ||
| write_log("ϵ_λ_f: $(ϵ_λ_f)") | ||
| write_log("ϵ_λ_p: $(ϵ_λ_p)") | ||
| write_log("solveQAP: $(solveQAP)") | ||
| write_log("") | ||
| write_log("Runtime: $(elapsed_time) seconds") | ||
| write_log("λ Iterations: $(count_iter)") | ||
| write_log("") | ||
| write_log("Cost:") | ||
| if !solveQAP | ||
| write_log("F0: $(f0(p_opt, G, H))") | ||
| write_log("F1: $(f1(p_opt, G, H))") | ||
| else | ||
| write_log("$(qapVal(p_opt, G, H))") | ||
| end | ||
| write_log("") | ||
| write_log("-"^60) | ||
| write_log("Resulting Matrix P") | ||
| write_log("-"^60) | ||
| write_log(p_vec) | ||
| end | ||
| log_string = return_log ? String(take!(log_stream)) : nothing | ||
|
|
||
| dataPoints = if return_dataPoints | ||
| (; λ_list=λ_list, f0_list=f0_list, f1_list=f1_list, fλ_list=fλ_list) |
In this PR a graph matching algorithm is implemented based on M. Zaslavskiy, F. Bach and J. -P. Vert, "A Path Following Algorithm for the Graph Matching Problem," in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 31, no. 12, pp. 2227-2242, Dec. 2009, doi: 10.1109/TPAMI.2008.245.
On the examples of the QAP that are mentioned in the paper this implementation yields feasible results. On Chr15a and Chr15c from https://qaplib.mgi.polymtl.ca/ it yields worse values then are listed in the paper, but on all others (Tai10a can not be found) this implementation finds a much better approximation in a feasible runtime when run with precision values of 1/10.
As I don't have much experience with writing pulishable code I'm hoping to get helpful feedback. Thank you in advance.