LEXIMIN benchmark: CCA and HD, original and uniform-adjusted quotas
================================================================

The report LEXIMIN-results-report.pdf describes the methods and results.
Its editable LaTeX source is LEXIMIN-results-report.tex.

WHAT WAS RUN
run_leximin.py implements Algorithm 2 in SI Section 10 of Flanigan et al.
(2021), with the formal primal LP and ILP column generation (Algorithm 1).
It uses Gurobi for LP and MILP optimization. This is an implementation of
that algorithm, not a run submitted to Panelot, and not the authors' unchanged
practical dual implementation. The authors' frozen code is included under
vendor/ as a reference, with its original GPL-3.0 license and README.
No quotas or previously fixed probabilities are relaxed in the accepted runs.

REPRODUCE (Python 3.12)
  python -m venv .venv
  . .venv/bin/activate
  python -m pip install -r requirements.txt
  OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 python run_leximin.py
  OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 python analyze_results.py
  python verify_saved_files.py
  python build_report.py
  pdflatex -interaction=nonstopmode -halt-on-error LEXIMIN-results-report.tex
  pdflatex -interaction=nonstopmode -halt-on-error LEXIMIN-results-report.tex

Each command is run from the unzipped package directory. TeX Live (including
lmodern, geometry, booktabs, amsmath, microtype, hyperref, fancyhdr and graphicx)
is required only to compile the report. A Gurobi license is required to rerun
the optimization. The restricted non-production license distributed with
gurobipy sufficed for the recorded models; check the license applicable to
your installation. An academic/full license can also be used.
Analysis and verification of the provided lotteries do not require Gurobi.

A single instance may be run or analyzed by appending its name, for example:
  python run_leximin.py HD_case1_original_quotas
  python analyze_results.py HD_case1_original_quotas
The four instance names, panel sizes and sampling seeds are in instances.json.
Solver or platform changes can yield a different supporting lottery. Compare
marginal probabilities and verified quotas, not exact panel lists or timings.

INPUTS IN EACH instances/<name>/ DIRECTORY
  respondents.csv: previous experiment's respondents, including target column.
  categories.csv: exact quota instance used in this benchmark.
  targets.csv: comparison targets as exact numerator/denominator and decimal.
  profile_targets.csv and calibration_certificate.json: original-quota cases
    only; snapshot of the earlier profile calibration and exact certificate.
  theorem2_summary.json: earlier 10,000-draw Theorem 2 result, not rerun here.
  pool.csv: Panelot-compatible pool input (see below).
prepare_inputs.py documents how these inputs were snapshotted from the earlier
CCA-replication/ and HD-replication/ directories. It is NOT needed to reproduce
this package; all inputs are already included. Do not run it in isolation.

OUTPUTS IN EACH INSTANCE
  lottery.json: full generated panel portfolio, probability vector, every
    stage's primal fixed values and dual weights, solver parameters/versions.
    Zero-weight panels are retained here for an audit trail.
  lottery_support.csv: every strictly positive-weight panel with its exact
    numerical lottery weight, members and quota metrics. IDs are identifiers,
    not row offsets. Panel IDs are zero-based positions in lottery.json.
  sampled_panels.csv: 10,000 draws, including member IDs and source panel ID.
  panel_metrics.csv: each draw's mean quota violation across all listed traits,
    maximum miss, panel size, number of violated traits, and every trait count.
  marginal_comparison.csv: each respondent's target, lottery marginal,
    discrepancy (probability and percentage points), and empirical frequency.
    Marginal comparisons use the full lottery, not empirical frequencies.
  trait_results.csv: each trait's quota, pool count, target/lottery expectation,
    support count range and quota violations.
  stage_certificates.csv: each LP stage independently repriced with SciPy/HiGHS.
  summary.json: numerical results and verification diagnostics.

GLOBAL OUTPUTS
  results_summary.csv and results.json: four-instance summaries.
  verification.json: independent checks of all saved CSV panels and marginals.
  original_quota_marginals.pdf/png: report figure.
  paper-results-snippet.tex: optional dark-green paragraph for the manuscript.
  input_manifest.json: SHA-256 hashes identifying all input snapshots.
  SHA256SUMS: integrity checks for all packaged deliverables except this file.

PANELOT (OPTIONAL CROSS-CHECK; NO WEB RUN WAS PERFORMED)
For the desired instance, open https://panelot.org/compute_lottery and upload
its categories.csv as the categories file and pool.csv as the pool file.
Enter panel size 75 for CCA or 30 for HD. pool.csv uses the required identifier
header pool_member_identifier; only trait columns follow it. The comparison
targets are intentionally omitted because LEXIMIN chooses its own marginals.
The original-quota instance uses unchanged categories; the uniform instance
uses the previously adjusted categories. Save the complete returned lottery,
not just a single selected panel, for marginal-probability analysis.

SOURCE
Bailey Flanigan, Paul Goelz, Anupam Gupta, Brett Hennig, Ariel D. Procaccia.
Fair algorithms for selecting citizens' assemblies. Nature 596, 548-552 (2021).
DOI: 10.1038/s41586-021-03788-6. Supplementary Information, Sections 8 and 10.
Official reference repository:
https://github.com/pgoelz/citizensassemblies-replication
Frozen commit: 6ad2d5fb2b22dc27d66b1d6e7c93c141967802de
The numerical settings and implementation distinctions are fully described
in the report. Computation date: 10 October 2026.
