Files
AFRYCA/plugins/afryca.rcp/preloaded/repository/Library/snippet/metric.script
T
2026-05-22 11:14:29 +02:00

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>