Skip to content

Adi20ti/RouteGeniusAI

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

RouteGenius AI

AI-powered multi-destination trip planner β€” enter your stops, pick an algorithm, get the optimal route instantly.

Live features

  • Three AI routing algorithms (Greedy, A*, TSP) with side-by-side comparison
  • Interactive Leaflet map with real OpenStreetMap tiles β€” no API key required
  • Free geocoding via Nominatim (OpenStreetMap)
  • Day-wise itinerary splitting (configurable km-per-day budget)
  • Full light / dark theme with zero-flash persistence
  • Docker-first deployment β€” one command to run everything

Table of Contents

  1. Architecture
  2. Project Structure
  3. Local Development
  4. Docker Deployment
  5. API Reference
  6. Algorithms
  7. Configuration
  8. Tech Stack

Architecture

Browser  ──(Next.js 14)──►  FastAPI (port 8000)
                                β”‚
                         sys.path inject
                                β”‚
                           ai-engine/
                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   greedy/             algorithms/
                   astar/              utils/
                   tsp/

The backend and ai-engine are separate Python packages kept in the same monorepo. The backend injects the ai-engine/ directory onto sys.path at startup so the algorithms can be imported without an install step.


Project Structure

routegenius-ai/
β”‚
β”œβ”€β”€ frontend/                  # Next.js 14 (App Router)
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ globals.css        # Design tokens + all component CSS
β”‚   β”‚   β”œβ”€β”€ layout.tsx         # Google Fonts, theme-flash prevention
β”‚   β”‚   └── page.tsx           # View state machine (homeβ†’inputβ†’results)
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ HomePage.tsx
β”‚   β”‚   β”œβ”€β”€ InputPage.tsx
β”‚   β”‚   β”œβ”€β”€ Map/
β”‚   β”‚   β”‚   β”œβ”€β”€ MapView.tsx    # Dynamic-import wrapper (ssr:false)
β”‚   β”‚   β”‚   β”œβ”€β”€ LeafletMap.tsx # react-leaflet implementation
β”‚   β”‚   β”‚   β”œβ”€β”€ SvgFallback.tsx
β”‚   β”‚   β”‚   β”œβ”€β”€ RouteLayer.tsx
β”‚   β”‚   β”‚   └── Marker.tsx
β”‚   β”‚   β”œβ”€β”€ Results/
β”‚   β”‚   β”‚   β”œβ”€β”€ ResultsPage.tsx
β”‚   β”‚   β”‚   β”œβ”€β”€ ComparisonPage.tsx
β”‚   β”‚   β”‚   β”œβ”€β”€ RouteSummary.tsx
β”‚   β”‚   β”‚   β”œβ”€β”€ ComparisonTable.tsx
β”‚   β”‚   β”‚   └── Itinerary.tsx
β”‚   β”‚   β”œβ”€β”€ Input/
β”‚   β”‚   β”‚   β”œβ”€β”€ LocationInput.tsx
β”‚   β”‚   β”‚   └── LocationList.tsx
β”‚   β”‚   └── UI/
β”‚   β”‚       β”œβ”€β”€ TopNav.tsx
β”‚   β”‚       β”œβ”€β”€ Button.tsx
β”‚   β”‚       β”œβ”€β”€ Card.tsx
β”‚   β”‚       └── Dropdown.tsx
β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   β”œβ”€β”€ useRoute.ts        # Geocoding + API calls
β”‚   β”‚   └── useMap.ts          # Bounds fitting helper
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ api.ts             # optimizeRoute / compareRoutes
β”‚   β”‚   β”œβ”€β”€ constants.ts       # ALGO_INFO, TRAVEL_MODES
β”‚   β”‚   └── helpers.ts         # geocodeLocation, toggleTheme, formatters
β”‚   └── types/index.ts         # TypeScript types (mirrors backend Pydantic)
β”‚
β”œβ”€β”€ backend/                   # FastAPI
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ core/config.py     # Settings (CORS, ai_engine_path)
β”‚   β”‚   β”œβ”€β”€ models/            # Pydantic request / response models
β”‚   β”‚   β”œβ”€β”€ routes/            # /optimize-route  /compare-routes
β”‚   β”‚   β”œβ”€β”€ services/          # route_service.py (orchestrator)
β”‚   β”‚   └── main.py            # Lifespan, CORS, /health
β”‚   β”œβ”€β”€ run.py
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ ai-engine/                 # Pure-Python algorithm core
β”‚   β”œβ”€β”€ algorithms/
β”‚   β”‚   β”œβ”€β”€ greedy.py          # Nearest-neighbour O(nΒ²)
β”‚   β”‚   β”œβ”€β”€ astar.py           # A* with MST heuristic
β”‚   β”‚   └── tsp.py             # Brute-force ≀8 nodes, NN+2-opt otherwise
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ distance.py        # Haversine formula
β”‚   β”‚   β”œβ”€β”€ graph.py           # Adjacency-matrix builder
β”‚   β”‚   └── itinerary.py       # Day-wise km-packing
β”‚   β”œβ”€β”€ tests/
β”‚   β”‚   β”œβ”€β”€ test_greedy.py
β”‚   β”‚   β”œβ”€β”€ test_astar.py
β”‚   β”‚   └── test_tsp.py
β”‚   └── benchmark.py
β”‚
β”œβ”€β”€ shared/
β”‚   └── types/
β”‚       β”œβ”€β”€ route.ts           # Canonical TypeScript types
β”‚       └── route.py           # Canonical Pydantic models
β”‚
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ setup.sh               # Install all deps (run once)
β”‚   └── run-all.sh             # Start backend + frontend in parallel
β”‚
└── docker-compose.yml

Local Development

Prerequisites

  • Node.js β‰₯ 18
  • Python β‰₯ 3.10
  • npm β‰₯ 9

First-time setup

# Clone the repo and install everything
git clone <repo-url>
cd routegenius-ai
bash scripts/setup.sh

setup.sh runs npm install --legacy-peer-deps for the frontend and pip install -r requirements.txt for both the backend and ai-engine.

Start all services

bash scripts/run-all.sh

This starts the backend on http://localhost:8000 and the frontend on http://localhost:3000 in parallel. Press Ctrl+C once to cleanly shut both down.

Start services individually

# Backend
cd backend
python run.py

# Frontend (separate terminal)
cd frontend
npm run dev

Run the AI engine tests

cd ai-engine
python -m pytest tests/ -v

Benchmark algorithms

cd ai-engine
python benchmark.py

Docker Deployment

Build and start (production)

docker compose up --build

The frontend will wait for the backend health check to pass before starting.

Service URL
Frontend http://localhost:3000
Backend http://localhost:8000
API docs http://localhost:8000/docs

Stop

docker compose down

Custom backend URL

If you deploy the backend at a different host/port, pass it as a build argument:

NEXT_PUBLIC_API_URL=https://api.example.com docker compose up --build

API Reference

All endpoints accept and return application/json.

GET /health

Returns the service status and a list of loaded algorithm modules.

Response

{
  "status": "ok",
  "algorithms_loaded": ["greedy", "astar", "tsp"]
}

POST /optimize-route

Optimise a list of locations with a single algorithm.

Request body

Field Type Required Default Description
locations Location[] (2–20 items) βœ“ Ordered list of {lat, lng} objects
algorithm "greedy"β”‚"astar"β”‚"tsp" βœ“ Algorithm to use
travel_mode "walk"β”‚"car"β”‚"transit" "car" Informational only in current version
max_daily_km number (β‰₯ 0) 0 If > 0, splits route into daily segments

Example

{
  "locations": [
    {"lat": 48.8566, "lng": 2.3522},
    {"lat": 51.5074, "lng": -0.1278},
    {"lat": 52.3676, "lng": 4.9041}
  ],
  "algorithm": "astar",
  "travel_mode": "car",
  "max_daily_km": 600
}

Response

{
  "route": [0, 2, 1],
  "total_distance": 892.4,
  "computation_time": 0.0003,
  "nodes_explored": 6,
  "solver_used": null,
  "itinerary": [
    {"day": 1, "stops": [0, 2], "distance_km": 430.1},
    {"day": 2, "stops": [2, 1], "distance_km": 462.3}
  ]
}

POST /compare-routes

Run all three algorithms on the same input and return a side-by-side comparison.

Request body β€” same fields as /optimize-route except algorithm is omitted.

Response

{
  "greedy": { ...RouteResult },
  "astar":  { ...RouteResult },
  "tsp":    { ...RouteResult },
  "summary": {
    "best_algorithm": "tsp",
    "best_distance_km": 891.2,
    "distances": {"greedy": 920.1, "astar": 892.4, "tsp": 891.2},
    "fastest_algorithm": "greedy",
    "computation_times": {"greedy": 0.00008, "astar": 0.0003, "tsp": 0.0012}
  }
}

Algorithms

Greedy (Nearest Neighbour)

Starts from the first location and repeatedly visits the closest unvisited node.

  • Time complexity: O(nΒ²)
  • Space complexity: O(n)
  • Best for: Fast approximations on large sets; usually within 20–25 % of optimal
  • Implementation: ai-engine/algorithms/greedy.py

A* (Heuristic Search)

Uses f(n) = g(n) + h(n) where:

  • g(n) = total distance travelled so far
  • h(n) = Minimum Spanning Tree (MST) of unvisited nodes (admissible lower bound)

Expands the most promising partial route at each step.

  • Time complexity: O(n! / pruned) β€” exponential worst case, much better with pruning
  • Space complexity: O(n Β· 2ⁿ) in the state space
  • Best for: Near-optimal routes when accuracy matters more than raw speed
  • Implementation: ai-engine/algorithms/astar.py

TSP (Exact / Heuristic)

Two-mode solver that automatically selects based on input size:

Nodes Solver Strategy
≀ 8 Brute force Enumerate all n! permutations, pick shortest
> 8 NN + 2-opt Multi-start nearest-neighbour followed by 2-opt local search
  • Best for: Exact optimality on small sets; high-quality heuristic on large sets
  • Implementation: ai-engine/algorithms/tsp.py

Configuration

Backend environment variables

Variable Default Description
AI_ENGINE_PATH Auto-detected from __file__ Absolute path to the ai-engine/ directory. Set automatically in Docker.
CORS_ORIGINS http://localhost:3000 Comma-separated list of allowed origins
ENV development production disables debug logging

Frontend environment variables

Variable Default Description
NEXT_PUBLIC_API_URL http://localhost:8000 Backend base URL (baked into the Next.js build)

Tech Stack

Layer Technology
Frontend Next.js 14, TypeScript, CSS custom properties
Map react-leaflet + OpenStreetMap (no API key)
Geocoding Nominatim / OpenStreetMap (no API key)
Icons lucide-react
Backend FastAPI, Pydantic v2, Uvicorn
AI Engine Pure Python β€” no ML libraries
Deployment Docker, docker-compose

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 50.7%
  • TypeScript 33.3%
  • CSS 9.9%
  • Shell 4.0%
  • Dockerfile 1.9%
  • JavaScript 0.2%