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)
| File | Size | Uploaded | |
|---|---|---|---|
| food_distribution_gym-0.1.0a1.tar.gz | 43.8 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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