diff --git a/.gitignore b/.gitignore index b54ca37..180266e 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,7 @@ target/ # Jupyter Notebook .ipynb_checkpoints - +.virtual_documents # IPython profile_default/ ipython_config.py diff --git a/hierarchical-nsa.ipynb b/hierarchical-nsa.ipynb index c92a9ac..7c0a4c3 100644 --- a/hierarchical-nsa.ipynb +++ b/hierarchical-nsa.ipynb @@ -20,7 +20,7 @@ "\n", "1. User-preferences Weights Calculations - Fuzzy Logic\n", "2. Service QoS Weights Calculations - AHP\n", - "3. Weights Normalisation such ∑ w_i = 1\n", + "3. Normalisation \n", "4. Final Weights Calculation RAT layer\n", "5. MEW\n", "6. SAW" @@ -181,16 +181,37 @@ "id": "4f998588-692a-428a-97fc-16721608a3bb", "metadata": {}, "source": [ - "#### 3. Weights Normalisation" + "#### 3. Normalisation" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 331, "id": "d47eb935-d633-4810-b9f3-fe62e9efb832", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "def square_root_normalize(matrix, criteria_types):\n", + " \"\"\"\n", + " Normalize the matrix using square root normalization,\n", + " accounting for upward and downward criteria.\n", + " \n", + " :param matrix: numpy array of shape (n_rats, n_criteria)\n", + " :param criteria_types: list of strings, either 'up' or 'down' for each criterion\n", + " :return: normalized matrix\n", + " \"\"\"\n", + " normalized = np.zeros_like(matrix, dtype=float)\n", + " \n", + " for j in range(matrix.shape[1]):\n", + " if criteria_types[j] == 'up':\n", + " normalized[:, j] = matrix[:, j] / np.sqrt(np.sum(matrix[:, j]**2))\n", + " elif criteria_types[j] == 'down':\n", + " normalized[:, j] = 1 - (matrix[:, j] / np.sqrt(np.sum(matrix[:, j]**2)))\n", + " else:\n", + " raise ValueError(f\"Invalid criterion type: {criteria_types[j]}. Must be 'up' or 'down'.\")\n", + " \n", + " return normalized" + ] }, { "cell_type": "markdown", @@ -200,14 +221,6 @@ "#### 4. Final Weights Calculation" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "66297d93-8ff7-4b64-bfd5-c76cb1ca4bc8", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "77ff1273-f181-4678-bfe6-1a51d9f44a55", @@ -218,21 +231,11 @@ }, { "cell_type": "code", - "execution_count": 241, + "execution_count": 332, "id": "ae5fa8b6-4113-421a-9112-10d1e270a8f3", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MEW Scores: [0.72184057 0.69568331 0.78690609]\n" - ] - } - ], + "outputs": [], "source": [ - "import numpy as np\n", - "\n", "def calculate_mew_scores(decision_matrix, weights):\n", " \"\"\"\n", " Calculate scores using the Multiple Exponen Weighted (MEW) method.\n", @@ -257,24 +260,7 @@ " weighted_matrix = np.power(decision_matrix, weights)\n", " mew_scores = np.prod(weighted_matrix, axis=1)\n", " \n", - " return mew_scores\n", - "\n", - "# Example usage\n", - "if __name__ == \"__main__\":\n", - " # Example normalized decision matrix (3 alternatives, 4 criteria)\n", - " decision_matrix = np.array([\n", - " [0.7, 0.8, 0.6, 0.9],\n", - " [0.6, 0.7, 0.8, 0.7],\n", - " [0.8, 0.9, 0.7, 0.8]\n", - " ])\n", - " \n", - " # Example weights\n", - " weights = np.array([0.3, 0.2, 0.3, 0.2])\n", - " \n", - " # Calculate MEW scores\n", - " scores = calculate_mew_scores(decision_matrix, weights)\n", - " \n", - " print(\"MEW Scores:\", scores)" + " return mew_scores" ] }, { @@ -287,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 242, + "execution_count": 333, "id": "2e4f5e3f-31ee-48a6-aeee-b87de52da99c", "metadata": {}, "outputs": [], @@ -328,7 +314,7 @@ }, { "cell_type": "code", - "execution_count": 243, + "execution_count": 334, "id": "da5ed195-d7d2-4cb3-a799-a7b119ad7dbd", "metadata": {}, "outputs": [], @@ -346,169 +332,27 @@ }, { "cell_type": "code", - "execution_count": 244, + "execution_count": 373, "id": "eb58539e-692c-43a9-8339-85cfcaae7c7b", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
0123456789
0CriteriaPCDJLTCLCCS
13G80010201010.0317010
24G50011050.1114030
35G3000.1110.012012030
46G1000.010.80.50.009100010.540
5LEO1000250100.450.11100015
6NaNdowndowndowndowndownupdownupup
\n", - "
" - ], - "text/plain": [ - " 0 1 2 3 4 5 6 7 8 9\n", - "0 Criteria P C D J L T CL CC S\n", - "1 3G 800 10 20 10 1 0.03 1 70 10\n", - "2 4G 500 1 10 5 0.1 1 1 40 30\n", - "3 5G 300 0.1 1 1 0.01 20 1 20 30\n", - "4 6G 100 0.01 0.8 0.5 0.009 1000 1 0.5 40\n", - "5 LEO 1000 2 50 10 0.45 0.1 1 1000 15\n", - "6 NaN down down down down down up down up up" - ] - }, - "execution_count": 244, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "df = pd.read_csv(file_path+\"/decision_matrix.csv\",header = None)\n", - "df" + "df = pd.read_csv(file_path+\"/decision_matrix.csv\",header = None)" ] }, { "cell_type": "code", - "execution_count": 245, + "execution_count": 374, "id": "a44a2674-b7c7-402a-a929-705049ab77d4", "metadata": {}, "outputs": [], "source": [ + "criteria_types = df.iloc[6:,1:].values[0]\n", + "\n", "dm_rat = df.iloc[1:6,1:7].values.astype(np.float64)\n", - "dm_ap = df.iloc[1:6,7:11].values.astype(np.float64)" + "dm_ap = df.iloc[1:6,7:11].values.astype(np.float64)\n", + "\n", + "normal_dm_rat = square_root_normalize(dm_rat, criteria_types[:6])" ] }, { @@ -521,7 +365,7 @@ }, { "cell_type": "code", - "execution_count": 264, + "execution_count": 339, "id": "21390f8d-04d4-4658-9dc2-9d8a53bda734", "metadata": {}, "outputs": [], @@ -548,7 +392,7 @@ }, { "cell_type": "code", - "execution_count": 250, + "execution_count": 340, "id": "18c9de10-b8e6-4d71-b2bf-2cb56d56292d", "metadata": {}, "outputs": [], @@ -559,7 +403,7 @@ }, { "cell_type": "code", - "execution_count": 205, + "execution_count": 341, "id": "d2fce88a-8d3b-4731-ae38-a40d958d87d7", "metadata": {}, "outputs": [], @@ -575,21 +419,10 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 342, "id": "9eba5fd3-be57-483d-bc3f-19cffedd365b", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0.2, 0.0, 0.0], dtype=object)" - ] - }, - "execution_count": 269, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def userspref_weights(criteria, users_prefs): # returns a matrix of weights user [1...U] x prefs [Q,P,C]\n", " userspref_weights = np.zeros_like(users_prefs)\n", @@ -598,36 +431,24 @@ " userspref_weights[i] = pref_weights(criteria[:2],users_prefs[i])\n", " #print(pref_weights(criteria[:2],users_prefs[i]))\n", " #print(userpref_weights[i])\n", - " return userspref_weights\n", - "\n", - "asf = userspref_weights(dm_rat[0], users_prefs)\n", - "\n", - "asf[1]\n", - "asf[]" + " return userspref_weights" ] }, { "cell_type": "code", - "execution_count": 270, + "execution_count": 343, "id": "b685c01e-8738-41c8-a7a3-1ab52749aabb", "metadata": {}, "outputs": [], "source": [ "def qos_nomarlisation(user_weights, service_weights):\n", " normal_uw = user_weights[1:] if np.sum(user_weights[1:]) <= 0 else user_weights[1:]/np.sum(user_weights[1:])\n", - " return np.concatenate((normal_uw * (1 - user_weights[0]) , service_weights * user_weights[0]))\n", - "\n", - "\n", - "#userspref_weights(dm_rat[0],users_prefs)[1][1:]\n", - "\n", - "#uw = np.array([0.5,0.4,0.8])\n", - "#sw = np.array([0.2,0.4,0.1,0.3])\n", - "#qos_nomarlisation(uw,sw)" + " return np.concatenate((normal_uw * (1 - user_weights[0]) , service_weights * user_weights[0]))" ] }, { "cell_type": "code", - "execution_count": 273, + "execution_count": 344, "id": "787edd08-2aed-4c8c-acea-c4af9fd9d198", "metadata": {}, "outputs": [], @@ -645,40 +466,65 @@ }, { "cell_type": "code", - "execution_count": 275, + "execution_count": null, + "id": "95657465-343b-4522-bd2b-2d8ca636cb18", + "metadata": {}, + "outputs": [], + "source": [ + "def hadamard_product(A, B):\n", + " # Ensure matrices have the same shape\n", + " if A.shape != B.shape:\n", + " raise ValueError(\"Matrices must have the same shape\")\n", + " \n", + " # Perform element-wise multiplication\n", + " return A * B # In NumPy, * operator performs element-wise multiplication for arrays" + ] + }, + { + "cell_type": "code", + "execution_count": 345, "id": "aff14bef-628e-4fed-b740-40577a0fd0af", "metadata": {}, + "outputs": [], + "source": [ + "rat_user_weights = np.zeros((5,27,6))\n", + "for i in range(5): \n", + " rat_user_weights[i] = users_service_weights(dm_rat[i],users_prefs,services_weights)[:, 0, :] # service 1 at index 0\n", + " #print(rat_user_weights[0])\n", + " #print(users_service_weights(dm_rat[i],users_prefs,services_weights)[:, 0, :])" + ] + }, + { + "cell_type": "code", + "execution_count": 348, + "id": "ab841183-4557-489b-b7c7-63992e03d02a", + "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 0. , 0.11300636, 0.02349906, 0.05243455,\n", " 0.01106003],\n", - " [0. , 0. , 0.02438016, 0.01272753, 0.05410509,\n", - " 0.10878722],\n", - " [0. , 0. , 0.11304389, 0.05237821, 0.02351262,\n", - " 0.01106529],\n", - " [0. , 0. , 0.05 , 0.05 , 0.05 ,\n", - " 0.05 ]])" + " [0.14545455, 0.65454545, 0.11300636, 0.02349906, 0.05243455,\n", + " 0.01106003],\n", + " [0.4 , 0.4 , 0.11300636, 0.02349906, 0.05243455,\n", + " 0.01106003],\n", + " [0.4 , 0.4 , 0.11300636, 0.02349906, 0.05243455,\n", + " 0.01106003],\n", + " [0. , 0.8 , 0.11300636, 0.02349906, 0.05243455,\n", + " 0.01106003]])" ] }, - "execution_count": 275, + "execution_count": 348, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "#for rat_criteria in dm_rat:\n", - "users_service_weights(dm_rat[0],users_prefs,services_weights)[][] \n" + "#for i in range(27):\n", + "# hadamard_product(rat_user_weights[:,i,:],normal_md_rat)\n", + " " ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d212fd1b-0181-41ea-b373-18d30c063352", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": {