{"id":16456009,"url":"https://github.com/anirbanroydas/opruut","last_synced_at":"2026-04-09T18:15:03.718Z","repository":{"id":67369732,"uuid":"75755489","full_name":"anirbanroydas/opruut","owner":"anirbanroydas","description":"A route optimiser for metro stations and subways giving (a). the shortest travel time with (b). maximum comfort [eg: less crowd, possibility of finding a seat, etc..] using primarily React Js (with Redux), Laravel framework(PHP), Node-Js(Socke.io Server), Neo4J (Graph Database).","archived":false,"fork":false,"pushed_at":"2017-04-11T18:51:40.000Z","size":17409,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-26T22:44:11.708Z","etag":null,"topics":["graph-database","job-queue","laravel","machine-learning","mysql","neo4j","nodejs","react","redis","redux","route-optimization","socketio","websocket"],"latest_commit_sha":null,"homepage":"https://opruut.readthedocs.io/en/latest","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anirbanroydas.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-06T17:36:23.000Z","updated_at":"2020-02-17T07:37:02.000Z","dependencies_parsed_at":"2023-02-21T17:45:53.071Z","dependency_job_id":null,"html_url":"https://github.com/anirbanroydas/opruut","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/anirbanroydas/opruut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anirbanroydas%2Fopruut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anirbanroydas%2Fopruut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anirbanroydas%2Fopruut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anirbanroydas%2Fopruut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anirbanroydas","download_url":"https://codeload.github.com/anirbanroydas/opruut/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anirbanroydas%2Fopruut/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271083703,"owners_count":24696350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graph-database","job-queue","laravel","machine-learning","mysql","neo4j","nodejs","react","redis","redux","route-optimization","socketio","websocket"],"created_at":"2024-10-11T10:24:24.412Z","updated_at":"2026-04-09T18:15:03.682Z","avatar_url":"https://github.com/anirbanroydas.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"opruut\n==============\n\nIts a route optimiser for metro stations and subways which gives \n a. the shortest travel time, and\n b. maximum comfort [eg: less crowd, possibility of finding a seat, etc..]\n\n\nScreencast of Demo\n-------------------\n\nhttps://www.useloom.com/share/fb490313ba1b45de9ba38095ab04ec94\n\n\nDocumentation\n--------------\n\n**Link :** https://opruut.readthedocs.io/en/latest/\n\n\nProject Home Page\n--------------------\n\n**Link :** https://www.github.com/anirbanroydas/opruut\n\n\n\nDetails\n--------\n\n\n:Author: Anirban Roy Das\n:Email: anirban.nick@gmail.com\n:Copyright(C): 2017, Anirban Roy Das \u003canirban.nick@gmail.com\u003e\n\nCheck ``opruut/LICENSE`` file for full Copyright notice.\n\n\n\nOverview\n---------\n\nIts a route optimiser for metro stations and subways which gives \n a. the shortest travel time, and\n b. maximum comfort [eg: less crowd, possibility of finding a seat, etc..]\n\nIt uses the `Laravel \u003chttps://www.laravel.com/\u003e`_  framework to implement the backend along with `react js \u003chttps://facebook.github.io/react/\u003e`_ for front end. it is highly scalable and use job queues to handle high load and the huge dataset.\n\n\n\nTechnical Specs\n----------------\n\n:PHP: Primay Server Side Language\n:Laravel: Advanced Web Framework for PHP\n:JavaScript: Client Side Language\n:React: Front end javascript view library\n:Redux: Data store for React\n:Mysql: Database\n:Redis: Session Library, Cache Library, Job Queue\n:Neo4j: Graph Database\n:Websocket: For live stream\n:Socket.io: JavaScript Client for websockets\n:NodeJs: For weboskcet(socket.io) server (larvael-echo-server)\n\n\n\nFeatures\n---------\n\n* Shortest Route\n* Comfort Factor\n* Seat finding probility \n* Great UI\n* React Js - Redux Js\n* Laravel/PHP\n\n\n\nAlgorithm and Logic\n--------------------\n\nWe are going to consider (a). **shortest distance or shortest time** to reach destination and (b). **comfort factor** to reach destination. We will determine the optimized route based on these two.\n\nShortest Distance/Time\n~~~~~~~~~~~~~~~~~~~~~~~\n\nTo determeine shortest route between source and destination, its pretty straight forward. We just have to find out shortest distance between two vertices in a graph. Here, our station network can be represented in a graph, hence we use **Neo4j** as the graph database to store and query the graph network of the metro stations.\n\nFinding shortest distance is easy. Algorithms like **Shortest Distance** can help us deteremine it. Although its not very scalable but given there will be not huge number of stations in a city, those algorithms will do a good enough job.\n\nBut here, we are trying to find the optimized route not only on the basis of distance or time but also on the basis of other factors like comfort, crowd, finding a seat, time of travel.\n\n**Few Things to Note**\n\n* Speed of train is constant\n* Means, shortest distance means shortest time too.\n\n\nComfort Factor\n~~~~~~~~~~~~~~~\n\nThis one is not so straight forward. To determine comfort factor and weigh them against shortest distanct/time factor and optimize route using these we have to actually take into consideration how to determine the comfort factor.\n\nSo to determine comfort factor, focus is done on 3 factors, one is **crowd factor** for the route, **empty seat factor** throughout the route and **Interchanges** between different metro lines (eg: from blue line to yellow line then yellow line to red line, etc)\n\nTo determind **crowd factor** and **empty seat factory**, lets first look at **IF (Importance Factor)** and how it helps in determing the previous two and hence the **Comfort Factor**\n\n\n\n\nImportance Factor (IF)\n++++++++++++++++++++++++\n\nSo, what is being done here is trying to find **Importance Factor** of each station and which will help us find the comfort factor of a route.\n\nSo what and how to find the importance factor of a metro station?\n\nHere are few properties that may determine **Importance Factor (IF)**:\n\n1. Population in the station area\n2. Offices in the station area\n3. Restaurants (food joints)\n4. Entertaiment sources (Movie Theatres, Malls, Game Zones)\n5. Educational Institutions\n6. Amenities (Hospitals, Parks)\n\n**IF** is directyly propertional to **CF (Comfort Factor)**\n\n\n\n\nPopulation - Why and How it determines IF?\n*******************************************\n\nLet say people entering metro at a particular station is **IN**.\nAnd, people coming out of the metro at a particular station is **OUT**.\n\nNow **IN** and **OUT** are directly propertional to **CF** and thus, **IF**.\n\nNow, people entering and exiting means population entering and exiting. A larger population at a station means more commute in general. Hence **IN** and **OUT** is the population factor.\n\nNow, Population is directly propertional to IF, i.e **IF = c1\\*(Population)**, where **c1** is a constant.\n\n\n\n\nOffices\n********\n\nOffices determine more people getting out of the metro at that station to go their offices and enter metro after leaving the offices.\n\nThus, offices directyly propertional to **IF**\n\n**IF = k1\\*(Offices)**, where **k1** is a function of time.\n\n**k1 = k1(t)**\n\nThis is because people generally come to offices in the morning and leave in the evening. That means more people exiting that metro station in the morning and more people entering the metro station in the evening.\n\nHere is a time graph of **k1** determined after doing a **polynomial regression analysis** on some dataset.\n\n.. image:: screenshots/offices.png \n\n\n\n\n\nRestaurants\n************\n\nSame reason as Offices. \n\n**IF = k2\\*(Restaurants)**, where **k2** is a function of time.\n\n**k2 = k2(t)**\n\nHere is a time graph of **k2** determined after doing a **polynomial regression analysis** on some dataset.\n\n.. image:: screenshots/restaurants.png \n\n\n\n\nEntertaiment Sources\n**********************\n\nSame reason as Offices. \n\n**IF = k3\\*(Entertaiment_Sources)**, where **k3** is a function of time.\n\n**k3 = k3(t)**\n\nHere is a time graph of **k3** determined after doing a **polynomial regression analysis** on some dataset.\n\n.. image:: screenshots/entertainment.png \n\n\n\n\nEducational Institutions\n*************************\n\nSame reason as Offices. \n\n**IF = k4\\*(Educational_Institutions)**, where **k4** is a function of time.\n\n**k4 = k4(t)**\n\nHere is a time graph of **k4** determined after doing a **polynomial regression analysis** on some dataset.\n\n.. image:: screenshots/educationInstitutions.png \n\n\n\n\nAmenities (Hospitals)\n**********************\n\nSame reason as Population. \n\n**IF = c2\\*(Amenities)**, where **c2** is a constant.\n\nThis is because need for ameneties like hospitals does not depend on time. Hence time cannot influece the factor, but more ameneties near a metro station means more commuters enter/exit that station on average. Thus the **IF**.\n\n\n\nCrowd Factor\n+++++++++++++\n\nNow since we looked into **IF**, lets focus on **crowd factor** and **empty seat factor**.\n\nCrowd factor is directly proportional to **IF**. So we have to determine the **crowd factor** at a specific time by calculating the **IF** at the same time. We already saw how IF is calculated at a specific time usign the graphs and values.\n\n\nEmpty Seat Factor\n++++++++++++++++++\n\nNow empty seats meand more probability to sit and hence means more comfort. Empty seat values will keep changing at every station and it also depends on the time of travel and also on the route. The station number in a particular metro line also determines the empty seat factor. \n\nLets see a sample empty seat graph for a particular route and how different stations in that metro line may have different empty seats factor depending on time and station number.\n\n.. image:: screenshots/empty_plot_blue-2_2_yamunaBank.png\n\nSo empty seat factory is determined using both time of travel and the above graph.\n\n**Empty Seats = Total Seats(constant) - Crowd in train** [at a particular time].\n\n**Comfort** = Sum of empty seats from source to destination (Since, comfort due to empty seats may change depending on the travel time because shot travel time does not require much comfort requirement, shorter travel time is mroe preferrable but in case of longer travel time, comfort become becomes important factor), i.e. for longer travel time, a large number of (-ve) seat comfort values adds upto a greater negative number which mean more discomfort compared to shorter travel time with lesser (-ve) empty seat vlaue.\n\n**NOTE :**  If seat comfort starts with positive (+ve) value, then it remains constant for the rest of the journey.\n\n\nInterchanges Factor\n++++++++++++++++++++\n\nThis is pretty straight forward too. Its the number of interchanges that happen in a route from source to destination. Its is multiplied by an factor to normalize the value to affect the final calculation of **CF** with no bias.\n\nSo finally the **Confort Factor (CF)** can be determined by using the above two.\n\n**CF = maximize(empty seat comfort factor) + minimize(crowd factor) + minimize(no. of interchanges of metro line junctions)**\n\n\nOptimzed Route\n~~~~~~~~~~~~~~~\n\nThe final calculation of the **Optimzed Route** is done by combining **Travel Time** adn **Confort Factor** and normalizing it using the below formulae.\n\n**Optimized Route = maximize(Confort \\* Comfort Preference Factor) + minimize(Travel Time \\* Travel Time Preference Factor)**\n\nThe Comfort Preference Factor and Travel Time Preference Factor both depends on time and sometimes manually set.\n\nBelow are the graphs of the preferences depending on time.\n\n\n\nComfort Preference Plot\n++++++++++++++++++++++++\n\n.. image:: screenshots/PreferencePlot_Comfort.png\n\n\n\nTravel Time Preference Plot\n++++++++++++++++++++++++++++\n\n.. image:: screenshots/PreferencePlot_TravelTime.png\n\n\n\nTodo\n-----\n\n1. Add Blog post regarding this topic.\n2. Add Contract Tests using pact\n3. Add integration tests\n4. Add e2e tests\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanirbanroydas%2Fopruut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanirbanroydas%2Fopruut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanirbanroydas%2Fopruut/lists"}