{"id":16634188,"url":"https://github.com/qanastek/easymcdm","last_synced_at":"2025-10-06T17:00:09.801Z","repository":{"id":42483118,"uuid":"466471009","full_name":"qanastek/EasyMCDM","owner":"qanastek","description":"Multiple-criteria decision-making (MCDM) with Electre, Promethee, Weighted Sum and Pareto","archived":false,"fork":false,"pushed_at":"2022-04-03T20:37:44.000Z","size":545,"stargazers_count":15,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T21:12:29.306Z","etag":null,"topics":["decision-making","electre","electre-iv","mcdm","multiple-criteria-decision-making","optimization","pareto","promethee","promethee-i","promethee-ii","python","weighted-sum"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/EasyMCDM","language":"Python","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/qanastek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null}},"created_at":"2022-03-05T14:07:49.000Z","updated_at":"2024-01-03T00:00:20.000Z","dependencies_parsed_at":"2022-08-20T07:40:41.789Z","dependency_job_id":null,"html_url":"https://github.com/qanastek/EasyMCDM","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qanastek%2FEasyMCDM","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qanastek%2FEasyMCDM/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qanastek%2FEasyMCDM/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qanastek%2FEasyMCDM/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qanastek","download_url":"https://codeload.github.com/qanastek/EasyMCDM/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245115807,"owners_count":20563239,"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","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":["decision-making","electre","electre-iv","mcdm","multiple-criteria-decision-making","optimization","pareto","promethee","promethee-i","promethee-ii","python","weighted-sum"],"created_at":"2024-10-12T05:30:41.340Z","updated_at":"2025-10-06T17:00:04.778Z","avatar_url":"https://github.com/qanastek.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI version](https://badge.fury.io/py/EasyMCDM.svg)](https://badge.fury.io/py/EasyMCDM)\r\n[![GitHub Issues](https://img.shields.io/github/issues/qanastek/EasyMCDM.svg)](https://github.com/qanastek/EasyMCDM/issues)\r\n[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg)](CONTRIBUTING.md)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)\r\n[![Downloads](https://static.pepy.tech/personalized-badge/EasyMCDM?period=total\u0026units=international_system\u0026left_color=grey\u0026right_color=orange\u0026left_text=Downloads)](https://pepy.tech/project/EasyMCDM)\r\n\r\n# EasyMCDM - Quick Installation methods\r\n\r\n## Install with PyPI\r\n\r\nOnce you have created your Python environment (Python 3.6+) you can simply type:\r\n\r\n```bash\r\npip3 install EasyMCDM\r\n```\r\n\r\n## Install with GitHub\r\n\r\nOnce you have created your Python environment (Python 3.6+) you can simply type:\r\n\r\n```bash\r\ngit clone https://github.com/qanastek/EasyMCDM.git\r\ncd EasyMCDM\r\npip3 install -r requirements.txt\r\npip3 install --editable .\r\n```\r\n\r\nAny modification made to the `EasyMCDM` package will be automatically interpreted as we installed it with the `--editable` flag.\r\n\r\n## Setup with Anaconda\r\n\r\n```bash\r\nconda create --name EasyMCDM python=3.6 -y\r\nconda activate EasyMCDM\r\n```\r\n\r\nMore information on managing environments with Anaconda can be found in [the conda cheat sheet](https://docs.conda.io/projects/conda/en/4.6.0/_downloads/52a95608c49671267e40c689e0bc00ca/conda-cheatsheet.pdf).\r\n\r\n# Try It\r\n\r\nData in `tests/data/donnees.csv` :\r\n\r\n```csv\r\nalfa_156,23817,201,8,39.6,6,378,31.2\r\naudi_a4,25771,195,5.7,35.8,7,440,33\r\ncit_xantia,25496,195,7.9,37,2,480,34\r\n```\r\n\r\n## Promethee\r\n\r\n```python\r\nfrom EasyMCDM.models.Promethee import Promethee\r\n\r\ndata = pd.read_csv('tests/data/donnees.csv', header=None).to_numpy()\r\n# or\r\ndata = {\r\n  \"alfa_156\": [23817.0, 201.0, 8.0, 39.6, 6.0, 378.0, 31.2],\r\n  \"audi_a4\": [25771.0, 195.0, 5.7, 35.8, 7.0, 440.0, 33.0],\r\n  \"cit_xantia\": [25496.0, 195.0, 7.9, 37.0, 2.0, 480.0, 34.0]\r\n}\r\nweights = [0.14,0.14,0.14,0.14,0.14,0.14,0.14]\r\nprefs = [\"min\",\"max\",\"min\",\"min\",\"min\",\"max\",\"min\"]\r\n\r\np = Promethee(data=data, verbose=False)\r\nres = p.solve(weights=weights, prefs=prefs)\r\nprint(res)\r\n```\r\n\r\n**Output :**\r\n\r\n```python\r\n{\r\n  'phi_negative': [('rnlt_safrane', 2.381), ('vw_passat', 2.9404), ('bmw_320d', 3.3603), ('saab_tid', 3.921), ('audi_a4', 4.34), ('cit_xantia', 4.48), ('rnlt_laguna', 5.04), ('alfa_156', 5.32), ('peugeot_406', 5.461), ('cit_xsara', 5.741)],\r\n  'phi_positive': [('rnlt_safrane', 6.301), ('vw_passat', 5.462), ('bmw_320d', 5.18), ('saab_tid', 4.76), ('audi_a4', 4.0605), ('cit_xantia', 3.921), ('rnlt_laguna', 3.6406), ('alfa_156', 3.501), ('peugeot_406', 3.08), ('cit_xsara', 3.08)],\r\n  'phi': [('rnlt_safrane', 3.92), ('vw_passat', 2.5214), ('bmw_320d', 1.8194), ('saab_tid', 0.839), ('audi_a4', -0.27936), ('cit_xantia', -0.5596), ('rnlt_laguna', -1.3995), ('alfa_156', -1.8194), ('peugeot_406', -2.381), ('cit_xsara', -2.661)],\r\n  'matrix': '...'\r\n}\r\n```\r\n\r\n## Electre Iv / Is\r\n\r\n```python\r\nfrom EasyMCDM.models.Electre import Electre\r\n\r\ndata = {\r\n    \"A1\" : [80, 90,  600, 5.4,  8,  5],\r\n    \"A2\" : [65, 58,  200, 9.7,  1,  1],\r\n    \"A3\" : [83, 60,  400, 7.2,  4,  7],\r\n    \"A4\" : [40, 80, 1000, 7.5,  7, 10],\r\n    \"A5\" : [52, 72,  600, 2.0,  3,  8],\r\n    \"A6\" : [94, 96,  700, 3.6,  5,  6],\r\n}\r\nweights = [0.1, 0.2, 0.2, 0.1, 0.2, 0.2]\r\nprefs = [\"min\", \"max\", \"min\", \"min\", \"min\", \"max\"]\r\nvetoes = [45, 29, 550, 6, 4.5, 4.5]\r\nindifference_threshold = 0.6\r\npreference_thresholds = [20, 10, 200, 4, 2, 2] # or None for Electre Iv\r\n\r\ne = Electre(data=data, verbose=False)\r\n\r\nresults = e.solve(weights, prefs, vetoes, indifference_threshold, preference_thresholds)\r\n```\r\n\r\n**Output :**\r\n\r\n```python\r\n{'kernels': ['A4', 'A5']}\r\n```\r\n\r\n## Pareto\r\n\r\n```python\r\nfrom EasyMCDM.models.Pareto import Pareto\r\n\r\ndata = 'tests/data/donnees.csv'\r\n# or\r\ndata = {\r\n  \"alfa_156\": [23817.0, 201.0, 8.0, 39.6, 6.0, 378.0, 31.2],\r\n  \"audi_a4\": [25771.0, 195.0, 5.7, 35.8, 7.0, 440.0, 33.0],\r\n  \"cit_xantia\": [25496.0, 195.0, 7.9, 37.0, 2.0, 480.0, 34.0]\r\n}\r\n\r\np = Pareto(data=data, verbose=False)\r\nres = p.solve(indexes=[0,1,6], prefs=[\"min\",\"max\",\"min\"])\r\nprint(res)\r\n```\r\n\r\n**Output :**\r\n\r\n```python\r\n{\r\n  'alfa_156': {'Weakly-dominated-by': [], 'Dominated-by': []},\r\n  'audi_a4': {'Weakly-dominated-by': ['alfa_156'], 'Dominated-by': ['alfa_156']}, \r\n  'cit_xantia': {'Weakly-dominated-by': ['alfa_156', 'vw_passat'], 'Dominated-by': ['alfa_156']},\r\n  'peugeot_406': {'Weakly-dominated-by': ['alfa_156', 'cit_xantia', 'rnlt_laguna', 'vw_passat'], 'Dominated-by': ['alfa_156', 'cit_xantia', 'rnlt_laguna', 'vw_passat']},\r\n  'saab_tid': {'Weakly-dominated-by': ['alfa_156'], 'Dominated-by': ['alfa_156']}, \r\n  'rnlt_laguna': {'Weakly-dominated-by': ['vw_passat'], 'Dominated-by': ['vw_passat']}, \r\n  'vw_passat': {'Weakly-dominated-by': [], 'Dominated-by': []},\r\n  'bmw_320d': {'Weakly-dominated-by': [], 'Dominated-by': []},\r\n  'cit_xsara': {'Weakly-dominated-by': [], 'Dominated-by': []},\r\n  'rnlt_safrane': {'Weakly-dominated-by': ['bmw_320d'], 'Dominated-by': ['bmw_320d']}\r\n}\r\n```\r\n\r\n## Weighted Sum\r\n\r\n```python\r\nfrom EasyMCDM.models.WeightedSum import WeightedSum\r\n\r\ndata = 'tests/data/donnees.csv'\r\n# or\r\ndata = {\r\n  \"alfa_156\": [23817.0, 201.0, 8.0, 39.6, 6.0, 378.0, 31.2],\r\n  \"audi_a4\": [25771.0, 195.0, 5.7, 35.8, 7.0, 440.0, 33.0],\r\n  \"cit_xantia\": [25496.0, 195.0, 7.9, 37.0, 2.0, 480.0, 34.0]\r\n}\r\n\r\np = WeightedSum(data=data, verbose=False)\r\nres = p.solve(pref_indexes=[0,1,6],prefs=[\"min\",\"max\",\"min\"], weights=[0.001,2,3], target='min')\r\nprint(res)\r\n```\r\n\r\n**Output :**\r\n\r\n```python\r\n[(1, 'bmw_320d', -299.04), (2, 'alfa_156', -284.58299999999997), (3, 'rnlt_safrane', -280.84), (4, 'saab_tid', -275.817), (5, 'vw_passat', -265.856), (6, 'audi_a4', -265.229), (7, 'rnlt_laguna', -262.93600000000004), (8, 'cit_xantia', -262.504), (9, 'peugeot_406', -252.551), (10, 'cit_xsara', -244.416)]\r\n```\r\n\r\n## Instant-Runoff Multicriteria Optimization (IRMO)\r\n\r\n**Short description** : Eliminate the worst individual for each criteria, until we reach the last one and select the best one.\r\n\r\n```python\r\nfrom EasyMCDM.models.Irmo import Irmo\r\n\r\np = Irmo(data=\"data/donnees.csv\", verbose=False)\r\nres = p.solve(\r\n    indexes=[0,1,4,5], # price -\u003e max_speed -\u003e comfort -\u003e trunk_space\r\n    prefs=[\"min\",\"max\",\"min\",\"max\"]\r\n)\r\nprint(res)\r\n```\r\n\r\n**Output :**\r\n\r\n```python\r\n{'best': 'saab_tid'}\r\n```\r\n\r\n# List of methods available\r\n\r\n- [Promethee I](https://www.sciencedirect.com/science/article/pii/S0098300411004365)\r\n- [Promethee II](https://www.sciencedirect.com/science/article/pii/S0098300411004365)\r\n- [Electre Iv](https://en.wikipedia.org/wiki/%C3%89LECTRE)\r\n- [Electre Is](https://en.wikipedia.org/wiki/%C3%89LECTRE)\r\n- [Weighted Sum](https://en.wikipedia.org/wiki/Weighted_sum_model)\r\n- [Pareto](https://www.sciencedirect.com/topics/engineering/pareto-optimality)\r\n- Instant-Runoff Multicriteria Optimization (IRMO)\r\n\r\n# Build PyPi package\r\n\r\nBuild: `python setup.py sdist bdist_wheel`\r\n\r\nUpload: `twine upload dist/*`\r\n\r\n# Citation\r\n\r\nIf you want to cite the tool you can use this:\r\n\r\n```bibtex\r\n@misc{EasyMCDM,\r\n  title={EasyMCDM},\r\n  author={Yanis Labrak, Quentin Raymondaud, Philippe Turcotte},\r\n  publisher={GitHub},\r\n  journal={GitHub repository},\r\n  howpublished={\\url{https://github.com/qanastek/EasyMCDM}},\r\n  year={2022}\r\n}\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqanastek%2Feasymcdm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqanastek%2Feasymcdm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqanastek%2Feasymcdm/lists"}