436 lines
15 KiB
Plaintext
436 lines
15 KiB
Plaintext
<snippet>
|
|
<subclass>afryca.ase.Snippet</subclass>
|
|
<file></file>
|
|
<category>Library</category>
|
|
<name>metric</name>
|
|
<description></description>
|
|
<code>
|
|
var metric = (typeof exports === "undefined")?(function metric() {}):(exports);
|
|
if(typeof global !== "undefined") { global.metric = metric; }
|
|
|
|
//
|
|
// Count number of changes in two FPR
|
|
//
|
|
metric.countChanges = function countChanges(pre, pos) {
|
|
var result = 0;
|
|
var alternatives = pre.getNumberOfAlternatives();
|
|
if(pre instanceof DecisionMatrix) { //El problema es que solo mira la diagonal superior y los dm no tienen
|
|
var criteria = pre.getNumberOfCriteria();
|
|
for (var row = 0; row < criteria; row++) {
|
|
for (var column = 0; column < alternatives; column++) {
|
|
var cTo=pre.getValue(row | 0, column | 0).compareTo(pos.getValue(row | 0, column | 0));
|
|
if (cTo!=0) {
|
|
result++;
|
|
}
|
|
}
|
|
}
|
|
}else{
|
|
for (var row = 0; row < (alternatives - 1); row++) {
|
|
for (var column = (row + 1); column < alternatives; column++) {
|
|
var cTo=pre.getValue(row | 0, column | 0).compareTo(pos.getValue(row | 0, column | 0));
|
|
if (cTo!=0) {
|
|
result++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count number of changes in a round
|
|
//
|
|
metric.countRoundChanges = function countRoundChanges(pre, pos) {
|
|
var result = 0;
|
|
var elements = pre.length - 1; // Last is collective
|
|
for (var position = 0; position < elements; position++) {
|
|
result += metric.countChanges(pre[position], pos[position]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count number of changes in a simulation
|
|
//
|
|
metric.countSimulationChanges = function countSimulationChanges(simulation) {
|
|
var rounds = simulation.getResult().get(EResultElements.rounds_results);
|
|
var changes = 0;
|
|
if (!rounds.isEmpty()) {
|
|
for (var round = 0; round < rounds.size(); round++) {
|
|
changes += metric.countRoundChanges(
|
|
rounds.get(round).get(ERoundResult.pre_preferences),
|
|
rounds.get(round).get(ERoundResult.pos_preferences));
|
|
}
|
|
}
|
|
return changes;
|
|
}
|
|
|
|
//
|
|
// Individual closeness to final collective
|
|
//
|
|
metric.individualClosenessToFinalCollective = function individualClosenessToFinalCollective(simulation) {
|
|
var result = 0;
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var m = simulationResult.get(EResultElements.number_of_experts);
|
|
var T = rounds.size();
|
|
if (m > 1) {
|
|
if (T > 0) {
|
|
for (var i = 0; i < m; i++) {
|
|
result += distance.normalizedKemeny(
|
|
rounds.get(T - 1).get(ERoundResult.pos_ranking_of_alternatives)[i],
|
|
rounds.get(T - 1).get(ERoundResult.pos_ranking_of_alternatives)[m]);
|
|
}
|
|
result = 1 - (result / m);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Collective difference between initial and final
|
|
//
|
|
metric.collectiveDifferenceBetweenInitialAndFinal = function collectiveDifferenceBetweenInitialAndFinal(simulation) {
|
|
var result = 0;
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var m = simulationResult.get(EResultElements.number_of_experts);
|
|
var T = rounds.size();
|
|
if (m > 1) {
|
|
if (T > 0) {
|
|
for (var t = 0; t < (T - 1); t++) {
|
|
result += distance.normalizedKemeny(
|
|
rounds.get(t).get(ERoundResult.pos_ranking_of_alternatives)[m],
|
|
rounds.get(t + 1).get(ERoundResult.pos_ranking_of_alternatives)[m]);
|
|
}
|
|
result /= T;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Individual difference between initial and final
|
|
//
|
|
metric.individualDifferenceBetweenInitialAndFinal = function individualDifferenceBetweenInitialAndFinal(simulation) {
|
|
var result = 0;
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var m = simulationResult.get(EResultElements.number_of_experts);
|
|
var T = rounds.size();
|
|
if (m > 1) {
|
|
if (T > 0) {
|
|
for (var i = 0; i < m; i++) {
|
|
for (var t = 0; t < (T - 1); t++) {
|
|
result += distance.normalizedKemeny(
|
|
rounds.get(t).get(ERoundResult.pos_ranking_of_alternatives)[i],
|
|
rounds.get(t + 1).get(ERoundResult.pos_ranking_of_alternatives)[i]);
|
|
}
|
|
}
|
|
result /= m;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Amount of changes
|
|
//
|
|
metric.amountOfChanges = function amountOfChanges(simulation) {
|
|
var result = 0;
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var m = simulationResult.get(EResultElements.number_of_experts);
|
|
var n = simulationResult.get(EResultElements.number_of_alternatives);
|
|
var T = rounds.size();
|
|
var advises;
|
|
var totalOfAdvices;
|
|
if (m > 1) {
|
|
if (T > 0) {
|
|
if (rounds.get(0).get(ERoundResult.advices) != null) {
|
|
totalOfAdvices = 0;
|
|
if(T == 1) {
|
|
advises = rounds.get(0).get(ERoundResult.advices);
|
|
for (var i = 0; i < m; i++) {
|
|
totalOfAdvices += advises[i];
|
|
}
|
|
result = totalOfAdvices;
|
|
} else {
|
|
for (var t = 0; t < (T - 1); t++) {
|
|
advises = rounds.get(t).get(ERoundResult.advices);
|
|
for (var i = 0; i < m; i++) {
|
|
totalOfAdvices += advises[i];
|
|
}
|
|
}
|
|
result = totalOfAdvices / (n * (n - 1) * (T - 1) * m);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Amount individual matches collective
|
|
//
|
|
metric.amountIndividualMatchesCollective = function amountIndividualMatchesCollective(simulation) {
|
|
var result = 0;
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var m = simulationResult.get(EResultElements.number_of_experts);
|
|
var T = rounds.size();
|
|
|
|
var rankingExpert;
|
|
var rankingExpertRt;
|
|
var rankingCollectiveRt;
|
|
|
|
var HashSet = Java.type('java.util.HashSet');
|
|
var topExpert;
|
|
var topExpertRt;
|
|
var topCollectiveRt;
|
|
|
|
var argMinTopExpertEqualArgMinTopCollectiveRt;
|
|
var argMinTopExpertRtEqualArgMinTopCollectiveRt;
|
|
|
|
var alternative;
|
|
if (m > 1) {
|
|
if (T > 0) {
|
|
for (var i = 0; i < m; i++) {
|
|
topExpert = new ArrayList();
|
|
topExpertRt = new ArrayList();
|
|
topCollectiveRt = new HashSet();
|
|
|
|
rankingExpert = rounds.get(0).get(ERoundResult.pos_ranking_of_alternatives)[i];
|
|
for (var pos = 0; pos < rankingExpert.length; pos++) {
|
|
if (rankingExpert[pos] == 1) {
|
|
topExpert.add(pos);
|
|
}
|
|
}
|
|
|
|
rankingExpertRt = rounds.get(T - 1).get(ERoundResult.pos_ranking_of_alternatives)[i];
|
|
for (var pos = 0; pos < rankingExpertRt.length; pos++) {
|
|
if (rankingExpertRt[pos] == 1) {
|
|
topExpertRt.add(pos);
|
|
}
|
|
}
|
|
|
|
rankingCollectiveRt = rounds.get(T - 1).get(ERoundResult.pos_ranking_of_alternatives)[m];
|
|
for (var pos = 0; pos < rankingCollectiveRt.length; pos++) {
|
|
if (rankingCollectiveRt[pos] == 1) {
|
|
topCollectiveRt.add(pos);
|
|
}
|
|
}
|
|
|
|
argMinTopExpertEqualArgMinTopCollectiveRt = false;
|
|
alternative = 0;
|
|
do {
|
|
if (topCollectiveRt.contains(topExpert.get(alternative))) {
|
|
argMinTopExpertEqualArgMinTopCollectiveRt = true;
|
|
}
|
|
alternative++;
|
|
} while ((alternative < topExpert.size()) && (!argMinTopExpertEqualArgMinTopCollectiveRt));
|
|
|
|
argMinTopExpertRtEqualArgMinTopCollectiveRt = false;
|
|
alternative = 0;
|
|
do {
|
|
if (topCollectiveRt.contains(topExpertRt.get(alternative))) {
|
|
argMinTopExpertRtEqualArgMinTopCollectiveRt = true;
|
|
}
|
|
alternative++;
|
|
} while ((alternative < topExpertRt.size()) && (!argMinTopExpertRtEqualArgMinTopCollectiveRt));
|
|
|
|
if (argMinTopExpertEqualArgMinTopCollectiveRt && argMinTopExpertRtEqualArgMinTopCollectiveRt) {
|
|
result += 1;
|
|
} else if (!argMinTopExpertEqualArgMinTopCollectiveRt && argMinTopExpertRtEqualArgMinTopCollectiveRt) {
|
|
result += 0.5;
|
|
}
|
|
|
|
}
|
|
result /= m;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Distance between collective and minimum cost
|
|
/*
|
|
metric.distanceBetweenCollectiveMinimumCost = function (simulation) {
|
|
//Simulations results
|
|
var simulationResult = simulation.getResult();
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
|
|
var numExperts = simulationResult.get(EResultElements.number_of_experts);
|
|
var numAlternatives = simulationResult.get(EResultElements.number_of_alternatives);
|
|
|
|
var preferences = rounds.get(0).get(ERoundResult.pre_preferences);
|
|
var preferencesWithoutGroup = adapters.copyNElementsVector(preferences, preferences.length - 1);
|
|
if(!(preferencesWithoutGroup[0] instanceof FPR)) {
|
|
return -1;
|
|
}
|
|
|
|
//Compute epsilon consensus model
|
|
var modifiedPreferences = rounds.get(rounds.size() - 1).get(ERoundResult.pos_preferences);
|
|
var collective = modifiedPreferences[modifiedPreferences.length - 1]
|
|
var modifiedPreferencesArray = adapters.copyNElementsVector(modifiedPreferences, modifiedPreferences.length - 1);
|
|
|
|
var distance, epsilon = 1;
|
|
for(var i = 0; i < modifiedPreferencesArray.length; ++i) {
|
|
distance = ConsensusEngine.distancePreferences(modifiedPreferencesArray[i], collective);
|
|
if(distance < epsilon) {
|
|
epsilon = distance;
|
|
}
|
|
}
|
|
|
|
//Minimum cost parameters
|
|
var alpha = simulationResult.get(EResultElements.consensus_threshold);
|
|
|
|
//Minimum cost parameters from preferences
|
|
var model = (InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.MEASUREMENT_HONGBIN, null) === 'true');
|
|
var costPref = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.COST_HONGBIN, null);
|
|
var weightsPref = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.WEIGHT_HONGBIN, null);
|
|
|
|
var cost = [];
|
|
var weights = [];
|
|
for (var i = 0; i < numExperts; i++) {
|
|
cost[i] = parseFloat(costPref.split(";")[i]);
|
|
weights[i] = parseFloat(weightsPref.split(";")[i]);
|
|
}
|
|
|
|
//Compute distance
|
|
var preferencesMinimumCost = consensus.hliu2018minimumcost(epsilon, alpha, cost, weights, preferencesWithoutGroup, numAlternatives, model);
|
|
var preferencesMinimumCostArray = adapters.copyNElementsVector(preferencesMinimumCost, preferencesMinimumCost.length);
|
|
|
|
return ConsensusEngine.distanceMinimumCost(modifiedPreferencesArray, preferencesMinimumCostArray);
|
|
}*/
|
|
|
|
metric.distanceBetweenCollectiveMinimumCost = function (simulation) {
|
|
//Simulations results
|
|
var simulationResult = simulation.getResult();
|
|
|
|
var rounds = simulationResult.get(EResultElements.rounds_results);
|
|
var numExperts = simulationResult.get(EResultElements.number_of_experts);
|
|
var numAlternatives = simulationResult.get(EResultElements.number_of_alternatives);
|
|
|
|
var preferences = rounds.get(0).get(ERoundResult.pre_preferences);
|
|
var preferencesWithoutGroup = adapters.copyNElementsVector(preferences, preferences.length - 1);
|
|
|
|
if(!(preferencesWithoutGroup[0] instanceof FPR)) {
|
|
return "Not supported information";
|
|
}
|
|
|
|
var preferencesJulia = metric.readPreferencesForJulia(numExperts, numAlternatives, preferencesWithoutGroup);
|
|
|
|
//Minimum cost parameters
|
|
var alpha = 1 - simulationResult.get(EResultElements.consensus_threshold);
|
|
var epsilon = parseFloat(InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.EPSILON_HONGBIN, null));
|
|
var costPref = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.COST_HONGBIN, null);
|
|
var weightsPref = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.WEIGHT_HONGBIN, null);
|
|
|
|
costPref = costPref.replaceAll(";", ",");
|
|
weightsPref = weightsPref.replaceAll(";", ",");
|
|
|
|
//Create file with info
|
|
var base = org.eclipse.core.runtime.Platform.getBundle("afryca.rcp").getEntry("preloaded/module/Minimum cost metric/linear_MCC_data.txt");
|
|
var path = org.eclipse.core.runtime.FileLocator.toFileURL(base).getPath();
|
|
path = path.substring(1, path.length());
|
|
|
|
var myWriter = new java.io.FileWriter(path);
|
|
myWriter.write(preferencesJulia + "&" + costPref + "&" + weightsPref);
|
|
myWriter.close();
|
|
|
|
//Minimum cost model
|
|
var model = (InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.MEASUREMENT_HONGBIN, null) === 'true');
|
|
|
|
//Julia script
|
|
var preferencesMinimumCost = metric.executeJuliaScript(numAlternatives, epsilon, alpha);
|
|
|
|
//Build FPRs with minimum cost values
|
|
var preferencesArray = metric.buildMinimumCostFPRs(preferencesMinimumCost, numAlternatives);
|
|
|
|
//Metric
|
|
var preferencesMinimumCostArray = adapters.copyNElementsVector(preferencesArray, preferencesArray.length);
|
|
var modifiedPreferences = rounds.get(rounds.size() - 1).get(ERoundResult.pos_preferences);
|
|
var modifiedPreferencesArray = adapters.copyNElementsVector(modifiedPreferences, modifiedPreferences.length - 1);
|
|
|
|
return ConsensusEngine.distanceMinimumCost(preferencesWithoutGroup, modifiedPreferencesArray, preferencesMinimumCostArray);
|
|
}
|
|
|
|
metric.readPreferencesForJulia = function(numExperts, numAlternatives, preferencesWithoutGroup) {
|
|
var preferencesJulia = "";
|
|
for(var m = 0; m < numExperts; m++) {
|
|
for(var i = 0; i < numAlternatives - 1; i++) {
|
|
for(var j = i + 1; j < numAlternatives; j++) {
|
|
preferencesJulia += preferencesWithoutGroup[m].getValue(i | 0, j | 0) + ",";
|
|
}
|
|
}
|
|
preferencesJulia = preferencesJulia.substring(0, preferencesJulia.length - 1);
|
|
preferencesJulia += ';';
|
|
}
|
|
|
|
preferencesJulia = preferencesJulia.substring(0, preferencesJulia.length - 1);
|
|
return preferencesJulia;
|
|
}
|
|
|
|
metric.executeJuliaScript = function(numAlternatives, epsilon, alpha) {
|
|
//File path
|
|
var base = org.eclipse.core.runtime.Platform.getBundle("afryca.rcp").getEntry("preloaded/module/Minimum cost metric/");
|
|
var path = org.eclipse.core.runtime.FileLocator.toFileURL(base).getPath();
|
|
path = path.substring(1, path.length());
|
|
|
|
//Execute Julia file by console
|
|
var processBuilder = new java.lang.ProcessBuilder();
|
|
processBuilder.command("cmd.exe", "/c", "cd " + path + " && " + "julia linear_MCC.jl " + numAlternatives + " " + epsilon + " " + alpha);
|
|
var process = processBuilder.start();
|
|
|
|
//Read results
|
|
var preferencesMinimumCost = new java.lang.StringBuilder();
|
|
var reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
|
|
|
|
var line;
|
|
while ((line = reader.readLine()) != null) {
|
|
preferencesMinimumCost.append(line + "\n");
|
|
}
|
|
|
|
process.waitFor();
|
|
|
|
var preferencesMinimumCostString = preferencesMinimumCost.toString();
|
|
preferencesMinimumCostString = preferencesMinimumCostString.substring(1, preferencesMinimumCostString.length - 1);
|
|
preferencesMinimumCostString = preferencesMinimumCostString.replaceAll("; ", ";");
|
|
|
|
return preferencesMinimumCostString;
|
|
}
|
|
|
|
metric.buildMinimumCostFPRs = function(preferencesMinimumCost, numAlternatives) {
|
|
var preferencesArray = [];
|
|
|
|
var preferencesByExpert = preferencesMinimumCost.split(";");
|
|
var fpr;
|
|
var fpr_values_expert;
|
|
var fpr_values;
|
|
|
|
var cont;
|
|
for(var m = 0; m < preferencesByExpert.length; m++) {
|
|
|
|
fpr = new FPR(numAlternatives);
|
|
fpr_values_expert = preferencesByExpert[m];//upper fpr values for the expert m
|
|
fpr_values = fpr_values_expert.split(" ");
|
|
|
|
cont = 0;
|
|
for(var i = 0; i < numAlternatives - 1; i++) {
|
|
for(var j = i + 1; j < numAlternatives; j++) {
|
|
fpr.setValueSymmetrically(i | 0, j | 0, Math.round(parseFloat(fpr_values[cont]) * 10000) / 10000);
|
|
cont++;
|
|
}
|
|
}
|
|
|
|
preferencesArray.push(fpr);
|
|
}
|
|
|
|
return preferencesArray;
|
|
}
|
|
|
|
metric
|
|
</code>
|
|
</snippet> |