{"id":23229017,"url":"https://github.com/mgrechanik/ant-colony-optimization","last_synced_at":"2025-08-21T00:12:41.632Z","repository":{"id":211029119,"uuid":"728015804","full_name":"mgrechanik/ant-colony-optimization","owner":"mgrechanik","description":"The implementation of the ant colony optimization algorithm. Allows to solve Travelling Salesman Problem , Shortest path problem, etc.","archived":false,"fork":false,"pushed_at":"2024-04-29T04:15:48.000Z","size":228,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-17T22:19:08.293Z","etag":null,"topics":["aco","adjacency-matrix","ant-colony-optimization","graph","optimization-algorithms","path-planning","php","php8","salesman-problem","search-algorithm","shortest-path-algorithm","shortest-path-problem","shortest-paths","travelling-salesman-problem","tsp","tsp-problem","tsp-solver"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgrechanik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2023-12-06T03:37:17.000Z","updated_at":"2025-05-05T11:55:10.000Z","dependencies_parsed_at":"2024-04-02T05:28:36.581Z","dependency_job_id":"70cd0cb3-e24c-414a-8817-946e8564397b","html_url":"https://github.com/mgrechanik/ant-colony-optimization","commit_stats":null,"previous_names":["mgrechanik/ant-colony-optimization"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mgrechanik/ant-colony-optimization","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrechanik%2Fant-colony-optimization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrechanik%2Fant-colony-optimization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrechanik%2Fant-colony-optimization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrechanik%2Fant-colony-optimization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgrechanik","download_url":"https://codeload.github.com/mgrechanik/ant-colony-optimization/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrechanik%2Fant-colony-optimization/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271405924,"owners_count":24753878,"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-20T02:00:09.606Z","response_time":69,"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":["aco","adjacency-matrix","ant-colony-optimization","graph","optimization-algorithms","path-planning","php","php8","salesman-problem","search-algorithm","shortest-path-algorithm","shortest-path-problem","shortest-paths","travelling-salesman-problem","tsp","tsp-problem","tsp-solver"],"created_at":"2024-12-19T01:15:55.794Z","updated_at":"2025-08-21T00:12:41.615Z","avatar_url":"https://github.com/mgrechanik.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ant colony optimization\n\n[Русская версия](docs/README_ru.md)\n\n## Table of contents\n\n* [Introdution](#introducion)\n* [Demo](#demo)\n* [Installing](#installing)\n* [How to use](#use)\n* [Settings](#settings)\n* [Performance](#performance)\n* [TSPLIB95](#tsplib95)\n* [Terminology](#terminology)\n\n\n---\n\n## Introdution \u003cspan id=\"introducion\"\u003e\u003c/span\u003e\n\nThe Ant colony optimization is a probabilistic technique for solving computational problems which can be reduced to finding good paths through graphs (from Wikipedia).\n\nThe task we are solving could be either \"[Travelling salesman problem](#tsp-example 'Code example of solving TSP with ACO')\" or \"[Shortest path problem](#spp-example 'Code example of solving SPP with ACO')\", or Constrained Shortest Path First, etc.  \nThe two first tasks are solved within this library.\n\nThere are a lot of strategies and variations of Classic ACO algorithm.  \nThis library out of the box implements Classic ACO and ACO with elitist ants.\n\nThe library could be easily extended so you can implement your ACO variations and to solve the tasks you need.\n\nThe initial data about the graph comes either from adjacency matrix or from a list of nodes (cities, vertices, etc) with their X and Y coordinates.\n\nThe work of library had been tested with [TSPLIB95](#tsplib95) data sets, so we could check it's [performance](#performance) and efficiency. \n\nAmount of ants, all coefficients and parameters could be [changed](#settings) to your need.\n\nNow we have [a web app](https://github.com/mgrechanik/aco-workshop-for-tsp \"Ant colony optimization workshop for solving a travelling salesman problem\") which you can install and run locally to practice with this algorithm. Look for it's video demo for details.\n\n---\n\n## Demo \u003cspan id=\"demo\"\u003e\u003c/span\u003e\n\nSolving the travelling salesman problem with the ant colony optimization algorithm:\n![Using this ACO library to solve the travelling salesman problem](https://raw.githubusercontent.com/mgrechanik/ant-colony-optimization/main/docs/dots.jpg \"Using this ACO library to solve the travelling salesman problem\")\n\n\nAnother example:\n![Using this ACO library to find the path for travelling salesman on the USA map image](https://raw.githubusercontent.com/mgrechanik/image-points-searcher/main/docs/second.jpg \"Using ACO to find the path for the travelling salesman on the USA map image\")\n\n\t\n---\n    \n## Installing \u003cspan id=\"installing\"\u003e\u003c/span\u003e\n\n#### Installing through composer::\n\nThe preferred way to install this library is through composer.\n\nEither run\n```\ncomposer require --prefer-dist mgrechanik/ant-colony-optimization\n```\n\nor add\n```\n\"mgrechanik/ant-colony-optimization\" : \"~1.0.0\"\n```\nto the require section of your `composer.json`.\n\n\n\n---\n\n## How to use  \u003cspan id=\"use\"\u003e\u003c/span\u003e \n\n### Basic API\n\n1) **Creating a Manager with the dependencies we need**\n```php\nManager::__construct(DistanceInterface $distanceStrategy = null, AFinder $finder = null, \n                     MathematicsInterface $mathematics = null, Task $task = null);\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- By default **Finder** will be Classic one, and the **Task** will be the Travelling salesman problem\n\n2) **Loading data from an adjacency matrix**\n```php\n$manager-\u003esetMatrix(array $matrix, int $nameStart = 0)\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- ```$nameStart``` - from which number start naming aliases of nodes\n\n3) **Loading data from an array of cities**\n```php\n$manager-\u003esetCities(City ...$cities)\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- This array of cities will be transformed to adjacency matrix. Distances will be calculated according to the strategy we set to a Manager.  \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- If city has a ```name``` property it will become it's name alias\n\n4) **Changing of the adjacency matrix**\n```php\n$manager-\u003eupdateMatrix(int $y, int $x, float|int $value, bool $double = true)\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- For example we could make some path impassable - ```$manager-\u003eupdateMatrix(1, 0, 1000000);```\n\n5) **Run the computational process**\n```php\n$distance = $manager-\u003erun(int $iterations = 400)\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- for small graphs we could reduce amount of iterations.  \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- It will return the distance we found or ```null``` when the search gave no result\n\n6) **Getting the path we found**\n```php\n$path = $manager-\u003egetInnerPath()\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- The path we found who consists of node's numbers.   \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;All nodes are internally named as numbers from 0 to N-1, where N is node's amount.  \n\n7) **Getting aliased path we found**\n```php\n$path = $manager-\u003egetNamedPath()\n```\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;- The path we found which consists of node's name aliases, if we set them.   \n\n### Examples\n\n#### Solving \"Travelling salesman problem\" with Classic ACO  \u003cspan id=\"tsp-example\"\u003e\u003c/span\u003e \n```php\nuse mgrechanik\\aco\\Manager;\n\n$manager = new Manager();\n$matrix = [\n            [ 0, 8, 4, 11],\n            [ 8, 0, 9, 5 ],\n            [ 4, 9, 0, 8 ],\n            [11, 5, 8, 0 ]\n          ];\n$manager-\u003esetMatrix($matrix);\n$distance = $manager-\u003erun(20);\nvar_dump('Distance=' . $distance);\nvar_dump($manager-\u003egetInnerPath())\n```\nWe will get:\n```php\nDistance=25\n\nArray\n(\n    [0] =\u003e 0\n    [1] =\u003e 1\n    [2] =\u003e 3\n    [3] =\u003e 2\n    [4] =\u003e 0\n) \n```\n\n#### Solving \"Shortest path problem\" with Classic ACO \u003cspan id=\"spp-example\"\u003e\u003c/span\u003e \n\n```php\nuse mgrechanik\\aco\\Manager;\nuse mgrechanik\\aco\\SppTask;\n\n$task = new SppTask(0, 3);\n$manager = new Manager(task : $task);\n$matrix = [\n            [ 0 , 8, 4, 100],\n            [ 8 , 0, 9, 5  ],\n            [ 4 , 9, 0, 8  ],\n            [100, 5, 8, 0  ]\n          ];\n$manager-\u003esetMatrix($matrix);   \n$finder = $manager-\u003egetFinder();\n// increase amount of ants to 6\n$finder-\u003esetM(6);\n$distance = $manager-\u003erun(50);\nvar_dump('Distance=' . $distance);\nvar_dump($manager-\u003egetInnerPath())\n```\nWe will get:\n```php\nDistance=12\n\nArray\n(\n    [0] =\u003e 0\n    [1] =\u003e 2\n    [2] =\u003e 3\n)\n// for comparison, the direct path [0, 3] is closed by big distance and distance of path [0, 1, 3] is 13\n```\n\n#### Loading data as an array of cities\n```php\nuse mgrechanik\\aco\\Manager;\nuse mgrechanik\\aco\\City;\n\n$cities = [new City(10,10), new City(50,50), new City(10,50), new City(60,10)];\n$manager = new Manager();\n$manager-\u003esetCities(...$cities);\n```\n\n\n#### Loading data as an adjacency matrix\n```php\nuse mgrechanik\\aco\\Manager;\n\n$matrix = [\n            [ 0, 8, 4, 11],\n            [ 8, 0, 9, 5 ],\n            [ 4, 9, 0, 8 ] ,\n            [11, 5, 8, 0 ]\n          ];\n$manager = new Manager();\n$manager-\u003esetMatrix($matrix);\n```\n\n#### Using the Elitist Finder\n\n```php\n$finder = new \\mgrechanik\\aco\\elitist\\Finder();\n$manager = new Manager(finder : $finder);\n//...\n```\n\n#### Have a look at the history of our work - best solutions we had been finding\n```php\nuse mgrechanik\\aco\\Manager;\n\n$matrix = [\n            [ 0, 8, 4, 11],\n            [ 8, 0, 9, 5 ],\n            [ 4, 9, 0, 8 ] ,\n            [11, 5, 8, 0 ]\n          ];\n$manager = new Manager();\n$finder = $manager-\u003egetFinder();\n$manager-\u003esetMatrix($matrix);\n$manager-\u003erun();\nvar_dump($finder-\u003egetHistory());\n```\n\n#### Loading a list of cities from an image file\n\nWith the use of [this library](https://github.com/mgrechanik/image-points-searcher  \"library to search for points on image\") we can load a list of cities from the image. And the result of the search could be displayed on the image too. It will look like images on [Demo](#demo \"the images we get this way\").\n\nRead docs of that library for more information how to prepare images but briefly it is this: On white canvas draw points of 10 px diameter (they are vertices of the graph) and use this image with the code below \n\n```php\nuse mgrechanik\\aco\\Manager;\nuse mgrechanik\\aco\\City;\n\ntry {\n    $imageSearcher = new \\mgrechanik\\imagepointssearcher\\Searcher(\n        './images/your_image.jpg',\n    );\n    $found = $imageSearcher-\u003erun();    \n    if ($found \u003e 1) {\n        $points = $imageSearcher-\u003egetPoints();\n        $cities = [];\n        foreach ($points as $point) {\n            $cities[] = new City($point['x'], $point['y']);\n        }    \n        $manager = new Manager();\n        $manager-\u003esetCities(...$cities);\n        if ($res = $manager-\u003erun()) {\n            $innerPath = $manager-\u003egetInnerPath();\n            $imageResult = new \\mgrechanik\\imagepointssearcher\\ImageResult($imageSearcher);\n            $imageResult-\u003edrawLabels();\n            $imageResult-\u003edrawMargins();\n            $imageResult-\u003edrawPath($innerPath);\n            $imageResult-\u003esave('./images/result.jpg');\n        }\n    }\n  \n} catch (Exception $e) {\n    //\n}\n```\n\n---\n\n## Settings  \u003cspan id=\"settings\"\u003e\u003c/span\u003e   \n\n### Finder settings\n\nThe base object we tune is the Finder.  \nLets get it:\n```php\n$manager = new Manager();\n$finder = $manager-\u003egetFinder();\n// Settings\n//$finder-\u003eset...\n// ...\n//$manager-\u003erun();\n```\n\n**Settings available:**\n\n- Set the distance value which makes the path between two nodes impassable  \n```-\u003esetClosedPathValue(int $value)```\n\n- Set amount of ants  \n```-\u003esetM(int $m)```\n\n- Set amount of ants in percents relatively to amount of nodes. Default behavior (=40%)  \n```-\u003esetMPercent(int $mPercent)```\n\n- Set the coefficients for formulas\n```php\n-\u003esetAlpha(float $alpha);\n-\u003esetBeta(float $beta);\n-\u003esetP(float $p);\n-\u003esetC(float $c);\n-\u003esetQ(int $q);\n```\n\n- Set the strategy to do the mathematical work  \n```-\u003esetMathematics(MathematicsInterface $mathematics)```\n\n- Set the task we are solving. Say TSP, SPP or other.  \n```-\u003esetTask(Task $task)```\n\n- Set an amount of elitist ants (when we use Elitist Finder)   \n```-\u003esetSigma(int $sigma)```\n\n- Set an amount of elitist ants in percents relatively to amount of regular ants. Default behavior (=50%) (when we use Elitist Finder)  \n```-\u003esetSigmaPercent(int $sPercent)```\n\n---\n\n## Performance  \u003cspan id=\"performance\"\u003e\u003c/span\u003e   \n\n\u003e First of all turn off XDebug or it's analogies, since they could significantly affect the time the algorithm works\n\nThis ACO algorithm finds [good](#demo) paths on a graph. And sometimes even best paths. \n\nLets take, for example, the ```berlin52.tsp``` task from [TSPLIB95](#tsplib95) library, which has 52 nodes.  \nSolving this task with the next code:\n```php\n$cities = TspLibLoader::loadCitiesFromEuc2dFile(__DIR__ . '/images/data/berlin52.tsp');\n$finder = new \\mgrechanik\\aco\\elitist\\Finder();\n$finder-\u003esetSigmaPercent(150);\n$finder-\u003esetMPercent(30);\n$finder-\u003esetAlpha(0.7);\n$manager = new Manager(finder : $finder);\n$manager-\u003esetCities(...$cities);\n$distance = $manager-\u003erun(300);\nvar_dump('Distance=' . $distance);\nvar_dump($finder-\u003egetHistory());\n```\nWe will see:\n```php\nDistance=7542\n\n   Array ... \n    [85] =\u003e Array\n        (\n            [distance] =\u003e 7542\n            [inner_path] =\u003e 0_21_30_17_2_16_20_41_6_1_29_22_19_49_28_15_45_43_33_34_35_38_39_36_37_47_23_4_14_5_3_24_11_27_26_25_46_12_13_51_10_50_32_42_9_8_7_40_18_44_31_48_0\n            [iteration] =\u003e 85\n            [time_spent] =\u003e 1.94 sec\n        )  \n    )\n```\n\nThis code, working on an office computer, found the best path ever known for less than 2 seconds.\n\nWe used here Elitist ACO algorithm since in practice it gives better results than Classic one. \n\nAn Algorithm is probabilistic, ants travel differently each new search. A lot depends upon amount of nodes, amount of ants, all coefficients and parameters used with formulas.\n\n\n---\n\n## TSPLIB95 \u003cspan id=\"tsplib95\"\u003e\u003c/span\u003e\n\nThe [TSPLIB95](http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/) library ships with a lot of ```Travelling salesman problems``` - initial data and solutions - best results ever found for these tasks ([paths](#tsplib95 \"The best paths are located in the corresponding name.opt.tour file\") and [distances](http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/STSP.html \"Here you can see the best distances ever found\")).\n\nThe library is valuable that with it's data we could test the efficiency of our algorithms, coefficients and parameters.\n\nThe library consists of a lot of different initial data formats. Out of the box we support two of them.\n\n### Loading data as a set of X and Y coordinates of cities. Distance is euclidean.\n\nExample of the file with this format - **berlin52.tsp** .  \nLoading the list of nodes (cities) and transfer it to Manager:\n\n```php\nuse mgrechanik\\aco\\TspLibLoader;\nuse mgrechanik\\aco\\Manager;\n\n$fileName = __DIR__ . '/berlin52.tsp';\n$cities = TspLibLoader::loadCitiesFromEuc2dFile($fileName);\n$manager = new Manager();\n$manager-\u003esetCities(...$cities);\n```\n\n### Loading data as an adjacency matrix\n\nExample of the file with this format - **bays29.tsp** .  \nLoading the adjacency matrix and transfer it to Manager:\n\n```php\nuse mgrechanik\\aco\\TspLibLoader;\nuse mgrechanik\\aco\\Manager;\n\n$fileName = __DIR__ . '/bays29.tsp';\n$matrix = TspLibLoader::loadMatrixFromExplicitMatrixFile($fileName);\n$manager = new Manager();\n// tsplib95 library names nodes starting with \"1\"\n$manager-\u003esetMatrix($matrix, 1);\n```\n\n---\n\n## Terminology  \u003cspan id=\"terminology\"\u003e\u003c/span\u003e   \n\n#### ```ACO``` - Ant colony optimization algorithm\n\n#### ```Nodes``` - Nodes or vertices or cities. Ants travel between them.\n\n#### ```Adjacency Matrix``` - Adjacency Matrix sets the distances between graph nodes. It is a basic structure our algorithm starts work with.\nWhen graph is loaded like ```Cities``` with their coordinates, this information will be converted to Adjacency Matrix\n\n#### ```Classic Finder``` - Finder who implements Classic ACO algorithm\n\n#### ```Elitist Finder``` - Finder who implements ACO algorithm when we use elitist ants\n\n#### ```Ant``` - ant, working unit, who move through the graph searching for the paths\n\n#### ```Task``` - The task we are solving on the graph. For example it could be  ```\"Travelling salesman problem\"``` or ```\"Shortest path problem\"```. Or other.\n\n#### ```TSP``` - Travelling salesman problem. With this library we can solve both symmetric and asymmetric types of tsp\n\n#### ```Manager``` -  The manager which task is to form adjacency matrix , give it to ```Finder``` to solve ```Task```.\n\n#### ```Iteration``` - The iteration during which all ants find one path and put pheromones on it. We set amount of iterations themselves.\n\n#### ```Pheromon``` - is the instance ants leave on paths\n\n#### ```m``` - Amount of ants\n\n#### ```mPercent``` - Amount of ants in percents relatively to the amount of nodes\n\n#### ```sigma``` - Amount of elitist ants, if we use corresponding algorithm\n\n#### ```sigmaPercent``` - Amount of elitist ants in percents relatively to the amount of regular ants\n\n#### ```alpha``` - The coefficient to control the influence of pheromone amount\n\n#### ```beta``` - The coefficient to control the influence of desirability of path\n\n#### ```p``` - The evaporation coefficient\n\n#### ```c``` - The starting amount of pheromones on paths\n\n#### ```Q``` - The constant used to calculate how many pheromones an ant puts on the path it found\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgrechanik%2Fant-colony-optimization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgrechanik%2Fant-colony-optimization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgrechanik%2Fant-colony-optimization/lists"}