{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "id": "O-7zL_Ui-jlH", "outputId": "2478fa93-05cd-4f38-abaa-c0e89ab08e73" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Starting SAW Method...\n", "\n", "\n", "--------------------------------------------------\n", "Criterion 1 (Benefit):\n", "Normalized values: [0.72727273 0.45454545 0.63636364 0.81818182 1. 0.54545455]\n", "--------------------------------------------------\n", "\n", "--------------------------------------------------\n", "Criterion 2 (Benefit):\n", "Normalized values: [0.7 0.3 0.5 0.9 1. 0.9]\n", "--------------------------------------------------\n", "\n", "--------------------------------------------------\n", "Criterion 3 (Benefit):\n", "Normalized values: [0.28571429 1. 0.85714286 1. 0.42857143 0.71428571]\n", "--------------------------------------------------\n", "\n", "--------------------------------------------------\n", "Criterion 4 (Cost):\n", "Normalized values: [1. 0.2 0.25 0.33333333 0.14285714 0.25 ]\n", "--------------------------------------------------\n", "\n", "--------------------------------------------------\n", "Weighted decision matrix:\n", "[[0.25454545 0.21 0.02857143 0.25 ]\n", " [0.15909091 0.09 0.1 0.05 ]\n", " [0.22272727 0.15 0.08571429 0.0625 ]\n", " [0.28636364 0.27 0.1 0.08333333]\n", " [0.35 0.3 0.04285714 0.03571429]\n", " [0.19090909 0.27 0.07142857 0.0625 ]]\n", "--------------------------------------------------\n", "\n", "--------------------------------------------------\n", "SAW Scores for Alternatives:\n", "[0.74311688 0.39909091 0.52094156 0.73969697 0.72857143 0.59483766]\n", "--------------------------------------------------\n", "\n", "==================================================\n", "\n", "*SAW Results:*\n", "\n", "Final Scores of Alternatives:\n", "Alternative 1: 0.7431\n", "Alternative 2: 0.3991\n", "Alternative 3: 0.5209\n", "Alternative 4: 0.7397\n", "Alternative 5: 0.7286\n", "Alternative 6: 0.5948\n", "\n", "Final Ranking of Alternatives (Best to Worst): [1 4 5 6 3 2]\n", "\n", "==================================================\n", "\n" ] }, { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAIjCAYAAAA0vUuxAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABQqUlEQVR4nO3deVwVZf//8fcBBMQFV0AQwSV3BQMlNHNDydvbpbuSvC34Utm3ksxoMerOtSQ1jRbTMskWTayvtmcZN2QqbpjlUmbllgpoKSreN9g58/ujn+fu3IADeuAovJ6PxzwenWuua+YzZ8rO25m5xmIYhiEAAAAAQLncXF0AAAAAAFzuCE4AAAAAYILgBAAAAAAmCE4AAAAAYILgBAAAAAAmCE4AAAAAYILgBAAAAAAmCE4AAAAAYILgBAAAAAAmCE4AAEiaM2eO2rRpI3d3d4WHhztlm9nZ2bJYLMrOznbK9i4n+/fvl8Vi0ZIlS1xdCgBUC4ITAFyiHTt26KabblJISIi8vb0VFBSkwYMH64UXXih3zOjRo2WxWDRp0iSH9oKCAlksFt1///2lxtx///2yWCyaMmVKqXXx8fGqU6eOzp496/Raa4PPP/9cjzzyiPr06aPXXntNM2fOrNC48s7jhSxbtkxpaWkXWWn1u9LqBYCqYjEMw3B1EQBwpdqwYYMGDBigVq1aKSEhQQEBATp06JA2btyon376ST/++GOpMadOnZK/v78CAgJktVp14MABWSwW+/r27durQYMGys3NdRgXGRmpb775Rv369dMXX3zhsK5t27Zq2rSpNm/e7NRaa4tHH31Uc+bM0b/+9S95enpWaIzZeZT+uOI0YMAAZWVlqX///pKkv/71r9q5c6f279/v5KOoGuXVaxiGiouLVadOHbm7u7umOACoRh6uLgAArmRPPfWUfH19tWXLFjVq1MhhXUFBQZlj/u///k9Wq1Xp6ekaOHCg1q5dq379+tnXX3vttXrjjTd05swZ1a9fX5JUVFSkb775RqNHj9YHH3wgq9Vq/7F69OhR/fzzzxo5cqTTa60qZ8+elY+PT7Xu80IKCgpUt27dCocmyfw8ViebzaaSkhJ5e3tX2z4tFku17g8AXI1b9QDgEvz000/q0qVLqSAiSX5+fmWOWbp0qQYPHqwBAwaoU6dOWrp0qcP6a6+9VlarVRs3brS3bdq0Sb///rseeughnTlzRtu3b7evW79+vX2cM2t966231KtXL/n4+Khx48a67rrr9Pnnnzv0eemll9SlSxd5eXkpMDBQ48eP18mTJx369O/fX127dlVubq6uu+46+fj46LHHHpMkFRcXa8qUKWrXrp28vLwUHBysRx55RMXFxQ7bWLNmja699lo1atRI9evXV4cOHezbuJDff/9dM2bMUNu2beXl5aXQ0FA99thjDtu3WCx67bXXVFRUJIvFUuHndszOY1n69++vjz/+2H51ymKxKDQ01L6+ot+HxWJRUlKSli5dav/+V69erSVLlshisWj9+vVKTk5W8+bNVa9ePd1www06duyYwzbef/99DRs2TIGBgfLy8lLbtm01Y8YMWa3WCtX73884PfPMM7JYLDpw4ECp405JSZGnp6dOnDhhb9u0aZOuv/56+fr6ysfHR/369bP/u3ze6dOnNXHiRIWGhsrLy0t+fn4aPHiwtm3bZvpdA4CzEZwA4BKEhIQoNzdXO3furFD/I0eOKCsrS2PGjJEkjRkzRu+++65KSkrsfc4HoHXr1tnb1q9fr/bt26tHjx5q2bKlww/MiganytQ6bdo03XbbbapTp46mT5+uadOmKTg4WP/85z/tfaZOnarx48crMDBQc+fO1Y033qiXX35ZQ4YM0blz5xy29+uvv2ro0KEKDw9XWlqaBgwYIJvNphEjRuiZZ57R8OHD9cILL2jUqFF69tlnFRcXZx+7a9cu/fWvf1VxcbGmT5+uuXPnasSIEaV+ZJflzjvv1OTJk3X11Vfr2WefVb9+/ZSamqpbbrnF3ufNN99U37595eXlpTfffFNvvvmmrrvuugtutyLnsSyPP/64wsPD1axZM/u+zj8/VNHv47x//vOfeuCBBxQXF6fnnnvOIYDdd999+uabbzRlyhTdc889+vDDD5WUlOQwfsmSJapfv76Sk5P13HPPKSIiQpMnT9ajjz5aoXr/2/nnvVasWFFq3YoVKzRkyBA1btzYXvt1112nU6dOacqUKZo5c6ZOnjypgQMHOtxuevfdd2vBggW68cYb9dJLL+mhhx5S3bp19d13313wewaAKmEAAC7a559/bri7uxvu7u5GdHS08cgjjxifffaZUVJSUmb/Z555xqhbt65x6tQpwzAM44cffjAkGatWrXLo5+fnZwwaNMj+OTY21khMTDQMwzBGjx5t3HzzzfZ1kZGRxlVXXeW0Wvfu3Wu4ubkZN9xwg2G1Wh3W2Ww2wzAMo6CgwPD09DSGDBni0OfFF180JBnp6en2tn79+hmSjIULFzps68033zTc3NyMr776yqF94cKFhiRj/fr1hmEYxrPPPmtIMo4dO2Z6jH+2fft2Q5Jx5513OrQ/9NBDhiTjn//8p70tISHBqFevXoW3XdHzmJWVZUgysrKy7G3Dhg0zQkJCSm2zot+HYRiGJMPNzc3YtWuXQ9/XXnvNkGTExMTYz5VhGMYDDzxguLu7GydPnrS3nT17tlQN//u//2v4+PgY//73v03r3bdvnyHJeO211+xt0dHRRkREhEO/zZs3G5KMN954wzCMP/4duuqqq4zY2FiHGs+ePWu0bt3aGDx4sL3N19fXGD9+fKl9A4ArcMUJAC7B4MGDlZOToxEjRuibb77R7NmzFRsbq6CgIH3wwQel+i9dulTDhg1TgwYNJElXXXWVIiIiSt3m1adPH23atElWq1U2m00bN25U79697evOX205e/astm/fbnq1qTK1vvfee7LZbJo8ebLc3Bz/N3F+8oMvvvhCJSUlmjhxokOfcePGqWHDhvr4448dxnl5eSkxMdGh7Z133lGnTp3UsWNHHT9+3L4MHDhQkpSVlSVJ9lsL33//fdlsNtPjPO+TTz6RJCUnJzu0P/jgg5JUqsbKqOh5rIyKfh/n9evXT507dy5zW3fddZfDRBV9+/a1T2BxXt26de3/fPr0aR0/flx9+/bV2bNn9f3331/UMcTFxSk3N1c//fSTvS0jI0NeXl72Z/C2b9+uvXv36u9//7t+/fVX+3EWFRVp0KBBWrt2rf08N2rUSJs2bdKRI0cuqh4AcCaCEwBcop49e2rlypU6ceKENm/erJSUFJ0+fVo33XSTdu/ebe/33Xff6euvv1afPn30448/2pf+/fvro48+0qlTp+x9r732WvuzTDt37lRhYaH69OkjSerdu7eOHDmi/fv32599qkhwqmitP/30k9zc3Mr9US7J/gO8Q4cODu2enp5q06ZNqedcgoKCSk28sHfvXu3atUvNmzd3WNq3by/pPxNWxMXFqU+fPrrzzjvl7++vW265RStWrDANUQcOHJCbm5vatWvn0B4QEKBGjRqV+SxORVTmPFZGRb+P81q3bl3utlq1auXw+fwtcn9+xmjXrl264YYb5Ovrq4YNG6p58+a69dZbJUmFhYUXdQw333yz3NzclJGRIemPmffeeecdDR06VA0bNrQfpyQlJCSUOtZXX31VxcXF9v3Pnj1bO3fuVHBwsHr16qWpU6fq559/vqjaAOBSMaseADiJp6enevbsqZ49e6p9+/ZKTEzUO++8Y3/v0ltvvSVJeuCBB/TAAw+UGv9///d/9qsyf37OydPTU02aNFHHjh0lSeHh4fLx8dG6deu0b98+h/7OqtXZ/nx14zybzaZu3bpp3rx5ZY4JDg62j127dq2ysrL08ccfa/Xq1crIyNDAgQP1+eefm06F/d9ThF+qypzHyqjo93FeWd/peeV9J8b/fwPJyZMn1a9fPzVs2FDTp09X27Zt5e3trW3btmnSpEmVurL3Z4GBgerbt69WrFihxx57TBs3btTBgwc1a9Yse5/z254zZ065Lxo+P5vk6NGj1bdvX61atUqff/655syZo1mzZmnlypUaOnToRdUIABeL4AQAVSAyMlLSH1OFS3/8YF22bJkGDBige++9t1T/GTNmaOnSpfYf3FdffbU9HHl5eSk6OtoeADw8PNSzZ0+tX79e+/btk5+fn/2qhDNqbdu2rWw2m3bv3l3uD9uQkBBJ0p49e9SmTRt7e0lJifbt26eYmBjT/bZt21bffPONBg0aZBpu3NzcNGjQIA0aNEjz5s3TzJkz9fjjjysrK6vcfYWEhMhms2nv3r3q1KmTvT0/P18nT560H0NlVPY8lqW8Y63M93GpsrOz9euvv2rlypUOE2GcD+J/Vtla4uLidO+992rPnj3KyMiQj4+Phg8fbl/ftm1bSVLDhg0r9O9JixYtdO+99+ree+9VQUGBrr76aj311FMEJwDVjlv1AOASZGVl2f8W/8/OP19z/la29evXa//+/UpMTNRNN91UaomLi1NWVpb9WQ4PDw9FRUVp/fr1Wr9+vf35pvN69+6ttWvXauPGjfZb+JxV66hRo+Tm5qbp06eXuvJwfnxMTIw8PT31/PPPO2xz8eLFKiws1LBhw0zrGT16tA4fPqxFixaVWvevf/1LRUVFkqTffvut1Przge6/p+n+s7/85S+SVGoWuPNXdCpS43+r7HksS7169cq8Fa6i34cznL8i9edzV1JSopdeeqnC9ZbnxhtvlLu7u95++2298847+utf/6p69erZ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q1U7duxQixYtqqpMAAAAALWcS684SVJycrISEhIUGRmpXr16KS0tTUVFRUpMTJQkxcfHKygoSKmpqZKk6dOn65prrlG7du108uRJzZkzRwcOHNCdd97pysMAAAAAUIO5PDjFxcXp2LFjmjx5svLy8hQeHq7Vq1fbJ4w4ePCg3Nz+c2HsxIkTGjdunPLy8tS4cWNFRERow4YN6ty5s6sOAQAAAEAN5/LgJElJSUlKSkoqc112drbD52effVbPPvtsNVQFAAAAAH+44mbVAwAAAIDqRnACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABOXHJysVqu2b9+uEydOOKMeAAAAALjsVDo4TZw4UYsXL5b0R2jq16+frr76agUHBys7O9vZ9QEAAACAy1U6OL377rsKCwuTJH344Yfat2+fvv/+ez3wwAN6/PHHnV4gAAAAALhapYPT8ePHFRAQIEn65JNPdPPNN6t9+/a6/fbbtWPHDqcXCAAAAACuVung5O/vr927d8tqtWr16tUaPHiwJOns2bNyd3d3eoEAAAAA4GoelR2QmJio0aNHq0WLFrJYLIqJiZEkbdq0SR07dnR6gQAAAADgapUOTlOnTlXXrl116NAh3XzzzfLy8pIkubu769FHH3V6gQAAAADgapUOTpJ00003SZL+/e9/29sSEhKcUxEAAAAAXGYq/YyT1WrVjBkzFBQUpPr16+vnn3+WJD3xxBP2acoBAAAAoCapdHB66qmntGTJEs2ePVuenp729q5du+rVV191anEAAAAAcDmodHB644039Morr2js2LEOs+iFhYXp+++/d2pxAAAAAHA5qHRwOnz4sNq1a1eq3Waz6dy5c04pCgAAAAAuJ5UOTp07d9ZXX31Vqv3dd99Vjx49nFIUAAAAAFxOKj2r3uTJk5WQkKDDhw/LZrNp5cqV2rNnj9544w199NFHVVEjAAAAALhUpa84jRw5Uh9++KG++OIL1atXT5MnT9Z3332nDz/8UIMHD66KGgEAAADApSp1xen333/XzJkzdfvtt2vNmjVVVRMAAAAAXFYqdcXJw8NDs2fP1u+//15V9QAAAADAZafSt+oNGjRIX375ZVXUAgAAAACXpUoHp6FDh+rRRx/VQw89pLffflsffPCBwwLg8jd//nyFhobK29tbUVFR2rx5c4XGLV++XBaLRaNGjXJoNwxDkydPVosWLVS3bl3FxMRo7969VVA5AACAa1R6Vr17771XkjRv3rxS6ywWi6xW66VXBaDKZGRkKDk5WQsXLlRUVJTS0tIUGxurPXv2yM/Pr9xx+/fv10MPPaS+ffuWWjd79mw9//zzev3119W6dWs98cQTio2N1e7du+Xt7V2VhwMAAFAtKn3FyWazlbsQmoDL37x58zRu3DglJiaqc+fOWrhwoXx8fJSenl7uGKvVqrFjx2ratGlq06aNwzrDMJSWlqZ//OMfGjlypLp376433nhDR44c0XvvvVfFRwMAAFA9Kh2cAFy5SkpKlJubq5iYGHubm5ubYmJilJOTU+646dOny8/PT3fccUepdfv27VNeXp7DNn19fRUVFXXBbQIAAFxJLio4ffnllxo+fLjatWundu3aacSIEfrqq6+cXRsAJzt+/LisVqv8/f0d2v39/ZWXl1fmmHXr1mnx4sVatGhRmevPj6vMNgEAAK40lQ5Ob731lmJiYuTj46MJEyZowoQJqlu3rgYNGqRly5ZVRY0AXOT06dO67bbbtGjRIjVr1szV5QAAALhMpSeHeOqppzR79mw98MAD9rYJEyZo3rx5mjFjhv7+9787tUAAztOsWTO5u7srPz/foT0/P18BAQGl+v/000/av3+/hg8fbm+z2WyS/niv2549e+zj8vPz1aJFC4dthoeHV8FRAAAAVL9KX3H6+eefHX5EnTdixAjt27fPKUUBqBqenp6KiIhQZmamvc1msykzM1PR0dGl+nfs2FE7duzQ9u3b7cuIESM0YMAAbd++XcHBwWrdurUCAgIctnnq1Clt2rSpzG0CAABciSp9xSk4OFiZmZlq166dQ/sXX3yh4OBgpxUGoGokJycrISFBkZGR6tWrl9LS0lRUVKTExERJUnx8vIKCgpSamipvb2917drVYXyjRo0kyaF94sSJevLJJ3XVVVfZpyMPDAws9b4nAACAK1Wlg9ODDz6oCRMmaPv27erdu7ckaf369VqyZImee+45pxcIwLni4uJ07NgxTZ48WXl5eQoPD9fq1avtkzscPHhQ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b3foExISYtx66632zzabzfDz8zMWLFhQbr1z5swxIiIi7J+nTJlihIWFleonyVi1apVhGIZRUFBgeHh4GGvXrrWvj46ONiZNmlThY+jWrZsxderUcusCALieh4tzGwCghtqzZ482b96sVatWSZI8PDwUFxenxYsXq3///hXaxo4dO2S1WtW+fXuH9uLiYjVt2tT+2dPTU927dy81/s9tFotFAQEBKigosLdlZGTo+eef108//aQzZ87o999/V8OGDStzmGrevLmGDBmipUuXqm/fvtq3b59ycnL08ssvV/gYJkyYoHvuuUeff/65YmJidOONN5Z5PAAA1yE4AQCqxOLFi/X7778rMDDQ3mYYhry8vPTiiy9WaBtnzpyRu7u7cnNz5e7u7rDuz7ey1a1bVxaLpdT4OnXqOHy2WCz2iSNycnI0duxYTZs2TbGxsfL19dXy5cs1d+7cCh/jeWPHjtWECRP0wgsvaNmyZerWrZu6detW4WO48847FRsbq48//liff/65UlNTNXfuXN13332VrgUAUDUITgAAp/v999/1xhtvaO7cuRoyZIjDulGjRuntt99Wx44dHdo9PT1ltVod2nr06CGr1aqCggL780LOsmHDBoWEhOjxxx+3tx04cMC0prKMHDlSd911l1avXq1ly5YpPj7evq6ixxAcHKy7775bd999t1JSUrRo0SKCEwBcRghOAACn++ijj3TixAndcccd8vX1dVh34403avHixZozZ45De2hoqM6cOaPMzEyFhYXJx8dH7du319ixYxUfH6+5c+eqR48eOnbsmDIzM9W9e3fTd0NdyFVXXaWDBw9q+fLl6tmzpz7++GP7bYV/rmnfvn3avn27WrZsqQYNGpQ5DXm9evU0atQoPfHEE/ruu+80ZswY+7qKHMPEiRM1dOhQtW/fXidOnFBWVpY6dep00ccGAHA+ZtUDADjd4sWLFRMTUyo0SX8Ep61bt+rbb791aO/du7fuvvtuxcXFqXnz5po9e7Yk6bXXXlN8fLwefPBBdejQQaNGjdKWLVvUqlWrS6pxxIgReuCBB5SUlKTw8HBt2LBBTzzxRKlar7/+eg0YMEDNmzfX22+/Xe72xo4dq2+++UZ9+/YtVZvZMVitVo0fP16dOnXS9ddfr/bt2+ull166pOMDADiXxTDKmBcWAAAAAGDHFScAAAAAMEFwAgAAAAATBCcAAAAAMEFwAgAAAAATBCcAAAAAMEFwAgAAAAATBCcAAAAAMEFwAgAAAAATBCcAAAAAMEFwAgAAAAATBCcAAAAAMPH/ANFM4Bafm3l3AAAAAElFTkSuQmCC\n" }, "metadata": {} } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "def normalize_matrix_saw(decision_matrix, is_benefit, verbose=False):\n", " \"\"\"\n", " Normalizes the decision matrix for SAW.\n", " Benefit criteria: Divide by max value.\n", " Cost criteria: Divide min value by each entry.\n", "\n", " Args:\n", " decision_matrix (numpy.ndarray): The original decision matrix.\n", " is_benefit (list): A list of booleans indicating if each criterion is a benefit (True) or cost (False).\n", " verbose (bool): If True, prints the normalization step.\n", "\n", " Returns:\n", " numpy.ndarray: The normalized decision matrix.\n", " \"\"\"\n", " num_criteria = decision_matrix.shape[1]\n", " normalized_matrix = np.zeros_like(decision_matrix, dtype=float)\n", "\n", " for j in range(num_criteria):\n", " if is_benefit[j]: # Benefit criterion\n", " max_val = np.max(decision_matrix[:, j])\n", " normalized_matrix[:, j] = decision_matrix[:, j] / max_val\n", " else: # Cost criterion\n", " min_val = np.min(decision_matrix[:, j])\n", " normalized_matrix[:, j] = min_val / decision_matrix[:, j]\n", "\n", " if verbose:\n", " print(f\"\\n{'-'*50}\")\n", " print(f\"Criterion {j + 1} {'(Benefit)' if is_benefit[j] else '(Cost)'}:\")\n", " print(f\"Normalized values: {normalized_matrix[:, j]}\")\n", " print(f\"{'-'*50}\")\n", "\n", " return normalized_matrix\n", "\n", "def apply_weights_saw(normalized_matrix, weights, verbose=False):\n", " \"\"\"\n", " Applies weights to the normalized decision matrix.\n", "\n", " Args:\n", " normalized_matrix (numpy.ndarray): The normalized decision matrix.\n", " weights (list): The weights corresponding to each criterion.\n", " verbose (bool): If True, prints the weighted matrix.\n", "\n", " Returns:\n", " numpy.ndarray: The weighted decision matrix.\n", " \"\"\"\n", " weighted_matrix = normalized_matrix * weights\n", " if verbose:\n", " print(f\"\\n{'-'*50}\")\n", " print(\"Weighted decision matrix:\")\n", " print(weighted_matrix)\n", " print(f\"{'-'*50}\")\n", " return weighted_matrix\n", "\n", "def calculate_saw_scores(weighted_matrix, verbose=False):\n", " \"\"\"\n", " Calculates the SAW scores by summing up weighted values for each alternative.\n", "\n", " Args:\n", " weighted_matrix (numpy.ndarray): The weighted decision matrix.\n", " verbose (bool): If True, prints the scores.\n", "\n", " Returns:\n", " numpy.ndarray: The total scores for each alternative.\n", " \"\"\"\n", " scores = np.sum(weighted_matrix, axis=1) # Sum of weighted values across criteria\n", " if verbose:\n", " print(f\"\\n{'-'*50}\")\n", " print(\"SAW Scores for Alternatives:\")\n", " print(scores)\n", " print(f\"{'-'*50}\")\n", " return scores\n", "\n", "def rank_saw(scores):\n", " \"\"\"\n", " Ranks the alternatives based on their SAW scores.\n", "\n", " Args:\n", " scores (numpy.ndarray): The scores of the alternatives.\n", "\n", " Returns:\n", " numpy.ndarray: The ranked indices of the alternatives (1st is the best).\n", " \"\"\"\n", " return np.argsort(scores)[::-1] # Sort scores in descending order\n", "\n", "def plot_saw_results(scores):\n", " \"\"\"\n", " Plots the SAW scores of alternatives as a bar chart.\n", "\n", " Args:\n", " scores (numpy.ndarray): The scores of the alternatives.\n", " \"\"\"\n", " plt.figure(figsize=(10, 6))\n", " bars = plt.bar(range(1, len(scores) + 1), scores, color='lightblue')\n", "\n", " # Annotate each bar with the score\n", " for bar in bars:\n", " height = bar.get_height()\n", " plt.text(bar.get_x() + bar.get_width() / 2, height + 0.03, f\"{height:.2f}\",\n", " ha='center', va='top', fontsize=10, color='black')\n", "\n", " plt.xlabel(\"Alternatives\")\n", " plt.ylabel(\"SAW Scores\")\n", " plt.title(\"SAW Scores of Alternatives\")\n", " plt.xticks(range(1, len(scores) + 1))\n", " plt.show()\n", "\n", "def saw(decision_matrix, weights, is_benefit, verbose=False, plot=True):\n", " \"\"\"\n", " Perform the Simple Additive Weighting (SAW) method for MCDM.\n", "\n", " Args:\n", " decision_matrix (list of lists): Decision matrix (alternatives x criteria).\n", " weights (list): Weights for each criterion (should sum to 1).\n", " is_benefit (list): List indicating which criteria are benefits (True) or costs (False).\n", " verbose (bool): If True, prints intermediate results.\n", " plot (bool): If True, generates a plot of the results.\n", "\n", " Prints:\n", " Final rankings and scores of alternatives.\n", " \"\"\"\n", " print(\"Starting SAW Method...\\n\")\n", "\n", " # Convert decision matrix to numpy array\n", " decision_matrix = np.array(decision_matrix)\n", "\n", " # Normalize the decision matrix\n", " normalized_matrix = normalize_matrix_saw(decision_matrix, is_benefit, verbose)\n", "\n", " # Apply weights\n", " weighted_matrix = apply_weights_saw(normalized_matrix, weights, verbose)\n", "\n", " # Calculate scores\n", " scores = calculate_saw_scores(weighted_matrix, verbose)\n", "\n", " # Rank alternatives\n", " rankings = rank_saw(scores)\n", "\n", " # Display results\n", " print(\"\\n\" + \"=\"*50)\n", " print(\"\\n*SAW Results:*\")\n", " print(\"\\nFinal Scores of Alternatives:\")\n", " for i, score in enumerate(scores):\n", " print(f\"Alternative {i + 1}: {score:.4f}\")\n", "\n", " print(\"\\nFinal Ranking of Alternatives (Best to Worst):\", rankings+1)\n", " print()\n", " print(\"=\"*50)\n", " print()\n", "\n", " # Plot results if requested\n", " if plot:\n", " plot_saw_results(scores)\n", "\n", "# Example Usage:\n", "\n", "# Decision matrix with 6 alternatives and 4 criteria\n", "decision_matrix = [[8, 7, 2, 1],\n", " [5, 3, 7, 5],\n", " [7, 5, 6, 4],\n", " [9, 9, 7, 3],\n", " [11, 10, 3, 7],\n", " [6, 9, 5, 4]]\n", "\n", "# Normalized weights for the 4 criteria\n", "weights = [0.35, 0.3, 0.1, 0.25] # Sum of weights should equal 1\n", "\n", "# Define which criteria are benefits (True) or costs (False)\n", "is_benefit = [True, True, True, False] # 4th criterion is a cost\n", "\n", "# Run SAW with verbose output and plot\n", "saw(decision_matrix, weights, is_benefit, verbose=True, plot=True)" ] } ] }