Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Food Distribution Gym

A reinforcement-learning environment built on The Farama Foundation's Gymnasium for food-distribution and food-security logistics research.

The environment models trade between cities with multiple commodities, demand and supply dynamics, price fluctuations, cash constraints, and climate and pest shocks. Agents distribute food across the network to reduce shortages.

Maintained under IROS Lab, Faculty of Computer Science (Fasilkom), Universitas Indonesia. The project is in alpha development.

Installation

From a source checkout:

git clone https://github.com/ui-iros/food-distribution-gym.git
cd food-distribution-gym
python -m pip install -e .

The distribution is named food-distribution-gym; import it as food_distribution_gym. The first alpha version is 0.1.0a1. Once that release is published on PyPI, installation without a clone will be:

python -m pip install --pre food-distribution-gym

Optional dependencies for the viewer and research scripts:

python -m pip install -e ".[render]"
python -m pip install -e ".[research]"

The base package requires Gymnasium, NumPy, and PyYAML. The render extra adds Pygame; research also includes Stable-Baselines3, PyTorch, pandas, and Matplotlib.

Isolated Environment

Use a virtual environment. On Windows PowerShell:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[research]"
.\.venv\Scripts\python.exe -m pip check

On Linux/macOS:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[research]"
python -m pip check

Use the same interpreter for installation and execution.

Repository Structure

food-distribution-gym/
|-- food_distribution_gym/       # Installable environment package
|   |-- __init__.py             # Gymnasium registration and public imports
|   |-- __main__.py             # Viewer entry point
|   |-- envs/
|   |   `-- food_security_env.py
|   |-- utils/                  # Configuration loading helpers
|   |-- config/                 # Bundled YAML scenarios
|   |-- assets/                 # Commodity, climate, and pest icons
|   `-- viewer.py               # Interactive simulation and replay
|-- scripts/                    # Training, evaluation, plotting, recording
|-- data/                       # CSV inputs for scenario generation
|-- tests/                      # Environment and installed-package checks
|-- docs/                       # Experiments and release instructions
|-- .github/workflows/          # CI and PyPI Trusted Publishing
|-- LICENSE
|-- CHANGELOG.md
|-- README.md
|-- pyproject.toml
`-- requirements.txt            # Install the research dependencies

Only food_distribution_gym/, including its scenarios and icons, is installed in the wheel. Research scripts, example CSVs, and documentation are included in the source distribution. Checkpoints and generated results are not bundled.

Experiments

Install .[research], then run scripts from the repository root:

python scripts/PPO.py --seed 42 --total-timesteps 1000000
python scripts/A2C.py --seed 42 --total-timesteps 1000000
python scripts/SAC.py --seed 42 --total-timesteps 1000000
python scripts/TD3.py --seed 42 --total-timesteps 1000000
python scripts/evaluate_and_plot.py --experiments 30
python scripts/plot_training_curves.py --algo ppo
python scripts/plot_comparison.py

All four training scripts use the bundled Indonesian six-city, two-commodity scenario by default. Models are saved under models/, CSVs and plots under outputs/, and episode recordings under episode_logs/. Generated outputs are ignored by Git. Training uses eight parallel environments with the spawn start method and a guarded entry point for Windows and Linux compatibility.

See scripts/README.md and docs/experiments.md.

Usage

Property Value
Action Space Box(-1.0, 1.0, (M * C * (C - 1) // 2,), float32)
Observation Space Box(0.0, 1.0, (obs_dim,), float32)
Create gymnasium.make("FoodDistribution-v0")
Default Scenario Six Indonesian provinces, two commodities (rice and corn)
Default Episode Length 100 steps

Import food_distribution_gym before creating the environment to register its ID:

import gymnasium as gym
import food_distribution_gym

food_distribution_gym.register_envs()
env = gym.make("FoodDistribution-v0")

obs, info = env.reset(seed=42)
env.action_space.seed(42)
terminated = truncated = False
while not (terminated or truncated):
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
env.close()

Here, C is the number of cities and M the number of commodities. The default scenario has 30 action components and 108 observation components. Each action specifies the signed trade quantity for one commodity and pair of cities. Positive values ship from the first city to the second; negative values reverse the direction. Quantities are scaled by X_max and projected into feasible integer flows using supply and, when enabled, cash constraints.

Observations contain normalized cash, stock, demand, and prices, plus one-step climate and pest transition probabilities when enabled. The reward combines shortage, cash-risk, and logistics-cost penalties. Their default weights are 1.0, 0.0, and 0.0, respectively.

Interactive Viewer

Install .[render] from source, then launch:

python -m food_distribution_gym

The equivalent command food-distribution-viewer launches the same viewer. The viewer discovers bundled scenarios independently of the current working directory. Models and replay files are read from models/ and episode_logs/ under the current working directory. Loading trained models requires the research extra. With no model loaded, the live simulation uses random actions.

The viewer displays the city network, commodity flows, stock and demand, cash, and climate and pest states. It supports dragging cities, zoom and pan, commodity selection, and manual trade control.

Key Action
Space Pause or play
Right / left arrow Step forward / backward (backward in Replay mode)
1-9 Select commodity
R Reset episode
M Toggle manual control in Live mode
+ / - Adjust playback speed
H Toggle help
F11 Toggle fullscreen
Esc Quit

The interactive viewer is separate from env.render(), which prints simulator state. An RGB renderer and Gymnasium RecordVideo integration are not included.

Scenario Configuration

The default scenario models Jawa Timur, Sulawesi Selatan, Sumatera Selatan, DKI Jakarta, Maluku, and Kalimantan Timur. Bundled YAML scenarios:

Filename Scenario
config_indonesia_6city_2comm.yaml Default scenario from Indonesian province data
config_6city_2comm_climate_pest.yaml Six cities, two commodities, climate and pest shocks
config_6city_2comm_climate_pest_harsh.yaml Six-city scenario with harsher shocks
config_10city_4comm_climate_pest.yaml Ten cities and four commodities

Load a bundled scenario by filename or a custom scenario by file path:

import gymnasium as gym
import food_distribution_gym

config = food_distribution_gym.load_config("config_6city_2comm_climate_pest.yaml")
env = gym.make("FoodDistribution-v0", config=config)
obs, info = env.reset(seed=42)
env.close()

FoodSecurityEnv(config) remains available directly from food_distribution_gym. YAML settings control initial stocks, demand, prices, cash, trade limits, climate and pest transitions, rewards, and the horizon. Changing city or commodity counts changes the policy dimensions; use a checkpoint trained for the selected configuration.

Episode Recording

Training records episodes through EpisodeLoggerCallback. For a separate rollout from a saved PPO model:

python scripts/episode_logger.py --model models/ppo_indonesia_6city_2comm_seed42.zip --config config_indonesia_6city_2comm.yaml --output episode_logs/ppo_seed42.pkl --seed 42

Open the saved episode in the viewer's Replay mode to inspect states, actions, trade flows, and reward components.

License and Releases

The code is licensed under the MIT License. See the release guide for local checks, TestPyPI, Trusted Publishing, and the first alpha release.

Package versions such as 0.1.0a1 are separate from the environment ID FoodDistribution-v0. Record both the package version and commit in experiments.

Acknowledgements

The food-security code was originally developed in tttor/discounting-free. This repository retains the relevant history. Package organization and documentation follow Cleaning Robots Gym.

Metadata

Release files for food-distribution-gym 0.1.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for food-distribution-gym 0.1.0a1
File Size Uploaded
food_distribution_gym-0.1.0a1.tar.gz 43.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for food-distribution-gym 0.1.0a1
File Interpreter ABI Platform
food_distribution_gym-0.1.0a1-py3-none-any.whl Python 3 none any Details

Total release size: 87.5 MB

Release files / food_distribution_gym-0.1.0a1.tar.gz

Download URL food_distribution_gym-0.1.0a1.tar.gz
Size 43.8 MB
Tags Source
SHA-256 checksum
How to use checksums
b0f2f0940a5b4417d71ca736e0ee06a85f78de6d0eb829c3ded9f50d37e63232
BLAKE2b-256 checksum
How to use checksums
99e3252005802985952616030c86ebe93e5add11e1f49070ac47811030e2676e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / food_distribution_gym-0.1.0a1-py3-none-any.whl

Download URL food_distribution_gym-0.1.0a1-py3-none-any.whl
Size 43.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
80b4cd06249db2d9fb92fbf4802db98beaaf65670e582b7462d77f4126190abc
BLAKE2b-256 checksum
How to use checksums
f5ede97812eaf51aa49beb8f5553ec9577d4ff5aab8e23989ebaaaef424f4901
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0a1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page