public code v1

This commit is contained in:
2026-05-22 11:14:29 +02:00
parent 427197ec5a
commit b8141736eb
28859 changed files with 575079 additions and 0 deletions
@@ -0,0 +1,483 @@
package afryca.consensusmodel;
import java.util.HashSet;
import java.util.Set;
import afryca.cm.CM;
import afryca.consensusmodel.definition.EResultElements;
import afryca.fpr.FPR;
import afryca.structure.Structure;
/**
* Quesada2015 consensus model
*
* @author Sinbad²
* @version 3.0
*/
public class Quesada2015 extends ConsensusModel {
private static final String CONSENSUS_MODEL_NAME = "F. Quesada et al. (2015)"; //$NON-NLS-1$
private static final String MU = "mu"; //$NON-NLS-1$
private static final String MAX_ROUNDS = "max_rounds"; //$NON-NLS-1$
private static final String EPSILON = "epsilon"; //$NON-NLS-1$
private static final String ALPHA = "alpha"; //$NON-NLS-1$
private static final String BETA = "beta"; //$NON-NLS-1$
private static final String INCREMENT = "increment"; //$NON-NLS-1$
private static final String H_START = "h_start"; //$NON-NLS-1$
private static final String ETA = "eta"; //$NON-NLS-1$
private static final String G = "g"; //$NON-NLS-1$
private Float mu;
private Integer maxrounds;
private Float epsilon;
private Float alpha;
private Float beta;
private Float increment;
private Integer h_start;
private Float eta;
private Float g;
private Float[] weights;
private Float[] normalizedWeights;
private Integer[][] behaviorsOfExperts;
private float[] ccs;
private float[] cdt;
private int h;
private Float cr;
private int[] advises;
private Set<Integer> expertsWithoutWeight;
@Override
protected void setModelConfiguration() {
}
@Override
protected void obtainConfigurationValues() {
mu = (Float) configuration.getValue(MU);
maxrounds = (Integer) configuration.getValue(MAX_ROUNDS);
epsilon = (Float) configuration.getValue(EPSILON);
alpha = (Float) configuration.getValue(ALPHA);
beta = (Float) configuration.getValue(BETA);
increment = (Float) configuration.getValue(INCREMENT);
h_start = (Integer) configuration.getValue(H_START);
eta = (Float) configuration.getValue(ETA);
g = (Float) configuration.getValue(G);
weights = new Float[numberOfExperts];
normalizedWeights = new Float[numberOfExperts];
float w = 1f / (float) numberOfExperts;
for (int i = 0; i < numberOfExperts; i++) {
weights[i] = g;
normalizedWeights[i] = w;
}
behaviorsOfExperts = null;
ccs = new float[numberOfExperts];
cdt = new float[numberOfExperts];
h = 0;
cr = 0f;
advises = null;
expertsWithoutWeight = new HashSet<Integer>();
}
@Override
protected Float[][][] obtainVisualizeValues() {
Structure[] auxPreferences = (Structure[]) clonePreferencesUnion(preferences, ConsensusEngine.groupPreferences(numberOfExperts, numberOfAlternatives, preferences, normalizedWeights));
Float[][][] preferencesGroupVisualization = new Float[numberOfExperts + 1][numberOfAlternatives][numberOfAlternatives];
for (int k = 0; k < numberOfExperts+1; k++) {
preferencesGroupVisualization[k] = auxPreferences[k].obtainVisualizeValues();
}
return preferencesGroupVisualization;
}
@Override
protected void preFirstSaveRoundResults() {
int round = 1;
Structure[] auxPreferences = (Structure[]) clonePreferencesUnion(preferences, ConsensusEngine.groupPreferences(numberOfExperts, numberOfAlternatives, preferences, normalizedWeights));
CM[][] sm_matrices = ConsensusEngine.similarityMatrices(numberOfExperts, numberOfAlternatives, auxPreferences);
CM cm = ConsensusEngine.consensusMatrixBasedOnSimilarityBetweenFPRs(numberOfExperts, numberOfAlternatives, sm_matrices, weights);
Float[] ac = ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, cm);
Float consensusDegreeAchieved = ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, ac);
preSaveRoundResult(round, auxPreferences,obtainVisualizeValues(), consensusDegreeAchieved);
result.put(EResultElements.initial_consensus_degree, consensusDegreeAchieved);
result.put(EResultElements.maxround, maxrounds);
result.put(EResultElements.consensus_threshold, mu);
result.put(EResultElements.consensus_model, CONSENSUS_MODEL_NAME);
}
@Override
protected void preSaveRoundResults() {
preSaveRoundResult(h + 1, preferences,obtainVisualizeValues(), cr);
}
@Override
protected void consensusRound() {
computeCollective();
CM[] proximityMatrices = ConsensusEngine.similarityMatricesRespectCollective(numberOfExperts, numberOfAlternatives, preferences, (FPR) preferences[numberOfExperts]);
CM[][] sm_matrices = ConsensusEngine.similarityMatrices(numberOfExperts, numberOfAlternatives, preferences);
eliminateExpertsSimilarityMatrices(sm_matrices);
CM cm = ConsensusEngine.consensusMatrixBasedOnSimilarityBetweenFPRs(numberOfExperts, numberOfAlternatives, sm_matrices, weights);
Float[] ac = ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, cm);
computeConsensusDegree(ac);
setLinguisticQuantifierValues();
advises = null;
if (cr < mu) {
eliminateExpertsProximityMatrices(proximityMatrices);
CM proximityAverageMatrix = ConsensusEngine.similarityAverageMatrix(numberOfExperts, numberOfAlternatives, proximityMatrices);
Boolean[][] pairsOfAlternativesToChange = identifyPairsOfAlternativesToChange(numberOfAlternatives, ac, cr, cm);
Boolean[][][] changePairsOfAlternativesByExperts = identifyChangePairsOfAlternativesByExperts(numberOfExperts, numberOfAlternatives, pairsOfAlternativesToChange, proximityMatrices, proximityAverageMatrix);
EChangeType[][][] changes = calculeChanges(numberOfExperts, numberOfAlternatives, changePairsOfAlternativesByExperts, (Structure[]) preferences, epsilon);
behaviorsOfExperts = makeChanges(numberOfExperts, numberOfAlternatives, (Structure[]) preferences, changes);
advises = new int[numberOfExperts];
for (int expert = 0; expert < numberOfExperts; expert++) {
advises[expert] = 0;
for (int a1 = 0; a1 < numberOfAlternatives; a1++) {
for (int a2 = 0; a2 < numberOfAlternatives; a2++) {
if (changes[expert][a1][a2] != EChangeType.NotChange) {
advises[expert] = advises[expert] + 1;
}
}
}
}
h++;
}
}
private void computeCollective(){
preferences[numberOfExperts] = ConsensusEngine.groupPreferences(numberOfExperts, numberOfAlternatives, preferences, normalizedWeights);
}
private void computeConsensusDegree(Float[] consensusOnAlternatives){
cr = ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, consensusOnAlternatives);
}
/**
* Eliminate experts' similarity matrices whose weight is equal to 0
* @param sm_matrices
* Similarity matrices
*/
private void eliminateExpertsSimilarityMatrices(CM[][] sm_matrices) {
for(int k = 0; k < numberOfExperts - 1; ++k) {
for(int l = k + 1; l < numberOfExperts; ++l) {
if(weights[k] == 0) {
sm_matrices[k][l] = null;
expertsWithoutWeight.add(k);
} else if(weights[l] == 0) {
sm_matrices[k][l] = null;
expertsWithoutWeight.add(l);
}
}
}
}
/**
* Eliminate experts' proximity matrices whose weight is equal to 0
* @param proximityMatrices
* Proximity matrices
*/
private void eliminateExpertsProximityMatrices(CM[] proximityMatrices) {
for(int i = 0; i < proximityMatrices.length; ++i) {
if(expertsWithoutWeight.contains(i)) {
proximityMatrices[i] = null;
}
}
}
@Override
protected void posSaveRoundResults() {
computeCollective();
CM[][] sm_matrices = ConsensusEngine.similarityMatrices(numberOfExperts, numberOfAlternatives, preferences);
eliminateExpertsSimilarityMatrices(sm_matrices);
CM cm = ConsensusEngine.consensusMatrixBasedOnSimilarityBetweenFPRs(numberOfExperts, numberOfAlternatives, sm_matrices, weights);
Float[] ac = ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, cm);
computeConsensusDegree(ac);
posSaveRoundResult(preferences,obtainVisualizeValues(), cr, advises, preferences[numberOfExperts]);
}
@Override
protected boolean mustBeCarriedOutAnotherRound() {
return (cr < mu) && (h < maxrounds);
}
@Override
protected void saveExecutionResults() {
this.configuration.setValue(PREFERENCES, preferences);
result.put(EResultElements.number_of_rounds_required, h);
result.put(EResultElements.consensus_degree_achieved, cr);
}
private void setLinguisticQuantifierValues() {
if (h >= (h_start - 1)) {
if (alpha < 0.9f) {
if ((alpha + increment) < 0.9f) {
alpha += increment;
} else {
alpha = 0.9f;
}
}
if (beta < 1f) {
if ((beta + increment) < 1f) {
beta += increment;
} else {
beta = 1f;
}
}
}
// Behavior management
if (h > 0) {
float leftPart;
float ratioAdvices;
float rightPart;
float eta2 = 1f - eta;
float differenceAdvices;
float totalNumberOfAssesments = ((float) numberOfAlternatives) * (((float) numberOfAlternatives) - 1f);
for (int i = 0; i < numberOfExperts; i++) {
if (behaviorsOfExperts[i][0] == 0) {
if(weights[i] != 0) {
ccs[i] = 1f;
}
} else {
ratioAdvices = ((float) behaviorsOfExperts[i][1]) / ((float) behaviorsOfExperts[i][0]);
leftPart = eta * ratioAdvices;
differenceAdvices = ((float) behaviorsOfExperts[i][0]) - ((float) behaviorsOfExperts[i][1]);
rightPart = eta2 * (1f - (differenceAdvices / totalNumberOfAssesments));
ccs[i] = leftPart + rightPart;
}
}
// cdt
for (int i = 0; i < numberOfExperts; i++) {
if (ccs[i] < alpha) {
cdt[i] = 0f;
} else if (ccs[i] < beta) {
cdt[i] = (ccs[i] - alpha) / (beta - alpha);
} else {
cdt[i] = 1f;
}
}
// Weights
for (int i = 0; i < numberOfExperts; i++) {
if ((weights[i] <= g) && (cdt[i] <= g)) {
weights[i] = (weights[i] * cdt[i]) / g;
} else if ((weights[i] >= g) && (cdt[i] >= g)) {
weights[i] = (weights[i] + cdt[i] - (weights[i] * cdt[i]) - g) / (1 - g);
} else {
weights[i] = (weights[i] + cdt[i]) / 2f;
}
}
normalizedWeights = ConsensusEngine.normalize(weights);
}
}
/**
* Identify pairs of alternatives to change
*
* @param alternatives
* Number of alternatives
* @param ac
* Alternatives consensus
* @param cr
* Overall consensus degree
* @param cm
* Consensus matrix
* @return Pairs of alternatives to change
*/
private static Boolean[][] identifyPairsOfAlternativesToChange(Integer alternatives, Float[] ac, Float cr, CM cm) {
Boolean[][] result = new Boolean[alternatives][alternatives];
Boolean change;
for (int i = 0; i < alternatives; i++) {
for (int j = 0; j < alternatives; j++) {
change = false;
if (i != j) {
if (ac[i] < cr) {
if ((float) cm.getValue(i, j) < cr) {
change = true;
}
}
}
result[i][j] = change;
}
}
return result;
}
/**
* Identify change in pairs of alternatives by experts
*
* @param experts
* Number of experts
* @param alternatives
* Number of alternatives
* @param pairsOfAlternativesToChange
* Pairs of alternatives to change
* @param proximityMatrices
* Proximity matrices
* @param proximityAverageMatrix
* Proximity average matrix
* @return Change in pairs of alternatives by experts
*/
private static Boolean[][][] identifyChangePairsOfAlternativesByExperts(Integer experts, Integer alternatives,
Boolean[][] pairsOfAlternativesToChange, CM[] proximityMatrices, CM proximityAverageMatrix) {
Boolean[][][] result = new Boolean[experts][alternatives][alternatives];
Boolean change;
for (int expert = 0; expert < experts; expert++) {
for (int i = 0; i < alternatives; i++) {
for (int j = 0; j < alternatives; j++) {
change = false;
if (pairsOfAlternativesToChange[i][j] && proximityMatrices[expert] != null) {
if ((float) proximityMatrices[expert].getValue(i, j) < (float) proximityAverageMatrix.getValue(i, j)) {
change = true;
}
}
result[expert][i][j] = change;
}
}
}
return result;
}
/**
* Calcule changes to make
*
* @param experts
* Number of experts
* @param alternatives
* Number of alternatives
* @param changePairsOfAlternativesByExperts
* Change in pairs of alternatives by experts
* @param preferences
* All FPR.
* @param epsilon
* Acceptability threshold
* @return Changes to make
*/
private static EChangeType[][][] calculeChanges(Integer experts, Integer alternatives,
Boolean[][][] changePairsOfAlternativesByExperts, Structure[] preferences, Float epsilon) {
EChangeType[][][] result = new EChangeType[experts][alternatives][alternatives];
Float difference;
for (int expert = 0; expert < experts; expert++) {
for (int i = 0; i < alternatives; i++) {
for (int j = 0; j < alternatives; j++) {
if (changePairsOfAlternativesByExperts[expert][i][j]) {
difference = (Float) preferences[expert].getValue(i, j) - (Float) preferences[experts].getValue(i, j);
if (difference < (-epsilon)) {
result[expert][i][j] = EChangeType.Increase;
} else if (difference > epsilon) {
result[expert][i][j] = EChangeType.Decrease;
} else {
result[expert][i][j] = EChangeType.NotChange;
}
} else {
result[expert][i][j] = EChangeType.NotChange;
}
}
}
}
return result;
}
/**
* Make preferences changes
*
* @param experts
* Number of experts
* @param alternatives
* Number of alternatives
* @param preferences
* All FPR
* @param changes
* Changes to make
*
* @return Behaviors of experts as Integer[number of experts][2 = {0 -
* number of advises, 1 - number of accepted advises}].
*/
private Integer[][] makeChanges(Integer experts, Integer alternatives, Structure[] preferences,
EChangeType[][][] changes) {
Integer[][] behaviorOfExperts = new Integer[experts][2];
float value;
EChangeType change;
double[] eChanges;
int n;
double changeMeasure;
for (int expert = 0; expert < experts; expert++) {
behaviorOfExperts[expert][0] = 0;
behaviorOfExperts[expert][1] = 0;
n = 0;
for (int i = 0; i < alternatives; i++) {
for (int j = 0; j < alternatives; j++) {
if (changes[expert][i][j] != EChangeType.NotChange) {
behaviorOfExperts[expert][0] = behaviorOfExperts[expert][0] + 1;
}
}
}
eChanges = getNChanges(behaviorOfExperts[expert][0]);
for (int i = 0; i < alternatives; i++) {
for (int j = 0; j < alternatives; j++) {
change = changes[expert][i][j];
if (change != EChangeType.NotChange) {
changeMeasure = eChanges[n++];
if (changeMeasure != 0f) {
behaviorOfExperts[expert][1] = behaviorOfExperts[expert][1] + 1;
value = (Float) preferences[expert].getValue(i, j);
if (change == EChangeType.Increase) {
value += changeMeasure;
} else if (change == EChangeType.Decrease) {
value -= changeMeasure;
}
if (value > 1f) {
value = 1f;
} else if (value < 0f) {
value = 0f;
}
((FPR) preferences[expert]).setValueSymmetrically(i, j, value);
}
}
}
}
}
return behaviorOfExperts;
}
}