diff --git a/src/main/java/Config.java b/src/main/java/Config.java index a98740c..2b44b4c 100644 --- a/src/main/java/Config.java +++ b/src/main/java/Config.java @@ -47,10 +47,10 @@ class Config { static final Fuzzy PUBLIC_PRICE = Fuzzy.VERY_HIGH; // These values can also be computed from max and min of weighted decision matrix - static double[] idealSolution = {1,1,1}; - static double[] antiIdealSolution = {0,0,0}; + static double[] idealSolution = {0.75, 1.0, 1.0}; + static double[] antiIdealSolution = {0.0, 0.0, 0.25}; // Number of decimal points for float number formatting - static DecimalFormat df = new DecimalFormat("0.000"); + static DecimalFormat df = new DecimalFormat("0.0000"); } diff --git a/src/main/java/Profiler.java b/src/main/java/Profiler.java index 5023e7c..cf20c7b 100644 --- a/src/main/java/Profiler.java +++ b/src/main/java/Profiler.java @@ -50,7 +50,7 @@ private ArrayList profileNode(String node) { siteCriteria.add(Fuzzy.VERY_LOW); } -// //Mobile-2 + //Mobile-2 else if (node.equalsIgnoreCase(Config.alternatives[1])) { siteCriteria.add(Fuzzy.VERY_HIGH); siteCriteria.add(Fuzzy.LOW); @@ -63,7 +63,7 @@ else if (node.equalsIgnoreCase(Config.alternatives[1])) { else if (node.equalsIgnoreCase(Config.alternatives[2])) { siteCriteria.add(Fuzzy.VERY_HIGH); siteCriteria.add(Fuzzy.HIGH); - siteCriteria.add(Fuzzy.GOOD); + siteCriteria.add(Fuzzy.LOW); siteCriteria.add(Fuzzy.HIGH); siteCriteria.add(Fuzzy.VERY_LOW); } @@ -98,10 +98,10 @@ else if (node.equalsIgnoreCase(Config.alternatives[5])) { //Public-1 else if (node.equalsIgnoreCase(Config.alternatives[6])) { siteCriteria.add(Fuzzy.HIGH); - siteCriteria.add(Fuzzy.GOOD); - siteCriteria.add(Fuzzy.VERY_HIGH); siteCriteria.add(Fuzzy.LOW); siteCriteria.add(Fuzzy.VERY_HIGH); + siteCriteria.add(Fuzzy.LOW); + siteCriteria.add(Fuzzy.GOOD); } //Public-2 @@ -110,7 +110,7 @@ else if (node.equalsIgnoreCase(Config.alternatives[7])) { siteCriteria.add(Fuzzy.HIGH); siteCriteria.add(Fuzzy.VERY_HIGH); siteCriteria.add(Fuzzy.LOW); - siteCriteria.add(Fuzzy.VERY_HIGH); + siteCriteria.add(Fuzzy.HIGH); } //Public-3 diff --git a/src/main/java/Test.java b/src/main/java/Test.java index a02d4a8..878c5cd 100644 --- a/src/main/java/Test.java +++ b/src/main/java/Test.java @@ -19,10 +19,10 @@ private void calculateAHP(){ // compArray[9] = Config.SECURITY_PRICE; double[] dm = {1.0, 5.0, 7.0, 9.0, 5.0, 6.0, 8.0, 3.0, 3.0, 2.0}; // DM1 -// double[] dm = {5.0, 7.0, 9.0, 9.0, 3.0, 7.0, 9.0, 7.0, 7.0, 1.0}; // DM2 -// double[] dm = {1.0/9.0, 1.0, 3.0, 3.0, 3.0, 9.0, 9.0, 9.0, 9.0, 1.0}; // DM3 -// double[] dm = {1.0, 3.0, 1.0/9.0, 5.0, 3.0, 1.0/9.0, 5.0, 1.0/9.0, 5.0, 9.0}; // DM4 -// double[] dm = {1.0, 3.0, 7.0, 1.0/9.0, 5.0, 7.0, 1.0/9.0, 3.0, 1.0/9.0, 1.0/9.0}; // DM5 +// double[] dm = {5.0, 7.0, 9.0, 9.0, 3.0, 7.0, 7.0, 5.0, 5.0, 1.0}; // DM2 +// double[] dm = {1.0/7.0, 1.0/5.0, 5.0, 5.0, 3.0, 9.0, 9.0, 9.0, 9.0, 1.0}; // DM3 +// double[] dm = {1.0, 1.0, 1.0/9.0, 3.0, 3.0, 1.0/9.0, 3.0, 1.0/9.0, 3.0, 9.0}; // DM4 +// double[] dm = {1.0, 3.0, 3.0, 1.0/9.0, 3.0, 3.0, 1.0/9.0, 3.0, 1.0/9.0, 1.0/9.0}; // DM5 System.arraycopy(dm, 0, compArray, 0, 10); diff --git a/src/main/java/TestGroupDecisionMaking.java b/src/main/java/TestGroupDecisionMaking.java index 247279d..f0b23e6 100644 --- a/src/main/java/TestGroupDecisionMaking.java +++ b/src/main/java/TestGroupDecisionMaking.java @@ -24,19 +24,19 @@ public static void main(String[] args) { // Reduce energy consumption to extend battery lifetime (e.g. when battery level is < 20) DecisionMaker dm2 = new DecisionMaker(ahp); - double[] criteriaImportance2 = {3.0, 7.0, 9.0, 9.0, 3.0, 7.0, 9.0, 5.0, 7.0, 2.0}; + double[] criteriaImportance2 = {5.0, 7.0, 9.0, 9.0, 3.0, 7.0, 7.0, 5.0, 5.0, 1.0}; // Reduce response time no matter the impact on energy consumption (e.g. when battery level > 80 or device is currently charging) DecisionMaker dm3 = new DecisionMaker(ahp); - double[] criteriaImportance3 = {1.0/3.0, 5.0, 7.0, 9.0, 5.0, 9.0, 9.0, 5.0, 7.0, 2.0}; + double[] criteriaImportance3 = {1.0/7.0, 1.0/5.0, 7.0, 7.0, 3.0, 9.0, 9.0, 9.0, 9.0, 1.0}; // Increase security level (Only offload if the offloading server is trusted and authenticated) DecisionMaker dm4 = new DecisionMaker(ahp); - double[] criteriaImportance4 = {1.0, 5.0, 1.0/5.0, 9.0, 5.0, 1.0/5.0, 8.0, 1.0/7.0, 3.0, 9.0}; + double[] criteriaImportance4 = {1.0, 1.0, 1.0/9.0, 3.0, 3.0, 1.0/9.0, 3.0, 1.0/9.0, 3.0, 9.0}; // Reduce the financial cost DecisionMaker dm5 = new DecisionMaker(ahp); - double[] criteriaImportance5 = {1.0, 5.0, 7.0, 1.0/5.0, 5.0, 6.0, 1.0/5.0, 3.0, 1.0/7.0, 1.0/9.0}; + double[] criteriaImportance5 = {1.0, 3.0, 3.0, 1.0/9.0, 3.0, 3.0, 1.0/9.0, 3.0, 1.0/9.0, 1.0/9.0}; // Start calculating pairwise comparison matrix for each DM dm1.setCriteriaImportance(criteriaImportance1); @@ -78,13 +78,21 @@ public static void main(String[] args) { Double[] dmWeights = {1.0/5.0, 1.0/5.0, 1.0/5.0, 1.0/5.0, 1.0/5.0}; Double[] collectivePriorityWeightVector = new Double[w1.length]; +// for (int i=0; i> normalisedSitesMatrix = calculateNormalisedFuzzyMatrix(sitesMatrix); TreeMap> normalisedWeightedFuzzyMatrix = calculateWeightedFuzzyMatrix(sitesMatrix); @@ -34,11 +35,13 @@ void start(){ } } + /** + * This method transforms the @Fuzzy linguistic terms to numerical values + * @param availableSites Map of the nodes with their relevant fuzzy linguistic values + * @return Returns the map of the nodes with their numerical fuzzy values + */ private TreeMap> transformToFuzzyValues(TreeMap> availableSites) { -// System.out.println(availableSites.keySet()); -// System.out.println(availableSites.values()); - for (Map.Entry> entry: availableSites.entrySet()) { System.out.println(entry); @@ -60,6 +63,11 @@ private TreeMap> transformToFuzzyValues(TreeMap> calculateNormalisedFuzzyMatrix(TreeMap> sitesMatrix) { TreeMap> normalisedMatrix = new TreeMap<>(); @@ -92,19 +100,29 @@ private TreeMap> calculateNormalisedFuzzyMatrix(TreeMa // for price: cost criterion if (i == 12) { // Avoid dividing zero by zero - if(aj == 0){ - rij.add(0.0); - rij.add(0.0); - rij.add(0.0); - } else { - double aj_cij = aj / entry.getValue().get(i + 2); - double aj_bij = aj / entry.getValue().get(i + 1); - double aj_aij = aj / entry.getValue().get(i); - - rij.add(aj_cij); - rij.add(aj_bij); - rij.add(aj_aij); - } +// double aj_cij, aj_bij, aj_aij; +// if (entry.getValue().get(i + 2) == 0){ +// aj_cij = 0; +// } else { +// aj_cij = aj / entry.getValue().get(i + 2); +// } +// +// if (entry.getValue().get(i + 1) == 0){ +// aj_bij = 0; +// } else { +// aj_bij = aj / entry.getValue().get(i + 1); +// } +// +// if (entry.getValue().get(i) == 0){ +// aj_aij = 0; +// } else{ +// aj_aij = aj / entry.getValue().get(i); +// } +// +// rij.add(aj_cij); +// rij.add(aj_bij); +// rij.add(aj_aij); + continue; } // For beneficial criteria else { @@ -126,7 +144,11 @@ private TreeMap> calculateNormalisedFuzzyMatrix(TreeMa return normalisedMatrix; } - + /** + * Adds the weights to the fuzzy values in the matrix + * @param sitesMatrix the map of the nodes with their numerical fuzzy values + * @return weighted fuzzy values evaluation matrix + */ private TreeMap> calculateWeightedFuzzyMatrix(TreeMap> sitesMatrix){ TreeMap> normalisedWeightedFuzzyMatrix = new TreeMap<>(); @@ -144,88 +166,63 @@ private TreeMap> calculateWeightedFuzzyMatrix(TreeMap< normalisedWeightedFuzzyMatrix.put(entry.getKey(), weightedMatrix); } - System.out.println("weighted fuzzy values: " + normalisedWeightedFuzzyMatrix); + System.out.println("weighted fuzzy values: "); -// System.out.println("weighted fuzzy values: "); -// -// for (Map.Entry> entry: sitesMatrix.entrySet()){ -// System.out.println(entry.getKey() + ": "); -// for (int j=0; j< entry.getValue().size(); j++) { -// Double d = entry.getValue().get(j); -// if (j%3 == 0) { -// System.out.println(); -// } -// System.out.print(Config.df.format(d) + ", "); -// } -// -// System.out.println(); -// } + for (Map.Entry> entry: normalisedWeightedFuzzyMatrix.entrySet()){ + System.out.print(entry.getKey() + ": "); + for (int j=0; j< entry.getValue().size(); j++) { + Double d = entry.getValue().get(j); + if (j%3 == 0) { + System.out.println(); + } + System.out.print(Config.df.format(d) + ", "); + } - return normalisedWeightedFuzzyMatrix; - } + System.out.println(); + } - private ArrayList profileNode(String node){ - ArrayList siteCriteria = new ArrayList<>(); - -// // Mobile node -// if (node.equalsIgnoreCase(Config.alternatives[0])){ -// siteCriteria.add(Config.MOBILE_BANDWIDTH); -// siteCriteria.add(Config.MOBILE_SPEED); -// siteCriteria.add(Config.MOBILE_AVAILABILITY); -// siteCriteria.add(Config.MOBILE_SECURITY); -// siteCriteria.add(Config.MOBILE_PRICE); -// } -// else if (node.equalsIgnoreCase(Config.alternatives[1])) { // Edge -// siteCriteria.add(Config.EDGE_BANDWIDTH); -// siteCriteria.add(Config.EDGE_SPEED); -// siteCriteria.add(Config.EDGE_AVAILABILITY); -// siteCriteria.add(Config.EDGE_SECURITY); -// siteCriteria.add(Config.EDGE_PRICE); -// } -// // Public cloud instance -// else { -// siteCriteria.add(Config.PUBLIC_BANDWIDTH); -// siteCriteria.add(Config.PUBLIC_SPEED); -// siteCriteria.add(Config.PUBLIC_AVAILABILITY); -// siteCriteria.add(Config.PUBLIC_SECURITY); -// siteCriteria.add(Config.PUBLIC_PRICE); -// } - - return siteCriteria; + return normalisedWeightedFuzzyMatrix; } + /** + * Calculates the distance to ideal and anti-ideal solutions for each node in the matrix + * @param sitesMatrix the map of the nodes with their numerical weighted fuzzy values + * @param ideal boolean to indicate ideal or anti-ideal + * @return Map of the nodes with their ideal and anti-ideal solutions + */ private TreeMap calculateDistance(TreeMap> sitesMatrix, boolean ideal) { EuclideanDistance distance = new EuclideanDistance(); // The normalized values for the ideal solution and negative ideal solution on criteria are always (1,1,1) and (0,0,0) respectively TreeMap results = new TreeMap<>(); + for (Map.Entry> entry: sitesMatrix.entrySet()) { double dValue = 0.0; for (int i = 0; i < entry.getValue().size(); i = i + 3) { double[] fuzzyValues = {entry.getValue().get(i), entry.getValue().get(i+1), entry.getValue().get(i+2)}; if (ideal) { // For D+ if (Config.costCriteria[i/3]) { // cost value for price criterion - dValue += distance.compute(fuzzyValues, Config.antiIdealSolution) * (1.0/3.0); -// dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.antiIdealSolution[0], 2) + -// Math.pow(entry.getValue().get(i+1) - Config.antiIdealSolution[1], 2) + -// Math.pow(entry.getValue().get(i+2) - Config.antiIdealSolution[2], 2)) * (1.0/3.0)); +// dValue += distance.compute(fuzzyValues, Config.antiIdealSolution) * (1.0/3.0); + dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.antiIdealSolution[0], 2) + + Math.pow(entry.getValue().get(i+1) - Config.antiIdealSolution[1], 2) + + Math.pow(entry.getValue().get(i+2) - Config.antiIdealSolution[2], 2)) * (1.0/3.0)); } else { - dValue += distance.compute(fuzzyValues, Config.idealSolution) * (1.0/3.0); -// dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.idealSolution[0], 2) + -// Math.pow(entry.getValue().get(i+1) - Config.idealSolution[1], 2) + -// Math.pow(entry.getValue().get(i+2) - Config.idealSolution[2], 2)) * (1.0/3.0)); +// dValue += distance.compute(fuzzyValues, Config.idealSolution) * (1.0/3.0); + dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.idealSolution[0], 2) + + Math.pow(entry.getValue().get(i+1) - Config.idealSolution[1], 2) + + Math.pow(entry.getValue().get(i+2) - Config.idealSolution[2], 2)) * (1.0/3.0)); } } else { // For D- if (Config.costCriteria[i/3]) { // cost value for price criterion - dValue += distance.compute(fuzzyValues, Config.idealSolution) * (1.0/3.0); -// dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.idealSolution[0], 2) + -// Math.pow(entry.getValue().get(i+1) - Config.idealSolution[1], 2) + -// Math.pow(entry.getValue().get(i+2) - Config.idealSolution[2], 2)) * (1.0/3.0)); +// dValue += distance.compute(fuzzyValues, Config.idealSolution) * (1.0/3.0); + dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.idealSolution[0], 2) + + Math.pow(entry.getValue().get(i+1) - Config.idealSolution[1], 2) + + Math.pow(entry.getValue().get(i+2) - Config.idealSolution[2], 2)) * (1.0/3.0)); } else { - dValue += distance.compute(fuzzyValues, Config.antiIdealSolution) * (1.0/3.0); -// dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.antiIdealSolution[0], 2) + -// Math.pow(entry.getValue().get(i+1) - Config.antiIdealSolution[1], 2) + -// Math.pow(entry.getValue().get(i+2) - Config.antiIdealSolution[2], 2)) * (1.0/3.0)); +// dValue += distance.compute(fuzzyValues, Config.antiIdealSolution) * (1.0/3.0); + dValue += Math.sqrt((Math.pow(entry.getValue().get(i) - Config.antiIdealSolution[0], 2) + + Math.pow(entry.getValue().get(i+1) - Config.antiIdealSolution[1], 2) + + Math.pow(entry.getValue().get(i+2) - Config.antiIdealSolution[2], 2)) * (1.0/3.0)); } } } @@ -238,17 +235,23 @@ private TreeMap calculateDistance(TreeMap calculateRelativeCloseness(TreeMap dPlusList, TreeMap dMinusList) { TreeMap cStar = new TreeMap<>(Collections.reverseOrder()); - for (Map.Entry entry: dPlusList.entrySet()) { + for (Map.Entry dPlusEntry: dPlusList.entrySet()) { // c* = d- / (d- + d+) - double c = dMinusList.get(entry.getKey()) / (dMinusList.get(entry.getKey()) + entry.getValue()); - cStar.put(c, entry.getKey()); + double c = dMinusList.get(dPlusEntry.getKey()) / (dMinusList.get(dPlusEntry.getKey()) + dPlusEntry.getValue()); + cStar.put(c, dPlusEntry.getKey()); } - System.out.println("closeness coefficient set is: " + cStar); +// System.out.println("closeness coefficient set is: " + cStar); return cStar; }