Skip to content

Commit

Permalink
Added the comments to the TOPSIS methods
Browse files Browse the repository at this point in the history
  • Loading branch information
dawand committed Oct 27, 2019
1 parent f061253 commit 5364dc7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 104 deletions.
6 changes: 3 additions & 3 deletions src/main/java/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");

}
10 changes: 5 additions & 5 deletions src/main/java/Profiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private ArrayList<Fuzzy> 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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
28 changes: 18 additions & 10 deletions src/main/java/TestGroupDecisionMaking.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<w1.length; i++) {
// Double wk = Math.pow(w1[i], dmWeights[0])
// * Math.pow(w2[i], dmWeights[1])
// * Math.pow(w3[i], dmWeights[2])
// * Math.pow(w4[i], dmWeights[3])
// * Math.pow(w5[i], dmWeights[4]);
// collectivePriorityWeightVector[i] = wk;
// }

// double sum = dmWeights[0] + dmWeights[1] + dmWeights[2] + dmWeights[3] + dmWeights[4];

for (int i=0; i<w1.length; i++) {
Double wk = Math.pow(w1[i], dmWeights[0])
* Math.pow(w2[i], dmWeights[1])
* Math.pow(w3[i], dmWeights[2])
* Math.pow(w4[i], dmWeights[3])
* Math.pow(w5[i], dmWeights[4]);
collectivePriorityWeightVector[i] = wk;
double wk = w1[i] * w2[i] * w3[i] * w4[i] * w5[i];
System.out.println("wk" + i + " is: " + wk);
collectivePriorityWeightVector[i] = Math.pow(wk, dmWeights[i]);
}

System.out.println("Wc: " + Arrays.toString(collectivePriorityWeightVector) + "\n");
Expand Down
167 changes: 85 additions & 82 deletions src/main/java/Topsis.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void start(){
availableSites = p.start();

sitesMatrix = transformToFuzzyValues(availableSites);
// Uncomment below if you want to normalise the Fuzzy values
// TreeMap<String, ArrayList<Double>> normalisedSitesMatrix = calculateNormalisedFuzzyMatrix(sitesMatrix);
TreeMap<String, ArrayList<Double>> normalisedWeightedFuzzyMatrix = calculateWeightedFuzzyMatrix(sitesMatrix);

Expand All @@ -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<String, ArrayList<Double>> transformToFuzzyValues(TreeMap<String, ArrayList<Fuzzy>> availableSites) {

// System.out.println(availableSites.keySet());
// System.out.println(availableSites.values());

for (Map.Entry<String,ArrayList<Fuzzy>> entry: availableSites.entrySet()) {

System.out.println(entry);
Expand All @@ -60,6 +63,11 @@ private TreeMap<String, ArrayList<Double>> transformToFuzzyValues(TreeMap<String
return sitesMatrix;
}

/**
* Normalises the numerical fuzzy values
* @param sitesMatrix the map of the nodes with their numerical fuzzy values
* @return the normalised fuzzy value matrix
*/
private TreeMap<String, ArrayList<Double>> calculateNormalisedFuzzyMatrix(TreeMap<String, ArrayList<Double>> sitesMatrix) {

TreeMap<String, ArrayList<Double>> normalisedMatrix = new TreeMap<>();
Expand Down Expand Up @@ -92,19 +100,29 @@ private TreeMap<String, ArrayList<Double>> 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 {
Expand All @@ -126,7 +144,11 @@ private TreeMap<String, ArrayList<Double>> 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<String, ArrayList<Double>> calculateWeightedFuzzyMatrix(TreeMap<String, ArrayList<Double>> sitesMatrix){

TreeMap<String, ArrayList<Double>> normalisedWeightedFuzzyMatrix = new TreeMap<>();
Expand All @@ -144,88 +166,63 @@ private TreeMap<String, ArrayList<Double>> 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<String, ArrayList<Double>> 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<String, ArrayList<Double>> 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<Fuzzy> profileNode(String node){
ArrayList<Fuzzy> 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<String, Double> calculateDistance(TreeMap<String, ArrayList<Double>> 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<String, Double> results = new TreeMap<>();


for (Map.Entry<String,ArrayList<Double>> 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));
}
}
}
Expand All @@ -238,17 +235,23 @@ private TreeMap<String, Double> calculateDistance(TreeMap<String, ArrayList<Doub
return results;
}

/**
* Calculates the relative closeness coefficient based on the ideal and anti-ideal distances for each alternative
* @param dPlusList the list of distances to ideal solution
* @param dMinusList the list of distances to anti-ideal solution
* @return map of the alternatives with their relative closeness coefficient score
*/
private TreeMap<Double, String> calculateRelativeCloseness(TreeMap<String, Double> dPlusList, TreeMap<String, Double> dMinusList) {

TreeMap<Double, String> cStar = new TreeMap<>(Collections.<Double>reverseOrder());

for (Map.Entry<String,Double> entry: dPlusList.entrySet()) {
for (Map.Entry<String,Double> 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;
}
Expand Down

0 comments on commit 5364dc7

Please sign in to comment.