102303812-topsis 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 102303812_topsis-1.0.0/102303812-topsis/__init__.py +1 -0
- 102303812_topsis-1.0.0/102303812-topsis/topsis.py +180 -0
- 102303812_topsis-1.0.0/102303812_topsis.egg-info/PKG-INFO +185 -0
- 102303812_topsis-1.0.0/102303812_topsis.egg-info/SOURCES.txt +11 -0
- 102303812_topsis-1.0.0/102303812_topsis.egg-info/dependency_links.txt +1 -0
- 102303812_topsis-1.0.0/102303812_topsis.egg-info/entry_points.txt +2 -0
- 102303812_topsis-1.0.0/102303812_topsis.egg-info/top_level.txt +2 -0
- 102303812_topsis-1.0.0/LICENSE +21 -0
- 102303812_topsis-1.0.0/PKG-INFO +185 -0
- 102303812_topsis-1.0.0/README.md +164 -0
- 102303812_topsis-1.0.0/_topsis_entry.py +7 -0
- 102303812_topsis-1.0.0/setup.cfg +4 -0
- 102303812_topsis-1.0.0/setup.py +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .topsis import topsis
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TOPSIS (Technique for Order of Preference by Similarity to Ideal Solution) Implementation
|
|
3
|
+
|
|
4
|
+
This module implements the TOPSIS multi-criteria decision analysis method.
|
|
5
|
+
TOPSIS ranks alternatives based on their distance from the ideal positive solution
|
|
6
|
+
and distance from the ideal negative solution.
|
|
7
|
+
|
|
8
|
+
Author: Harsh Tanwar
|
|
9
|
+
Roll Number: 102303812
|
|
10
|
+
Email: htanwar_be23@thapar.edu
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
import pandas as pd
|
|
15
|
+
import numpy as np
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def check_numeric(df):
|
|
20
|
+
"""
|
|
21
|
+
Validates that all columns from the 2nd column onwards contain numeric values.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
df (pd.DataFrame): Input dataframe to validate
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
bool: True if all columns (from 2nd onwards) are numeric, False otherwise
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
# Check from 2nd column (index 1) to the end
|
|
31
|
+
df.iloc[:, 1:].astype(float)
|
|
32
|
+
return True
|
|
33
|
+
except ValueError:
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def topsis(input_file, weights, impacts, result_file):
|
|
38
|
+
"""
|
|
39
|
+
Implements the TOPSIS algorithm to rank alternatives based on multiple criteria.
|
|
40
|
+
|
|
41
|
+
The algorithm follows these steps:
|
|
42
|
+
1. Load and validate input data
|
|
43
|
+
2. Normalize the decision matrix using vector normalization
|
|
44
|
+
3. Apply weights to the normalized matrix
|
|
45
|
+
4. Determine ideal best and ideal worst solutions
|
|
46
|
+
5. Calculate Euclidean distances from ideal solutions
|
|
47
|
+
6. Compute performance scores and rank alternatives
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
input_file (str): Path to CSV file containing alternatives and criteria values
|
|
51
|
+
weights (str): Comma-separated string of weights for each criterion
|
|
52
|
+
impacts (str): Comma-separated string of impacts ('+' for beneficial, '-' for non-beneficial)
|
|
53
|
+
result_file (str): Path for output CSV file with TOPSIS scores and ranks
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
None: Writes results to the specified output file
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
# Step 1: Load Data
|
|
60
|
+
try:
|
|
61
|
+
df = pd.read_csv(input_file)
|
|
62
|
+
except FileNotFoundError:
|
|
63
|
+
print(f"Error: File '{input_file}' not found.")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
# Step 2: Input Validation
|
|
67
|
+
if len(df.columns) < 3:
|
|
68
|
+
print("Error: Input file must contain three or more columns.")
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
if not check_numeric(df):
|
|
72
|
+
print("Error: From 2nd to last columns must contain numeric values only.")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
# Calculate number of criteria (excluding the first column which contains alternative names)
|
|
76
|
+
cols = len(df.columns) - 1
|
|
77
|
+
|
|
78
|
+
# Parse weights and impacts from comma-separated strings
|
|
79
|
+
weights = [float(w) for w in weights.split(',')]
|
|
80
|
+
impacts = impacts.split(',')
|
|
81
|
+
|
|
82
|
+
# Validate that weights, impacts, and criteria count match
|
|
83
|
+
if len(weights) != cols or len(impacts) != cols:
|
|
84
|
+
print("Error: The number of weights, number of impacts and number of columns (from 2nd to last columns) must be the same.")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
# Validate impact values are either '+' or '-'
|
|
88
|
+
if not all(i in ['+', '-'] for i in impacts):
|
|
89
|
+
print("Error: Impacts must be either +ve or -ve.")
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
# Step 3: TOPSIS Algorithm Implementation
|
|
93
|
+
|
|
94
|
+
# 3.1 Vector Normalization
|
|
95
|
+
# Create a copy of numeric columns for calculations to preserve original data
|
|
96
|
+
df_calc = df.iloc[:, 1:].copy().astype(float)
|
|
97
|
+
|
|
98
|
+
# Calculate root sum of squares for each criterion
|
|
99
|
+
rss = np.sqrt((df_calc**2).sum())
|
|
100
|
+
|
|
101
|
+
# Normalize the decision matrix using vector normalization
|
|
102
|
+
df_norm = df_calc / rss
|
|
103
|
+
|
|
104
|
+
# 3.2 Weighted Normalization
|
|
105
|
+
# Apply criterion weights to the normalized matrix
|
|
106
|
+
df_weighted = df_norm * weights
|
|
107
|
+
|
|
108
|
+
# 3.3 Determine Ideal Best and Ideal Worst Solutions
|
|
109
|
+
ideal_best = []
|
|
110
|
+
ideal_worst = []
|
|
111
|
+
|
|
112
|
+
for i in range(cols):
|
|
113
|
+
if impacts[i] == '+':
|
|
114
|
+
# For beneficial criteria: maximum is ideal best, minimum is ideal worst
|
|
115
|
+
ideal_best.append(df_weighted.iloc[:, i].max())
|
|
116
|
+
ideal_worst.append(df_weighted.iloc[:, i].min())
|
|
117
|
+
else:
|
|
118
|
+
# For non-beneficial criteria: minimum is ideal best, maximum is ideal worst
|
|
119
|
+
ideal_best.append(df_weighted.iloc[:, i].min())
|
|
120
|
+
ideal_worst.append(df_weighted.iloc[:, i].max())
|
|
121
|
+
|
|
122
|
+
# 3.4 Calculate Euclidean Distances
|
|
123
|
+
# Distance from ideal positive solution (best)
|
|
124
|
+
s_plus = np.sqrt(((df_weighted - ideal_best) ** 2).sum(axis=1))
|
|
125
|
+
|
|
126
|
+
# Distance from ideal negative solution (worst)
|
|
127
|
+
s_minus = np.sqrt(((df_weighted - ideal_worst) ** 2).sum(axis=1))
|
|
128
|
+
|
|
129
|
+
# 3.5 Calculate Performance Score
|
|
130
|
+
# Performance score = distance from worst / (distance from best + distance from worst)
|
|
131
|
+
# Higher score indicates better performance
|
|
132
|
+
total_dist = s_plus + s_minus
|
|
133
|
+
performance_score = s_minus / total_dist
|
|
134
|
+
|
|
135
|
+
# Step 4: Generate Output
|
|
136
|
+
# Add TOPSIS score and rank columns to the original dataframe
|
|
137
|
+
df['Topsis Score'] = performance_score
|
|
138
|
+
|
|
139
|
+
# Rank alternatives in descending order of TOPSIS score (higher score = better rank)
|
|
140
|
+
df['Rank'] = df['Topsis Score'].rank(ascending=False).astype(int)
|
|
141
|
+
|
|
142
|
+
# Write results to output CSV file
|
|
143
|
+
df.to_csv(result_file, index=False)
|
|
144
|
+
print(f"Result file '{result_file}' created successfully.")
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
print(f"An error occurred: {e}")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def main():
|
|
151
|
+
"""
|
|
152
|
+
Main entry point for command-line execution of TOPSIS algorithm.
|
|
153
|
+
|
|
154
|
+
Parses command-line arguments and calls the topsis function.
|
|
155
|
+
Expected arguments:
|
|
156
|
+
- InputDataFile: Path to input CSV file
|
|
157
|
+
- Weights: Comma-separated weights string
|
|
158
|
+
- Impacts: Comma-separated impacts string
|
|
159
|
+
- OutputResultFileName: Path to output CSV file
|
|
160
|
+
"""
|
|
161
|
+
if len(sys.argv) != 5:
|
|
162
|
+
print("Usage: python <program.py> <InputDataFile> <Weights> <Impacts> <OutputResultFileName>")
|
|
163
|
+
print('Example: python topsis.py data.csv "1,1,1,2,1" "+,+,+,-,+" result.csv')
|
|
164
|
+
return
|
|
165
|
+
|
|
166
|
+
input_file = sys.argv[1]
|
|
167
|
+
weights = sys.argv[2]
|
|
168
|
+
impacts = sys.argv[3]
|
|
169
|
+
result_file = sys.argv[4]
|
|
170
|
+
|
|
171
|
+
# Additional file existence check before processing
|
|
172
|
+
if not os.path.exists(input_file):
|
|
173
|
+
print(f"Error: File '{input_file}' not found.")
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
topsis(input_file, weights, impacts, result_file)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
if __name__ == "__main__":
|
|
180
|
+
main()
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: 102303812-topsis
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python package to implement TOPSIS
|
|
5
|
+
Home-page: https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis
|
|
6
|
+
Author: Harsh Tanwar
|
|
7
|
+
Author-email: htanwar_be23@thapar.edu
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: author-email
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
# 102303812-topsis
|
|
23
|
+
|
|
24
|
+
A Python package to implement **TOPSIS** (Technique for Order of Preference by Similarity to Ideal Solution) for multi-criteria decision analysis.
|
|
25
|
+
|
|
26
|
+
**Author:** Harsh Tanwar
|
|
27
|
+
**Roll No:** 102303812
|
|
28
|
+
**Email:** htanwar_be23@thapar.edu
|
|
29
|
+
|
|
30
|
+
**Repository:** [Assignment1-Topsis](https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What is TOPSIS?
|
|
35
|
+
|
|
36
|
+
TOPSIS ranks alternatives by comparing each to an *ideal positive* and *ideal negative* solution. Alternatives closer to the ideal positive and farther from the ideal negative get higher scores and better ranks. The method uses vector normalization, weighted criteria, and Euclidean distances to compute a performance score for each alternative.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Python 3.6+
|
|
43
|
+
- **pandas** – data handling
|
|
44
|
+
- **numpy** – numerical operations
|
|
45
|
+
|
|
46
|
+
Install dependencies:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install pandas numpy
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
### From PyPI (if published)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install 102303812-topsis
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From source (clone or download the repo)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/htan11/course-materials.git
|
|
66
|
+
cd course-materials/UCS654/Assignment1-Topsis
|
|
67
|
+
pip install .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or, in the folder containing `setup.py`:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Command line
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
topsis <InputDataFile> <Weights> <Impacts> <OutputResultFileName>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Example (with 5 criteria):**
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### As a Python module
|
|
93
|
+
|
|
94
|
+
(Because the package name contains a hyphen, use `importlib` to import.)
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import importlib
|
|
98
|
+
topsis = getattr(importlib.import_module("102303812-topsis"), "topsis")
|
|
99
|
+
|
|
100
|
+
topsis("data.csv", "1,1,1,1,1", "+,+,-,+,-", "result.csv")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Parameters
|
|
106
|
+
|
|
107
|
+
| Parameter | Description |
|
|
108
|
+
|-----------|-------------|
|
|
109
|
+
| **InputDataFile** | Path to a CSV file: first column = alternative names, remaining columns = numeric criterion values. Must have a header row. |
|
|
110
|
+
| **Weights** | Comma-separated weights for each criterion (e.g. `"1,1,1,2,1"`). Number of values must match number of criteria. |
|
|
111
|
+
| **Impacts** | Comma-separated impacts: `+` for beneficial (higher is better), `-` for non-beneficial (lower is better). Same count as criteria. |
|
|
112
|
+
| **OutputResultFileName** | Path for the output CSV. Contains original columns plus **Topsis Score** and **Rank**. |
|
|
113
|
+
|
|
114
|
+
- Beneficial (`+`): e.g. Quality, Customer Rating — higher value is better.
|
|
115
|
+
- Non-beneficial (`-`): e.g. Price, Delivery Time — lower value is better.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Input file format
|
|
120
|
+
|
|
121
|
+
CSV with a header; first column = alternative names, rest = numeric only.
|
|
122
|
+
|
|
123
|
+
**Example (`data.csv`):**
|
|
124
|
+
|
|
125
|
+
| Product | Quality | Price | Features | Customer Rating | Delivery Time |
|
|
126
|
+
|---------|---------|-------|----------|-----------------|---------------|
|
|
127
|
+
| A1 | 8.5 | 450 | 7.2 | 4.3 | 3 |
|
|
128
|
+
| A2 | 7.8 | 380 | 8.1 | 4.5 | 5 |
|
|
129
|
+
| ... | ... | ... | ... | ... | ... |
|
|
130
|
+
|
|
131
|
+
- Column 1: labels (not used in math).
|
|
132
|
+
- Columns 2–6: criteria. Weights and impacts must be given for each of these in order.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Example with this dataset
|
|
137
|
+
|
|
138
|
+
For 5 criteria (Quality, Price, Features, Customer Rating, Delivery Time):
|
|
139
|
+
|
|
140
|
+
- **Weights:** `"1,1,1,1,1"` (equal weight).
|
|
141
|
+
- **Impacts:** `"+,+,-,+,-"` (Quality +, Price +, Features -, Customer Rating +, Delivery Time -).
|
|
142
|
+
|
|
143
|
+
Run:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Output CSV will have all input columns plus:
|
|
150
|
+
|
|
151
|
+
- **Topsis Score** – higher is better.
|
|
152
|
+
- **Rank** – 1 = best alternative.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Output
|
|
157
|
+
|
|
158
|
+
The result file contains:
|
|
159
|
+
|
|
160
|
+
- All original columns.
|
|
161
|
+
- **Topsis Score** – performance score in [0, 1].
|
|
162
|
+
- **Rank** – integer rank (1 = best).
|
|
163
|
+
|
|
164
|
+
Example message: `Result file 'result.csv' created successfully.`
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Project structure
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
assignment1_DS-main/
|
|
172
|
+
├── README.md
|
|
173
|
+
├── setup.py
|
|
174
|
+
├── data.csv # Sample input
|
|
175
|
+
├── 102303812-topsis/
|
|
176
|
+
│ ├── __init__.py
|
|
177
|
+
│ └── topsis.py # TOPSIS implementation
|
|
178
|
+
└── LICENSE
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
_topsis_entry.py
|
|
4
|
+
setup.py
|
|
5
|
+
102303812-topsis/__init__.py
|
|
6
|
+
102303812-topsis/topsis.py
|
|
7
|
+
102303812_topsis.egg-info/PKG-INFO
|
|
8
|
+
102303812_topsis.egg-info/SOURCES.txt
|
|
9
|
+
102303812_topsis.egg-info/dependency_links.txt
|
|
10
|
+
102303812_topsis.egg-info/entry_points.txt
|
|
11
|
+
102303812_topsis.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harsh Tanwar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: 102303812-topsis
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python package to implement TOPSIS
|
|
5
|
+
Home-page: https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis
|
|
6
|
+
Author: Harsh Tanwar
|
|
7
|
+
Author-email: htanwar_be23@thapar.edu
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: author-email
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
# 102303812-topsis
|
|
23
|
+
|
|
24
|
+
A Python package to implement **TOPSIS** (Technique for Order of Preference by Similarity to Ideal Solution) for multi-criteria decision analysis.
|
|
25
|
+
|
|
26
|
+
**Author:** Harsh Tanwar
|
|
27
|
+
**Roll No:** 102303812
|
|
28
|
+
**Email:** htanwar_be23@thapar.edu
|
|
29
|
+
|
|
30
|
+
**Repository:** [Assignment1-Topsis](https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What is TOPSIS?
|
|
35
|
+
|
|
36
|
+
TOPSIS ranks alternatives by comparing each to an *ideal positive* and *ideal negative* solution. Alternatives closer to the ideal positive and farther from the ideal negative get higher scores and better ranks. The method uses vector normalization, weighted criteria, and Euclidean distances to compute a performance score for each alternative.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Python 3.6+
|
|
43
|
+
- **pandas** – data handling
|
|
44
|
+
- **numpy** – numerical operations
|
|
45
|
+
|
|
46
|
+
Install dependencies:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install pandas numpy
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
### From PyPI (if published)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install 102303812-topsis
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From source (clone or download the repo)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/htan11/course-materials.git
|
|
66
|
+
cd course-materials/UCS654/Assignment1-Topsis
|
|
67
|
+
pip install .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or, in the folder containing `setup.py`:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Command line
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
topsis <InputDataFile> <Weights> <Impacts> <OutputResultFileName>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Example (with 5 criteria):**
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### As a Python module
|
|
93
|
+
|
|
94
|
+
(Because the package name contains a hyphen, use `importlib` to import.)
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import importlib
|
|
98
|
+
topsis = getattr(importlib.import_module("102303812-topsis"), "topsis")
|
|
99
|
+
|
|
100
|
+
topsis("data.csv", "1,1,1,1,1", "+,+,-,+,-", "result.csv")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Parameters
|
|
106
|
+
|
|
107
|
+
| Parameter | Description |
|
|
108
|
+
|-----------|-------------|
|
|
109
|
+
| **InputDataFile** | Path to a CSV file: first column = alternative names, remaining columns = numeric criterion values. Must have a header row. |
|
|
110
|
+
| **Weights** | Comma-separated weights for each criterion (e.g. `"1,1,1,2,1"`). Number of values must match number of criteria. |
|
|
111
|
+
| **Impacts** | Comma-separated impacts: `+` for beneficial (higher is better), `-` for non-beneficial (lower is better). Same count as criteria. |
|
|
112
|
+
| **OutputResultFileName** | Path for the output CSV. Contains original columns plus **Topsis Score** and **Rank**. |
|
|
113
|
+
|
|
114
|
+
- Beneficial (`+`): e.g. Quality, Customer Rating — higher value is better.
|
|
115
|
+
- Non-beneficial (`-`): e.g. Price, Delivery Time — lower value is better.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Input file format
|
|
120
|
+
|
|
121
|
+
CSV with a header; first column = alternative names, rest = numeric only.
|
|
122
|
+
|
|
123
|
+
**Example (`data.csv`):**
|
|
124
|
+
|
|
125
|
+
| Product | Quality | Price | Features | Customer Rating | Delivery Time |
|
|
126
|
+
|---------|---------|-------|----------|-----------------|---------------|
|
|
127
|
+
| A1 | 8.5 | 450 | 7.2 | 4.3 | 3 |
|
|
128
|
+
| A2 | 7.8 | 380 | 8.1 | 4.5 | 5 |
|
|
129
|
+
| ... | ... | ... | ... | ... | ... |
|
|
130
|
+
|
|
131
|
+
- Column 1: labels (not used in math).
|
|
132
|
+
- Columns 2–6: criteria. Weights and impacts must be given for each of these in order.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Example with this dataset
|
|
137
|
+
|
|
138
|
+
For 5 criteria (Quality, Price, Features, Customer Rating, Delivery Time):
|
|
139
|
+
|
|
140
|
+
- **Weights:** `"1,1,1,1,1"` (equal weight).
|
|
141
|
+
- **Impacts:** `"+,+,-,+,-"` (Quality +, Price +, Features -, Customer Rating +, Delivery Time -).
|
|
142
|
+
|
|
143
|
+
Run:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Output CSV will have all input columns plus:
|
|
150
|
+
|
|
151
|
+
- **Topsis Score** – higher is better.
|
|
152
|
+
- **Rank** – 1 = best alternative.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Output
|
|
157
|
+
|
|
158
|
+
The result file contains:
|
|
159
|
+
|
|
160
|
+
- All original columns.
|
|
161
|
+
- **Topsis Score** – performance score in [0, 1].
|
|
162
|
+
- **Rank** – integer rank (1 = best).
|
|
163
|
+
|
|
164
|
+
Example message: `Result file 'result.csv' created successfully.`
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Project structure
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
assignment1_DS-main/
|
|
172
|
+
├── README.md
|
|
173
|
+
├── setup.py
|
|
174
|
+
├── data.csv # Sample input
|
|
175
|
+
├── 102303812-topsis/
|
|
176
|
+
│ ├── __init__.py
|
|
177
|
+
│ └── topsis.py # TOPSIS implementation
|
|
178
|
+
└── LICENSE
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# 102303812-topsis
|
|
2
|
+
|
|
3
|
+
A Python package to implement **TOPSIS** (Technique for Order of Preference by Similarity to Ideal Solution) for multi-criteria decision analysis.
|
|
4
|
+
|
|
5
|
+
**Author:** Harsh Tanwar
|
|
6
|
+
**Roll No:** 102303812
|
|
7
|
+
**Email:** htanwar_be23@thapar.edu
|
|
8
|
+
|
|
9
|
+
**Repository:** [Assignment1-Topsis](https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What is TOPSIS?
|
|
14
|
+
|
|
15
|
+
TOPSIS ranks alternatives by comparing each to an *ideal positive* and *ideal negative* solution. Alternatives closer to the ideal positive and farther from the ideal negative get higher scores and better ranks. The method uses vector normalization, weighted criteria, and Euclidean distances to compute a performance score for each alternative.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- Python 3.6+
|
|
22
|
+
- **pandas** – data handling
|
|
23
|
+
- **numpy** – numerical operations
|
|
24
|
+
|
|
25
|
+
Install dependencies:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install pandas numpy
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
### From PyPI (if published)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install 102303812-topsis
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### From source (clone or download the repo)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/htan11/course-materials.git
|
|
45
|
+
cd course-materials/UCS654/Assignment1-Topsis
|
|
46
|
+
pip install .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or, in the folder containing `setup.py`:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install .
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Command line
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
topsis <InputDataFile> <Weights> <Impacts> <OutputResultFileName>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Example (with 5 criteria):**
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### As a Python module
|
|
72
|
+
|
|
73
|
+
(Because the package name contains a hyphen, use `importlib` to import.)
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import importlib
|
|
77
|
+
topsis = getattr(importlib.import_module("102303812-topsis"), "topsis")
|
|
78
|
+
|
|
79
|
+
topsis("data.csv", "1,1,1,1,1", "+,+,-,+,-", "result.csv")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Parameters
|
|
85
|
+
|
|
86
|
+
| Parameter | Description |
|
|
87
|
+
|-----------|-------------|
|
|
88
|
+
| **InputDataFile** | Path to a CSV file: first column = alternative names, remaining columns = numeric criterion values. Must have a header row. |
|
|
89
|
+
| **Weights** | Comma-separated weights for each criterion (e.g. `"1,1,1,2,1"`). Number of values must match number of criteria. |
|
|
90
|
+
| **Impacts** | Comma-separated impacts: `+` for beneficial (higher is better), `-` for non-beneficial (lower is better). Same count as criteria. |
|
|
91
|
+
| **OutputResultFileName** | Path for the output CSV. Contains original columns plus **Topsis Score** and **Rank**. |
|
|
92
|
+
|
|
93
|
+
- Beneficial (`+`): e.g. Quality, Customer Rating — higher value is better.
|
|
94
|
+
- Non-beneficial (`-`): e.g. Price, Delivery Time — lower value is better.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Input file format
|
|
99
|
+
|
|
100
|
+
CSV with a header; first column = alternative names, rest = numeric only.
|
|
101
|
+
|
|
102
|
+
**Example (`data.csv`):**
|
|
103
|
+
|
|
104
|
+
| Product | Quality | Price | Features | Customer Rating | Delivery Time |
|
|
105
|
+
|---------|---------|-------|----------|-----------------|---------------|
|
|
106
|
+
| A1 | 8.5 | 450 | 7.2 | 4.3 | 3 |
|
|
107
|
+
| A2 | 7.8 | 380 | 8.1 | 4.5 | 5 |
|
|
108
|
+
| ... | ... | ... | ... | ... | ... |
|
|
109
|
+
|
|
110
|
+
- Column 1: labels (not used in math).
|
|
111
|
+
- Columns 2–6: criteria. Weights and impacts must be given for each of these in order.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Example with this dataset
|
|
116
|
+
|
|
117
|
+
For 5 criteria (Quality, Price, Features, Customer Rating, Delivery Time):
|
|
118
|
+
|
|
119
|
+
- **Weights:** `"1,1,1,1,1"` (equal weight).
|
|
120
|
+
- **Impacts:** `"+,+,-,+,-"` (Quality +, Price +, Features -, Customer Rating +, Delivery Time -).
|
|
121
|
+
|
|
122
|
+
Run:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
topsis data.csv "1,1,1,1,1" "+,+,-,+,-" result.csv
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Output CSV will have all input columns plus:
|
|
129
|
+
|
|
130
|
+
- **Topsis Score** – higher is better.
|
|
131
|
+
- **Rank** – 1 = best alternative.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Output
|
|
136
|
+
|
|
137
|
+
The result file contains:
|
|
138
|
+
|
|
139
|
+
- All original columns.
|
|
140
|
+
- **Topsis Score** – performance score in [0, 1].
|
|
141
|
+
- **Rank** – integer rank (1 = best).
|
|
142
|
+
|
|
143
|
+
Example message: `Result file 'result.csv' created successfully.`
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Project structure
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
assignment1_DS-main/
|
|
151
|
+
├── README.md
|
|
152
|
+
├── setup.py
|
|
153
|
+
├── data.csv # Sample input
|
|
154
|
+
├── 102303812-topsis/
|
|
155
|
+
│ ├── __init__.py
|
|
156
|
+
│ └── topsis.py # TOPSIS implementation
|
|
157
|
+
└── LICENSE
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="102303812-topsis",
|
|
8
|
+
version="1.0.0",
|
|
9
|
+
author="Harsh Tanwar",
|
|
10
|
+
author_email="htanwar_be23@thapar.edu",
|
|
11
|
+
description="A Python package to implement TOPSIS",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/htan11/course-materials/tree/main/UCS654/Assignment1-Topsis",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
],
|
|
21
|
+
py_modules=["_topsis_entry"],
|
|
22
|
+
entry_points={
|
|
23
|
+
"console_scripts": [
|
|
24
|
+
"topsis=_topsis_entry:main",
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
)
|