---
title: "Getting Started with ShortForm"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting Started with ShortForm}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Overview

**ShortForm** is an R package for constructing short-form assessments
from larger item banks using reproducible, optimization-based
workflows.

It provides implementations of three metaheuristic search algorithms
to automate item selection while preserving prespecified psychometric
properties (such as model fit):

- **Ant Colony Optimization** (`antColony()`) -- adapted from
  [Leite, Huang, & Marcoulides (2008)](https://doi.org/10.1080/00273170802285743)
- **Simulated Annealing** (`simulatedAnnealing()`) -- following
  [Kirkpatrick et al. (1983)](https://doi.org/10.1126/science.220.4598.671)
- **Tabu Search** (`tabuSearch()`, and the lower-level `tabu.sem()`) --
  based on [Marcoulides & Falk (2018)](https://doi.org/10.1080/10705511.2017.1409074)

All three search over candidate short forms of a `lavaan` model,
evaluating each candidate's fit and keeping the best one found. This
vignette gives a quick tour of all three; see the dedicated vignettes
(`vignette("antColony")`, `vignette("simulatedAnnealing")`,
`vignette("tabuSearch")`) for a deeper look at each one.

## When to use ShortForm

- Reducing assessment length while maintaining measurement validity
- Automating item selection for large-scale assessments
- Building reproducible pipelines for psychometric modeling and evaluation

## A shared workflow

All three algorithms follow the same general shape:

1. **Specify the full model** -- lavaan syntax for the item bank you're
   reducing, with every candidate item already listed under its factor.
2. **Choose how many items to keep per factor**, and (for
   `simulatedAnnealing()`/`tabuSearch()`) which fit measure or custom
   function to optimize.
3. **Run the algorithm** -- it searches candidate short forms and keeps
   track of the best one found.
4. **Inspect the result** -- every algorithm returns an S4 object with
   `show()`/`summary()`/`plot()` methods.

```{r setup}
library(ShortForm)
```

## Quick example: Ant Colony Optimization

```{r quick-example-ACO}
set.seed(58310)

result_ACO <- antColony(
  data = lavaan::HolzingerSwineford1939,
  ants = 2, evaporation = 0.7,
  initialModel = " visual  =~ x1 + x2 + x3
                   textual =~ x4 + x5 + x6
                   speed   =~ x7 + x8 + x9 ",
  itemsPerFactor = c(3, 3, 3),
  steps = 2, fit.indices = c("cfi"), fit.statistics.test = "(cfi > 0.6)",
  maxIterations = 2, parallel = FALSE, verbose = FALSE
)

result_ACO
```

## Quick example: Simulated Annealing

```{r quick-example-SA}
set.seed(58310)

result_SA <- suppressWarnings(simulatedAnnealing(
  initialModel = " visual  =~ x1 + x2 + x3
                   textual =~ x4 + x5 + x6
                   speed   =~ x7 + x8 + x9 ",
  originalData = lavaan::HolzingerSwineford1939,
  maxIterations = 3,
  criterion = "cfi", negateCriterion = TRUE,
  itemsPerFactor = c(2, 2, 2),
  items = paste0("x", 1:9)
))

result_SA
```

## Quick example: Tabu Search

```{r quick-example-TS}
set.seed(58310)

shortAntModel <- "
Ability =~ Item1 + Item2 + Item3 + Item4 + Item5 + Item6 + Item7 + Item8
Ability ~ Outcome
"

result_TS <- tabuSearch(
  initialModel = shortAntModel,
  originalData = simulated_test_data, itemsPerFactor = 7,
  maxIterations = 3, tabu.size = 3, parallel = FALSE
)

result_TS
```

## Which algorithm should I use?

There's no universally "best" choice -- all three are heuristic
searches, so it's reasonable to try more than one and compare results.
A few practical differences:

- **Ant Colony Optimization** evaluates many candidate short forms
  ("ants") per iteration and is naturally parallel-friendly; it's a
  good default when you can afford to evaluate a lot of candidate
  models and want a threshold-based fit criterion (e.g. "CFI > 0.95
  AND RMSEA < 0.06") rather than a single scalar to optimize.
- **Simulated Annealing** explores one candidate at a time per chain
  but can accept a worse candidate with some probability (shrinking
  over time), which helps it escape local optima; running multiple
  parallel chains (`setChains`) gives several independent searches to
  compare.
- **Tabu Search** also explores one candidate at a time, but instead
  of accepting worse candidates, it forbids revisiting recently-tried
  changes (the "tabu" list) to avoid cycling back to the same local
  optimum.

## Outputs

Every algorithm returns an S4 object with:

- `show()`/`print()` -- a compact summary: run time, the selected
  criterion and its final-model value, the function call, and the
  final model syntax
- `summary()` -- the above plus the full `lavaan` fit output
- `plot()` -- a visualization of how the search progressed (fit over
  iterations/steps, or ACO's pheromone/regression diagnostics)

```{r outputs}
plot(result_TS)
```
