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,389 @@
package afryca.consensusmodel;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import afryca.consensusmodel.definition.EResultElements;
import afryca.fpr.FPR;
import afryca.structure.Structure;
/**
* HerreraViedma2002 consensus model
*
* @author Sinbad²
* @version 3.0
*/
public class HerreraViedma2002 extends ConsensusModel {
private static final String CONSENSUS_MODEL_NAME = "E. Herrera-Viedma et al. (2002)"; //$NON-NLS-1$
private static final String AGGREGATION_QUANTIFIERS = "aggregation_quantifiers"; //$NON-NLS-1$
private static final String EXPLOTATION_QUANTIFIERS = "explotation_quantifiers"; //$NON-NLS-1$
private static final String B = "b"; //$NON-NLS-1$
private static final String BETA = "beta"; //$NON-NLS-1$
private static final String MAXCYCLE = "maxcycle"; //$NON-NLS-1$
private static final String CL = "cl"; //$NON-NLS-1$
private Float[] aggregation_quantifiers;
private Float[] explotation_quantifiers;
private Float b;
private Float beta;
private Integer maxcycle;
private Float cl;
private Integer[][] alternativesRankings;
private int h;
private Float cm;
private int[] advises;
private Float[] aggregation_weights;
private Float[] explotation_weights;
@Override
protected void setModelConfiguration() {
}
@Override
protected void obtainConfigurationValues() {
aggregation_quantifiers = (Float[]) configuration.getValue(AGGREGATION_QUANTIFIERS);
explotation_quantifiers = (Float[]) configuration.getValue(EXPLOTATION_QUANTIFIERS);
b = (Float) configuration.getValue(B);
beta = (Float) configuration.getValue(BETA);
maxcycle = (Integer) configuration.getValue(MAXCYCLE);
cl = (Float) configuration.getValue(CL);
alternativesRankings = new Integer[numberOfExperts + 1][];
h = 0;
cm = 0f;
advises = null;
aggregation_weights = ConsensusEngine.computeOWAWeights(numberOfExperts, aggregation_quantifiers[0], aggregation_quantifiers[1]);
explotation_weights = ConsensusEngine.computeOWAWeights(numberOfAlternatives, explotation_quantifiers[0], explotation_quantifiers[1]);
}
@Override
protected Float[][][] obtainVisualizeValues() {
Structure[] auxPreferences = (Structure[]) clonePreferencesUnion(preferences, ConsensusEngine.groupPreferencesOWA(numberOfExperts, numberOfAlternatives, preferences, aggregation_weights));
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() {
Structure[] auxPreferences = clonePreferencesUnion(preferences, ConsensusEngine.groupPreferencesOWA(numberOfExperts, numberOfAlternatives, preferences, aggregation_weights));
Float[] QGDD;
for (int i = 0; i <= numberOfExperts; i++) {
QGDD = ConsensusEngine.QGDD(numberOfAlternatives, auxPreferences[i], explotation_weights);
alternativesRankings[i] = ConsensusEngine.alternativesRanking(QGDD);
}
Set<Integer> Xsol = ConsensusEngine.solutionSet(alternativesRankings[numberOfExperts]);
Integer[][] differencesBetweenRankings = differencesBetweenRankings(alternativesRankings);
Float[][] consensusDegreesOnAlternativesByExperts = consensusDegreesOnAlternativesByExperts(differencesBetweenRankings, b);
Float[] consensusDegreesOnAlternatives = consensusDegreesOnAlternatives(consensusDegreesOnAlternativesByExperts);
Float consensusDegreeAchieved = consensusMeasure(consensusDegreesOnAlternatives, beta, Xsol);
preSaveRoundResult(1, auxPreferences, obtainVisualizeValues(), consensusDegreeAchieved);
result.put(EResultElements.initial_consensus_degree, consensusDegreeAchieved);
result.put(EResultElements.maxround, maxcycle);
result.put(EResultElements.consensus_threshold, cl);
result.put(EResultElements.consensus_model, CONSENSUS_MODEL_NAME);
}
@Override
protected void preSaveRoundResults() {
preSaveRoundResult(h + 1, preferences, obtainVisualizeValues(), cm);
}
@Override
protected void consensusRound() {
computeCollective();
Float[] QGDD;
for (int i = 0; i <= numberOfExperts; i++) {
QGDD = ConsensusEngine.QGDD(numberOfAlternatives, preferences[i], explotation_weights);
alternativesRankings[i] = ConsensusEngine.alternativesRanking(QGDD);
}
Set<Integer> Xsol = ConsensusEngine.solutionSet(alternativesRankings[numberOfExperts]);
Integer[][] differencesBetweenRankings = differencesBetweenRankings(alternativesRankings);
Float[][] consensusDegreesOnAlternativesByExperts = consensusDegreesOnAlternativesByExperts(differencesBetweenRankings, b);
Float[] consensusDegreesOnAlternatives = consensusDegreesOnAlternatives(consensusDegreesOnAlternativesByExperts);
computeConsensusDegree(consensusDegreesOnAlternatives, Xsol);
advises = null;
if (cm < cl) {
Float[] proximityMeasures = proximityMeasures(consensusDegreesOnAlternativesByExperts, beta, Xsol);
Set<Integer> farthestExperts = selectFarthestExperts(proximityMeasures);
Map<Integer, EChangeType[]> changesByExperts = changesByExperts(farthestExperts, differencesBetweenRankings);
makeChanges(changesByExperts, preferences);
advises = new int[numberOfExperts];
for (int expert = 0; expert < numberOfExperts; expert++) {
advises[expert] = 0;
if (changesByExperts.get(expert) != null) {
for (EChangeType change : changesByExperts.get(expert)) {
if (change != EChangeType.NotChange) {
advises[expert] = advises[expert] + 1;
}
}
}
}
h++;
}
}
private void computeCollective() {
preferences[numberOfExperts] = ConsensusEngine.groupPreferencesOWA(numberOfExperts, numberOfAlternatives, preferences, aggregation_weights);
}
private void computeConsensusDegree(Float[] consensusDegreesOnAlternatives, Set<Integer> Xsol) {
cm = consensusMeasure(consensusDegreesOnAlternatives, beta, Xsol);
}
@Override
protected void posSaveRoundResults() {
computeCollective();
Float[] QGDD;
for (int i = 0; i <= numberOfExperts; i++) {
QGDD = ConsensusEngine.QGDD(numberOfAlternatives, preferences[i], explotation_weights);
alternativesRankings[i] = ConsensusEngine.alternativesRanking(QGDD);
}
Set<Integer> Xsol = ConsensusEngine.solutionSet(alternativesRankings[numberOfExperts]);
Integer[][] differencesBetweenRankings = differencesBetweenRankings(alternativesRankings);
Float[][] consensusDegreesOnAlternativesByExperts = consensusDegreesOnAlternativesByExperts(differencesBetweenRankings, b);
Float[] consensusDegreesOnAlternatives = consensusDegreesOnAlternatives(consensusDegreesOnAlternativesByExperts);
computeConsensusDegree(consensusDegreesOnAlternatives, Xsol);
posSaveRoundResult(preferences, obtainVisualizeValues(), cm, advises, preferences[numberOfExperts]);
}
@Override
protected boolean mustBeCarriedOutAnotherRound() {
return (h < maxcycle) && (cm < cl);
}
@Override
protected void saveExecutionResults() {
this.configuration.setValue(PREFERENCES, preferences);
result.put(EResultElements.number_of_rounds_required, h);
result.put(EResultElements.consensus_degree_achieved, cm);
}
private static Integer[][] differencesBetweenRankings(Integer[][] alternativesRankings) {
Integer[][] result = new Integer[alternativesRankings.length - 1][alternativesRankings[0].length];
Integer[] groupRanking = alternativesRankings[alternativesRankings.length - 1];
Integer[] expertRanking;
for (int i = 0; i < result.length; i++) {
expertRanking = alternativesRankings[i];
result[i] = differencesBetweenRankings(expertRanking, groupRanking);
}
return result;
}
private static Integer[] differencesBetweenRankings(Integer[] eR, Integer[] gR) {
Integer[] result = new Integer[eR.length];
for (int i = 0; i < eR.length; i++) {
result[i] = gR[i] - eR[i];
}
return result;
}
private static Float[][] consensusDegreesOnAlternativesByExperts(Integer[][] differencesBetweenRankings, float b) {
int experts = differencesBetweenRankings.length;
int alternatives = differencesBetweenRankings[0].length;
Float[][] result = new Float[experts][alternatives];
for (int e = 0; e < experts; e++) {
for (int a = 0; a < alternatives; a++) {
result[e][a] = (float) Math.pow((((float) Math.abs(differencesBetweenRankings[e][a])) / ((float) (alternatives - 1))), b);
result[e][a] = Math.round(result[e][a] * 100f) / 100f;
}
}
return result;
}
private static Float[] consensusDegreesOnAlternatives(Float[][] consensusDegreesOnAlternativesByExperts) {
int experts = consensusDegreesOnAlternativesByExperts.length;
int alternatives = consensusDegreesOnAlternativesByExperts[0].length;
Float[] result = new Float[alternatives];
for (int a = 0; a < alternatives; a++) {
result[a] = 0f;
for (int e = 0; e < experts; e++) {
result[a] += (consensusDegreesOnAlternativesByExperts[e][a] / experts);
}
result[a] = 1f - result[a];
}
return result;
}
private static Float consensusMeasure(Float[] consensusMeasures, float beta, Set<Integer> Xsol) {
return s_owa__or_like(consensusMeasures, beta, Xsol);
}
private static Float[] proximityMeasures(Float[][] proximityMeasuresByExperts, float beta, Set<Integer> Xsol) {
int experts = proximityMeasuresByExperts.length;
Float[] result = new Float[experts];
for (int i = 0; i < experts; i++) {
result[i] = proximityMeasure(proximityMeasuresByExperts[i], beta, Xsol);
}
return result;
}
private static Float proximityMeasure(Float[] proximityMeasuresByExpert, float beta, Set<Integer> Xsol) {
Float[] aux = new Float[proximityMeasuresByExpert.length];
for (int i = 0; i < proximityMeasuresByExpert.length; i++) {
aux[i] = 1f - proximityMeasuresByExpert[i];
}
return s_owa__or_like(aux, beta, Xsol);
}
private static Float s_owa__or_like(Float[] values, float beta, Set<Integer> Xsol) {
Float result = 0f;
float value_1 = 0f;
float value_2 = 0f;
int size_1 = Xsol.size();
int size_2 = values.length - size_1;
for (int i = 0; i < values.length; i++) {
if (Xsol.contains(i)) {
value_1 += values[i] / (size_1);
} else {
value_2 += values[i] / (size_2);
}
}
result = ((1f - beta) * value_1) + (beta * value_2);
result = Math.round(result * 100f) / 100f;
return result;
}
private static Set<Integer> selectFarthestExperts(Float[] proximityMeasures) {
Set<Integer> result = new HashSet<>();
List<Float> orderedValues = new ArrayList<>();
for (Float value : proximityMeasures) {
orderedValues.add(Float.valueOf(value));
}
Collections.sort(orderedValues);
float threashold = orderedValues.get(orderedValues.size() / 2);
for (int i = 0; i < proximityMeasures.length; i++) {
if (proximityMeasures[i].floatValue() <= threashold) {
result.add(Integer.valueOf(i));
}
}
return result;
}
private static Map<Integer, EChangeType[]> changesByExperts(Set<Integer> farthestExperts, Integer[][] differencesBetweenRankings) {
Map<Integer, EChangeType[]> result = new HashMap<>();
EChangeType[] changes;
int alternatives = differencesBetweenRankings[0].length;
for (int expert : farthestExperts) {
changes = new EChangeType[alternatives];
for (int alternative = 0; alternative < alternatives; alternative++) {
if (differencesBetweenRankings[expert][alternative] < 0) {
changes[alternative] = EChangeType.Increase;
} else if (differencesBetweenRankings[expert][alternative].intValue() == 0) {
changes[alternative] = EChangeType.NotChange;
} else {
changes[alternative] = EChangeType.Decrease;
}
}
result.put(Integer.valueOf(expert), changes);
}
return result;
}
private void makeChanges(Map<Integer, EChangeType[]> changes, Structure[] preferences) {
int alternatives = ((FPR) preferences[0]).getPreferences().length;
int numberOfChanges = 0;
// Count changes
for (EChangeType[] changesArray : changes.values()) {
for (EChangeType change : changesArray) {
if (EChangeType.NotChange != change) {
numberOfChanges++;
}
}
}
// Get behaviour for changes
double[] changesToMake = getNChanges(numberOfChanges);
// Make changes
EChangeType[] changesArray;
EChangeType change;
numberOfChanges = 0;
float value;
float newValue;
for (Integer expertIndex : changes.keySet()) {
changesArray = changes.get(expertIndex);
for (int i = 0; i < changesArray.length; i++) {
change = changesArray[i];
if (EChangeType.NotChange != change) {
value = (float) changesToMake[numberOfChanges++];
if (value != 0f) {
if (EChangeType.Decrease == change) {
value *= -1f;
}
for (int j = 0; j < alternatives; j++) {
if (i != j) {
newValue = (Float) preferences[expertIndex].getValue(i, j);
newValue += value;
if (newValue > 1f) {
newValue = 1f;
} else if (newValue < 0f) {
newValue = 0f;
}
((FPR) preferences[expertIndex]).setValueSymmetrically(i, j, newValue);
}
}
}
}
}
}
}
}