## ----setup, include = FALSE---------------------------------------------------
# Global chunk options. Each example must be reproducible, so a fixed
# random seed is set at every code block that involves stochastic steps.
knitr::opts_chunk$set(
  collapse = TRUE,
  comment  = "#>",
  fig.align = "center",
  warning   = FALSE,
  message   = FALSE
)

## ----citation, eval = FALSE---------------------------------------------------
# citation("momst")

## ----install, eval = FALSE----------------------------------------------------
# # install.packages("remotes")
# remotes::install_github("jorgeklz/momst", build_vignettes = TRUE)

## ----load---------------------------------------------------------------------
library(momst)

## ----instance-----------------------------------------------------------------
# Number of nodes and number of objectives
n_nodes   <- 10
n_obj     <- 2

# Generate a complete graph with two independent weights per edge
inst <- generate_instance(
  n        = n_nodes,
  num_obj  = n_obj,
  range_a  = c(10, 100),   # weight range for objective 1
  range_b  = c(10,  50),   # weight range for objective 2
  seed     = 12345
)

# The instance has n*(n-1)/2 edges
nrow(inst)

# First six edges of the complete graph
head(inst)

## ----lookup-------------------------------------------------------------------
lk <- build_weight_lookup(inst, n_nodes, n_obj)

# Each element is a symmetric weight matrix
str(lk, max.level = 1)

# Weight of edge (1, 2) in objective 1
lk[[1]][1, 2]

## ----run-base-----------------------------------------------------------------
res_base <- run_momst(
  instance        = inst,
  n               = n_nodes,
  num_obj         = n_obj,
  variant         = "base",      # pure NSGA-II
  iterations      = 3,           # three independent runs
  pop_size        = 30,          # must be even
  tour_size       = 2,           # binary tournament selection
  cross_rate      = 0.80,        # crossover probability
  mut_rate        = 0.10,        # per-individual mutation probability
  max_generations = 40,          # generations per run
  convergence_window = 8,        # early stopping window
  verbose         = FALSE,
  seed            = 2026
)

## ----structure----------------------------------------------------------------
names(res_base)

## ----front-base---------------------------------------------------------------
# Number of non-dominated trees
nrow(res_base$global_pareto)

# Show the chromosomes and their objective values
res_base$global_pareto

## ----front-sorted-------------------------------------------------------------
front <- res_base$global_pareto[order(res_base$global_pareto$objective_1), ]
front[, c("objective_1", "objective_2")]

## ----extremes-----------------------------------------------------------------
# Best tree for objective 1
front[which.min(front$objective_1), c("objective_1", "objective_2")]

# Best tree for objective 2
front[which.min(front$objective_2), c("objective_1", "objective_2")]

## ----plot-front-base, fig.cap = "Global Pareto front returned by the base variant."----
plot_pareto_front(res_base)

## ----best-tree, fig.cap = "Best-compromise spanning tree of the base variant.", fig.width = 6, fig.height = 6----
if (requireNamespace("igraph", quietly = TRUE)) {
  plot_best_tree(res_base, n = n_nodes)
} else {
  message("Install 'igraph' to plot the spanning tree.")
}

## ----run-3obj-----------------------------------------------------------------
res_3obj <- run_momst(
  n               = 8,
  num_obj         = 3,
  variant         = "base",
  iterations      = 2,
  pop_size        = 30,
  max_generations = 25,
  range_a         = c(10, 100),
  range_b         = c(10,  50),
  range_c         = c(30, 200),
  verbose         = FALSE,
  seed            = 7
)

# Three-objective non-dominated set
head(res_3obj$global_pareto[, c("objective_1", "objective_2", "objective_3")])

## ----pairs-plot, fig.cap = "Pairwise projections of the three-objective Pareto front.", fig.width = 6, fig.height = 6----
front3 <- res_3obj$global_pareto[, c("objective_1", "objective_2", "objective_3")]
pairs(front3, pch = 19, col = "steelblue")

## ----reproducibility----------------------------------------------------------
a <- run_momst(n = 8, num_obj = 2, variant = "base",
               iterations = 1, pop_size = 20, max_generations = 15,
               verbose = FALSE, seed = 99)

b <- run_momst(n = 8, num_obj = 2, variant = "base",
               iterations = 1, pop_size = 20, max_generations = 15,
               verbose = FALSE, seed = 99)

identical(a$global_pareto, b$global_pareto)

