From e165fd470b2cc568a3142c18a5699c5724a49cb1 Mon Sep 17 00:00:00 2001 From: harshangrjn Date: Tue, 19 Oct 2021 19:09:54 -0600 Subject: [PATCH] clean ups --- CHANGELOG.md | 1 + docs/README.md | 2 +- src/constraints.jl | 1 - src/lopt_model.jl | 52 +++++++++++++++++++------------------- src/quickguide.md | 62 ---------------------------------------------- src/relaxations.jl | 4 +-- src/solution.jl | 2 +- 7 files changed, 31 insertions(+), 93 deletions(-) delete mode 100644 src/quickguide.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e33ac56..7e0ec99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ LaplacianOpt.jl Change Log - Added CITATION.bib - Added support for Gurobi MIP solver in `examples/solver.jl` - Updated `LO` to `LOpt` +- `lopt_model.jl` function calls updated with `LOpt` - Minor docs cleanups ### v0.1.4 diff --git a/docs/README.md b/docs/README.md index 7ccdab4..c130b94 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # Documentation for LaplacianOpt.jl ## Installation -LaplacianOpt.jl's documentation is generated using [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl). To install it, run the following command in a Julia session: +LaplacianOpt's documentation is generated using [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl). To install it, run the following command in a Julia session: ```julia Pkg.add("Documenter") diff --git a/src/constraints.jl b/src/constraints.jl index abebf73..9ac3b7f 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -111,7 +111,6 @@ function constraint_eigen_cuts_on_full_matrix(W_val::Matrix{Float64}, cb_cuts, l else Memento.warn(_LOGGER, "Eigen cut corresponding to the negative eigenvalue could not be added") - end end diff --git a/src/lopt_model.jl b/src/lopt_model.jl index cf8a801..71a625e 100644 --- a/src/lopt_model.jl +++ b/src/lopt_model.jl @@ -2,41 +2,41 @@ function build_LOModel(data::Dict{String, Any}) lom = LaplacianOptModel(data) - variable_LOModel(lom) + LOpt.variable_LOModel(lom) if lom.data["solution_type"] == "exact" - constraint_LOModel(lom) + LOpt.constraint_LOModel(lom) end - objective_LOModel(lom) + LOpt.objective_LOModel(lom) return lom end function variable_LOModel(lom::LaplacianOptModel) - variable_lifted_W_matrix(lom) - variable_edge_onoff(lom) - variable_algebraic_connectivity(lom) + LOpt.variable_lifted_W_matrix(lom) + LOpt.variable_edge_onoff(lom) + LOpt.variable_algebraic_connectivity(lom) return end function constraint_LOModel(lom::LaplacianOptModel) - constraint_build_W_var_matrix(lom) + LOpt.constraint_build_W_var_matrix(lom) - constraint_topology_no_self_loops(lom) - constraint_topology_vertex_cutset(lom) - constraint_topology_total_edges(lom) + LOpt.constraint_topology_no_self_loops(lom) + LOpt.constraint_topology_vertex_cutset(lom) + LOpt.constraint_topology_total_edges(lom) - constraint_lazycallback_wrapper(lom) + LOpt.constraint_lazycallback_wrapper(lom) return end function objective_LOModel(lom::LaplacianOptModel) - objective_maximize_algebraic_connectivity(lom) + LOpt.objective_maximize_algebraic_connectivity(lom) return end @@ -70,7 +70,7 @@ function optimize_LOModel!(lom::LaplacianOptModel; optimizer=nothing) Memento.debug(_LOGGER, "JuMP model optimize time: $(time() - start_time)") - lom.result = build_LOModel_result(lom, solve_time) + lom.result = LOpt.build_LOModel_result(lom, solve_time) return lom.result end @@ -84,7 +84,7 @@ function run_LOpt_model(params::Dict{String, Any}, lom_optimizer::MOI.OptimizerW result_lopt = LOpt.optimize_LOModel!(model_lopt, optimizer = lom_optimizer) if visualize_solution - LaplacianOpt.visualize_solution(result_lopt, data, visualizing_tool = visualizing_tool) + LOpt.visualize_solution(result_lopt, data, visualizing_tool = visualizing_tool) end return result_lopt @@ -98,7 +98,7 @@ function run_MaxSpanTree_model(params::Dict{String, Any}, lom_optimizer::MOI.Opt result_mst = LOpt.optimize_LOModel!(model_mst, optimizer = lom_optimizer) if visualize_solution - LaplacianOpt.visualize_solution(result_mst, data, visualizing_tool = visualizing_tool) + LOpt.visualize_solution(result_mst, data, visualizing_tool = visualizing_tool) end return result_mst @@ -109,28 +109,28 @@ function build_MaxSpanTree_model(data::Dict{String, Any}, lazy_callback::Bool) m_mst = LaplacianOptModel(data) - variable_MaxSpanTree_model(m_mst, lazy_callback) + LOpt.variable_MaxSpanTree_model(m_mst, lazy_callback) - constraint_MaxSpanTree_model(m_mst, lazy_callback) + LOpt.constraint_MaxSpanTree_model(m_mst, lazy_callback) - objective_MaxSpanTree_model(m_mst) + LOpt.objective_MaxSpanTree_model(m_mst) return m_mst end function objective_MaxSpanTree_model(lom::LaplacianOptModel) - objective_maximize_spanning_tree_cost(lom) + LOpt.objective_maximize_spanning_tree_cost(lom) return end function variable_MaxSpanTree_model(lom::LaplacianOptModel, lazy_callback::Bool) - variable_edge_onoff(lom) + LOpt.variable_edge_onoff(lom) if !lazy_callback - variable_multi_commodity_flow(lom) + LOpt.variable_multi_commodity_flow(lom) end return @@ -138,14 +138,14 @@ end function constraint_MaxSpanTree_model(lom::LaplacianOptModel, lazy_callback::Bool) - constraint_topology_no_self_loops(lom) - constraint_topology_vertex_cutset(lom) - constraint_topology_total_edges(lom) + LOpt.constraint_topology_no_self_loops(lom) + LOpt.constraint_topology_vertex_cutset(lom) + LOpt.constraint_topology_total_edges(lom) if lazy_callback - constraint_lazycallback_wrapper(lom) + LOpt.constraint_lazycallback_wrapper(lom) else - constraint_topology_multi_commodity_flow(lom) + LOpt.constraint_topology_multi_commodity_flow(lom) end return diff --git a/src/quickguide.md b/src/quickguide.md deleted file mode 100644 index 4da868b..0000000 --- a/src/quickguide.md +++ /dev/null @@ -1,62 +0,0 @@ -# Quick Start Guide - -## Getting started - -After the installation of LaplacianOpt and CPLEX (use GLPK if open-source is preferable) from the Julia package manager, and the cost matrix of the complete graph (for example, see [`examples/instances/5_nodes`](https://github.com/harshangrjn/LaplacianOpt.jl/tree/main/examples/instances/5_nodes)) is provided in the JSON format, an optimization model to maximize the algebraic connectivity of the weighted graph's Laplacian matrix can be executed with a few lines of code as follows: - -```julia -import LaplacianOpt as LOpt -using JuMP -using CPLEX - -params = Dict{String, Any}( -"num_nodes" => 5, -"instance" => 1, -"optimizer" => "cplex" -) - -lom_optimizer = JuMP.optimizer_with_attributes(CPLEX.Optimizer) -results = LOpt.run_LOpt_model(params, lom_optimizer) -``` - -# Extracting results -The run commands (for example, `run_LOpt_model`) in LaplacianOpt return detailed results in the form of a dictionary. This dictionary can be used for further processing of the results. For example, for the given instance of a complete graph, the algorithm's runtime and the optimal objective value (maximum algebraic connectivity) can be accessed with, - -```julia -results["solve_time"] -results["objective"] -``` - -The `"solution"` field contains detailed information about the solution produced by the optimization model. -For example, one can obtain the edges of the optimal graph toplogy from the symmetric adjacency matrix with, - -```Julia -optimal_graph = LOpt.optimal_graph_edges(results["solution"]["z_var"]) -``` -Further, algebraic connectivity and the Fiedler vector of the optimal graph topology (though can be applied on any graph topology) can be obtained from the adjacency matrix with, -```Julia -optimal_adjacency = results["solution"]["z_var"] .* LOpt.get_data(params)["edge_weights"] -graph_data = LOpt.GraphData(optimal_adjacency) -println("Algebraic connectivity: ", graph_data.ac) -println("Fiedler vector: ", graph_data.fiedler) -``` - -# Visualizing results -LaplacianOpt also currently supports the visualization of optimal graphs layouts obtained from the `results` dictionary (from above. To do so, these are the two options: -+ [TikzGraphs](https://github.com/JuliaTeX/TikzGraphs.jl) package for a simple and quick visualization of the graph layout without support to include edge weights, which can be executed with - -```julia -data = LOpt.get_data(params) -LOpt.visualize_solution(results, data, visualizing_tool = "tikz") -``` - -+ [Graphviz](https://graphviz.org) package for better visualization of weighted graphs. To this end, LaplacianOpt generates the raw `.dot` file, which can be further visualized using the Graphviz software either via the direct [installation](https://graphviz.org/download/) on the computer or using an online front-end visualization GUI (for example, see [Edotor](https://edotor.net)). Dot files can be generated in LaplacianOpt with - -```julia -data = LOpt.get_data(params) -LOpt.visualize_solution(results, data, visualizing_tool = "graphviz") -``` -For example, on a weighted complete graph with 10 nodes in [instance #1](https://github.com/harshangrjn/LaplacianOpt.jl/blob/main/examples/instances/10_nodes/10_1.json), the optimal spanning tree with maximum algebraic connectivity, out of ``10^8`` feasible solutions, obtained by LaplacianOpt (using Graphviz visualization) is shown below - -![Optimal solution](assets/10_nodes_opt_1.png) - diff --git a/src/relaxations.jl b/src/relaxations.jl index b8e4f31..c282449 100644 --- a/src/relaxations.jl +++ b/src/relaxations.jl @@ -31,8 +31,8 @@ z <= JuMP.upper_bound(x)*y + JuMP.lower_bound(y)*x - JuMP.upper_bound(x)*JuMP.lo ``` """ function relaxation_bilinear(m::JuMP.Model, xy::JuMP.VariableRef, x::JuMP.VariableRef, y::JuMP.VariableRef) - lb_x, ub_x = variable_domain(x) - lb_y, ub_y = variable_domain(y) + lb_x, ub_x = LOpt.variable_domain(x) + lb_y, ub_y = LOpt.variable_domain(y) if (lb_x == 0) && (ub_x == 1) && ((lb_y != 0) || (ub_y != 1)) diff --git a/src/solution.jl b/src/solution.jl index 549004a..eca3263 100644 --- a/src/solution.jl +++ b/src/solution.jl @@ -10,7 +10,7 @@ function build_LOModel_result(lom::LaplacianOptModel, solve_time::Number) solution = Dict{String,Any}() if result_count > 0 - solution = build_LOModel_solution(lom) + solution = LOpt.build_LOModel_solution(lom) else Memento.warn(_LOGGER, "LaplacianOpt model has no results - solution cannot be built") end