package afryca.consensusmodel.labella2020ELICIT; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import afryca.cm.CM; import afryca.consensusmodel.ConsensusEngine; import afryca.consensusmodel.ConsensusModel; import afryca.consensusmodel.EChangeType; import afryca.consensusmodel.cluster.ClusterELICITPR; import afryca.consensusmodel.clustering.FuzzyCMeansELICITPR; import afryca.consensusmodel.definition.EResultElements; import afryca.consensusmodel.definition.ERoundResult; import afryca.domain.fuzzyset.FuzzySet; import afryca.domain.fuzzyset.function.types.TrapezoidalFunction; import afryca.elicit.ELICIT; import afryca.elicit.ELICITPR; import afryca.hlpr.HLPR; import afryca.hlpr.valuation.EUnaryRelationType; import afryca.hlpr.valuation.HesitantLinguisticValuation; import afryca.structure.Structure; import afryca.structure.pair.Pair; import afryca.twotuple.TwoTuple; public class Labella2020ELICITLarge_2 extends ConsensusModel { private static final String CONSENSUS_MODEL_NAME = "Labella et al. (2020-ELICIT)"; //$NON-NLS-1$ private static final float CHANGE_DEGREE_TRANSLATION = 0.2f; private static final int CHANGE_DEGREE_LABEL = 3; private static final String MU = "mu"; //$NON-NLS-1$ private static final String DELTA = "delta"; //$NON-NLS-1$ private static final String MAX_ROUNDS = "h_max"; //$NON-NLS-1$ private static final String EPSILON = "epsilon"; //$NON-NLS-1$ private ArrayList proximityMatrices; private Map, Float[][]> similarityMatrices; private ELICITPR[] preferencesWithoutCollective; private Structure[] preferencesAux; private List postClusters; private CM cm; private Float[] consensusAlternatives; private ELICITPR collective; private int[] advises; private int numberOfChanges; private Integer h_max; private Integer round; private Float cr; private Float delta; private Float mu; private Float epsilon; @Override protected void setModelConfiguration() {} @Override protected void obtainConfigurationValues() { mu = (Float) configuration.getValue(MU); delta = (Float) configuration.getValue(DELTA); h_max = (Integer) configuration.getValue(MAX_ROUNDS); epsilon = (Float) configuration.getValue(EPSILON); postClusters = new LinkedList(); preferencesWithoutCollective = new ELICITPR[numberOfExperts]; round = 0; numberOfChanges = 0; advises = null; initializeAdvises(); initializeELICITPreferences(); computePreferencesWithoutCollective(); } /** * Transform initial CLEs into ELICIT information */ private void initializeELICITPreferences() { Structure[] preferencesAux = new Structure[numberOfExperts + 1]; for(int k = 0; k < numberOfExperts; ++k) { HLPR hlpr = (HLPR) preferences[k]; ELICIT[][] elicit_preference = new ELICIT[numberOfAlternatives][numberOfAlternatives]; for(int i = 0; i < numberOfAlternatives; ++i) { for(int j = 0; j < numberOfAlternatives; ++j) { HesitantLinguisticValuation hlv = hlpr.getHesitantLinguisticValuation(i, j); ELICIT elicitValuation = new ELICIT((FuzzySet) hlv.getDomain()); elicitValuation.createRelation(ConsensusEngine.calculateFuzzyEnvelope((FuzzySet) hlv.getDomain(), hlv)); elicit_preference[i][j] = elicitValuation; } } ELICITPR elicitPR = new ELICITPR(numberOfAlternatives); elicitPR.setDomain((FuzzySet) hlpr.getDomain()); elicitPR.setPreferences(elicit_preference); preferencesAux[k] = elicitPR; } Structure collective = preferencesAux[0].groupPreferences(numberOfExperts, numberOfAlternatives, numberOfCriteria, Arrays.copyOfRange(preferencesAux, 0, preferencesAux.length - 1)); this.preferencesAux = clonePreferencesUnion(preferencesAux, collective); } /** * Initialize preferences without collective opinion */ private void computePreferencesWithoutCollective() { // Copy preferences except collective for (int i = 0; i < numberOfExperts; i++) { try { preferencesWithoutCollective[i] = (ELICITPR) preferencesAux[i].clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } /** * Initialize advises array */ private void initializeAdvises() { advises = new int[experts.length]; for (int i = 0; i < advises.length; i++) { advises[i] = 0; } } @Override protected void preFirstSaveRoundResults() { Structure[] auxPreferences = clonePreferencesUnion(preferencesAux, preferencesAux[0].groupPreferences(numberOfExperts, numberOfAlternatives, numberOfCriteria, Arrays.copyOfRange(preferencesAux, 0, preferencesAux.length - 1))); postClusters = generateClusters(alternatives, experts, preferencesWithoutCollective, 1); computeConsensusDegree(); preSaveRoundResult(1, auxPreferences, obtainVisualizeValues(), cr); roundsResults.get(roundsResults.size() - 1).put(ERoundResult.clusters, postClusters); result.put(EResultElements.initial_consensus_degree, cr); result.put(EResultElements.maxround, h_max); result.put(EResultElements.consensus_threshold, mu); result.put(EResultElements.consensus_model, CONSENSUS_MODEL_NAME); } @SuppressWarnings("unchecked") private List generateClusters(String[] alternatives, String[] experts, ELICITPR[] preferences, float parameter) { return (roundsResults.isEmpty() ? FuzzyCMeansELICITPR.doClusteringFuzzyCMeansClusterForEachAlternative(alternatives, experts, preferences, null, parameter) : FuzzyCMeansELICITPR.doClusteringFuzzyCMeansClusterForEachAlternative(alternatives, experts, preferences, (List) roundsResults.get(roundsResults.size() - 1).get(ERoundResult.clusters), parameter)); } private void computeConsensusDegree() { computeSimilarityMatrices(); computeConsensusMatrix(); computeConsensusAlternatives(); computeOverallConsensusDegree(); computeCollective(); } private void computeSimilarityMatrices() { similarityMatrices = new LinkedHashMap<>(); Float similarityValue; for (int i = 0; i < numberOfExperts - 1; ++i) { Float[][] similarityMatrix = new Float[numberOfAlternatives][numberOfAlternatives]; for (int t = i + 1; t < numberOfExperts; ++t) { Pair pairExperts = new Pair(i, t); for (int l = 0; l < numberOfAlternatives - 1; ++l) { for (int k = l + 1; k < numberOfAlternatives; ++k) { ELICIT expert1ELICIT = ((ELICITPR) preferencesAux[i]).getELICITValuation(l, k); ELICIT expert2ELICIT = ((ELICITPR) preferencesAux[t]).getELICITValuation(l, k); similarityValue = computeSimilarity(expert1ELICIT.getBeta(), expert2ELICIT.getBeta()); similarityMatrix[l][k] = similarityValue; similarityMatrix[k][l] = similarityValue; } } similarityMatrices.put(pairExperts, similarityMatrix); } } } private Float computeSimilarity(TrapezoidalFunction trp1, TrapezoidalFunction trp2) { return (float) (1f - trp1.distance(trp2, 1)); } private void computeConsensusMatrix() { List sim = new LinkedList(); cm = new CM(numberOfAlternatives); for (int l = 0; l < numberOfAlternatives; ++l) { for (int k = 0; k < numberOfAlternatives; ++k) { sim.clear(); if(l != k) { for (Pair pairExperts : similarityMatrices.keySet()) sim.add(similarityMatrices.get(pairExperts)[l][k]); cm.setValue(l, k, aggregateSIMValues(sim)); } else { cm.setValue(l, k, 1f); } } } } private Float aggregateSIMValues(List sim) { Float arithmeticMean = 0f; for (Float simValue : sim) arithmeticMean += simValue; return arithmeticMean / sim.size(); } private void computeConsensusAlternatives() { consensusAlternatives = ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, cm); } private void computeOverallConsensusDegree() { cr = Math.round(ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, consensusAlternatives) * 10000f) / 10000f; } private void computeCollective() { collective = (ELICITPR) preferencesAux[0].groupPreferences(numberOfExperts, numberOfAlternatives, numberOfCriteria, Arrays.copyOfRange(preferencesAux, 0, preferencesAux.length - 1)); preferencesAux[preferencesAux.length - 1] = collective; } @Override protected void preSaveRoundResults() { preSaveRoundResult(round + 1, preferencesAux, obtainVisualizeValues(), cr); roundsResults.get(roundsResults.size() - 1).put(ERoundResult.clusters, postClusters); } @Override protected void consensusRound() { advises = null; computeConsensusDegree(); if(cr < mu) { if (cr < delta) groupAdviceGeneration(); else individualAdviceGeneration(); computePreferencesWithoutCollective(); postClusters = generateClusters(alternatives, experts, preferencesWithoutCollective, 1f); round++; } } private void groupAdviceGeneration() { computeProximityMatrices(); computeGroupChanges(); } private void computeProximityMatrices() { proximityMatrices = new ArrayList<>(); Float[][] proximityMatrix; Float proximityValue; for (int i = 0; i < postClusters.size(); ++i) { proximityMatrix = new Float[numberOfAlternatives][numberOfAlternatives]; for (int l = 0; l < numberOfAlternatives - 1; ++l) { for (int k = l + 1; k < numberOfAlternatives; ++k) { ELICIT centroidELICIT = ((ELICIT[][]) postClusters.get(i).getCentroid())[l][k]; ELICIT collectiveELICIT = collective.getELICITValuation(l, k); proximityValue = computeSimilarity(centroidELICIT.getBeta(), collectiveELICIT.getBeta()); proximityMatrix[l][k] = proximityValue; proximityMatrix[k][l] = proximityValue; } } proximityMatrices.add(proximityMatrix); } } private void computeGroupChanges() { Map>> groupsToChange = identifyChangesToDoByGroup(); EChangeType[][][] changesDirection = computeGroupChangesDirection(groupsToChange); makeChanges(changesDirection); computeNumberOfAdvises(changesDirection); } private Map>> identifyChangesToDoByGroup() { Map>> changes = new HashMap<>(); List alternativesToChange = identifyAlternativesToChange(); Float[][] overallProximityMatrix = computeOverallProximityValues(); for(ClusterELICITPR cluster: postClusters) { for(int alt: alternativesToChange) { for(int j = 0 ; j < numberOfAlternatives; ++j) { if(j > alt) { if(proximityMatrices.get(cluster.getId())[alt][j] < overallProximityMatrix[alt][j]) { Pair pair = new Pair(alt, j); if(changes.get(cluster.getId()) == null) { List> pairsAlternatives = new LinkedList<>(); pairsAlternatives.add(pair); changes.put(cluster.getId(), pairsAlternatives); } else { List> pairsAlternatives = changes.get(cluster.getId()); pairsAlternatives.add(pair); } } } } } } return changes; } private List identifyAlternativesToChange() { List alternativesToChange = new LinkedList<>(); for (int l = 0; l < numberOfAlternatives; ++l) { Float consensusAlternative = consensusAlternatives[l]; if (consensusAlternative < mu) alternativesToChange.add(l); } return alternativesToChange; } private Float[][] computeOverallProximityValues() { Float[][] overallProximityMatrix = new Float[numberOfAlternatives][numberOfAlternatives]; Float[][] proximityMatrix; float acum; for(int l = 0; l < numberOfAlternatives; ++l) { for(int j = 0; j < numberOfAlternatives; ++j) { acum = 0; if(l != j) { for(int u = 0; u < postClusters.size(); ++u) { proximityMatrix = proximityMatrices.get(u); acum += proximityMatrix[l][j]; } overallProximityMatrix[l][j] = acum / postClusters.size(); } } } return overallProximityMatrix; } private EChangeType[][][] computeGroupChangesDirection(Map>> groupsToChange) { int a1, a2; Float difference; EChangeType[][][] result = initializeChanges(); for (Integer group : groupsToChange.keySet()) { List> pairAlternativesToChange = groupsToChange.get(group); for(Pair pairAlternatives: pairAlternativesToChange) { a1 = pairAlternatives.getLeft(); a2 = pairAlternatives.getRight(); ELICIT expertELICIT = ((ELICIT[][]) postClusters.get(group).getCentroid())[a1][a2]; ELICIT collectiveELICIT = collective.getELICITValuation(a1, a2); difference = (float) (expertELICIT.getBeta().getSimpleDefuzzifiedValue() - collectiveELICIT.getBeta().getSimpleDefuzzifiedValue()); if (difference < (-epsilon)) { for(Integer exp: postClusters.get(group).getExperts()) { result[exp][a1][a2] = EChangeType.Increase; numberOfChanges++; } } else if (difference > epsilon) { for(Integer exp: postClusters.get(group).getExperts()) { result[exp][a1][a2] = EChangeType.Decrease; numberOfChanges++; } } } } return result; } private EChangeType[][][] initializeChanges() { EChangeType[][][] result = new EChangeType[numberOfExperts][numberOfAlternatives][numberOfAlternatives]; for (int i = 0; i < numberOfExperts; i++) { for (int l = 0; l < numberOfAlternatives; l++) { for (int k = 0; k < numberOfAlternatives; k++) { result[i][l][k] = EChangeType.NotChange; } } } numberOfChanges = 0; return result; } private void makeChanges(EChangeType[][][] changes) { ELICIT value; EChangeType change; double[] changesToMake = getNChanges(numberOfChanges); int currentChange = 0; float ch; for (int i = 0; i < numberOfExperts; i++) { for (int l = 0; l < numberOfAlternatives; l++) { for (int k = 0; k < numberOfAlternatives; k++) { if (l != k) { change = changes[i][l][k]; if (change != EChangeType.NotChange) { ch = (float) changesToMake[currentChange++]; if (ch != 0f) { value = (ELICIT) preferencesAux[i].getValue(l, k); double difference = Math.abs(value.getBeta().centroid() - ((ELICIT) collective.getValue(l, k)).getBeta().centroid()); if (change == EChangeType.Increase) { if(difference >= 1d / ((FuzzySet) preferencesAux[i].getDomain()).getLabelSet().getCardinality()) { value = increaseCaseLabel(value); } else { value = increaseCaseTranslation(value); } } else if (change == EChangeType.Decrease) { if(difference >= 1d / ((FuzzySet) preferencesAux[i].getDomain()).getLabelSet().getCardinality()) { value = decreaseCaseLabel(value); } else { value = decreaseCaseTranslation(value); } } ((ELICITPR) preferencesAux[i]).setValueSymmetrically(l, k, value); } } } } } } } private void computeNumberOfAdvises(EChangeType[][][] changesDirection) { advises = new int[numberOfExperts]; for (int i = 0; i < numberOfExperts; i++) { advises[i] = 0; for (int l = 0; l < numberOfAlternatives; l++) { for (int k = 0; k < numberOfAlternatives; k++) { if (changesDirection[i][l][k] != EChangeType.NotChange) { advises[i] = advises[i] + 1; } } } } } private void individualAdviceGeneration() { computeProximityMatrices(); computeIndividualChanges(); } private void computeIndividualChanges() { Map>> changesToDo = identifyChangesToDoByIndividual(); EChangeType[][][] changesDirection = computeIndividualChangesDirection(changesToDo); makeChanges(changesDirection); computeNumberOfAdvises(changesDirection); } private Map>> identifyChangesToDoByIndividual() { Float similarity; List alternativesToChange = identifyAlternativesToChange(); Float[][] overallProximityMatrix = computeOverallProximityValues(); Map>> expertsToChange = new HashMap<>(); for (ClusterELICITPR cluster: postClusters) { for (Integer exp : cluster.getExperts()) { for (int alt: alternativesToChange) { for(int j = 0; j < numberOfAlternatives; ++j) { if(alt > j) { similarity = computeSimilarity(collective.getELICITValuation(alt, j).getBeta(), ((ELICITPR) preferencesAux[exp]).getELICITValuation(alt, j).getBeta()); if (similarity <= overallProximityMatrix[alt][j]) { if (expertsToChange.get(exp) == null) { List> pairAlternativesToChangeByGroup = new LinkedList<>(); pairAlternativesToChangeByGroup.add(new Pair(alt, j)); expertsToChange.put(exp, pairAlternativesToChangeByGroup); } else { expertsToChange.get(exp).add(new Pair(alt, j)); } } } } } } } return expertsToChange; } private EChangeType[][][] computeIndividualChangesDirection(Map>> expertsToChange) { EChangeType[][][] result = initializeIndividualChanges(); Float difference; for (Integer i: expertsToChange.keySet()) { List> pairAlternativesToChange = expertsToChange.get(i); for (int l = 0; l < numberOfAlternatives; l++) { for (int k = 0; k < numberOfAlternatives; k++) { if(l != k) { Pair pairAlternatives = new Pair(l, k); if (pairAlternativesToChange.contains(pairAlternatives)) { ELICIT expertELICIT = ((ELICITPR) preferencesAux[i]).getELICITValuation(l, k); ELICIT collectiveELICIT = collective.getELICITValuation(l, k); difference = (float) (expertELICIT.getBeta().getSimpleDefuzzifiedValue() - collectiveELICIT.getBeta().getSimpleDefuzzifiedValue()); if (difference < (-epsilon)) { result[i][l][k] = EChangeType.Increase; numberOfChanges++; } else if (difference > epsilon) { result[i][l][k] = EChangeType.Decrease; numberOfChanges++; } else if((-epsilon) <= difference && difference <= epsilon) { result[i][l][k] = EChangeType.NotChange; } } } } } } return result; } private EChangeType[][][] initializeIndividualChanges() { EChangeType[][][] result = new EChangeType[numberOfExperts][numberOfAlternatives][numberOfAlternatives]; for (int i = 0; i < numberOfExperts; i++) { for (int l = 0; l < numberOfAlternatives; l++) { for (int k = 0; k < numberOfAlternatives; k++) { result[i][l][k] = EChangeType.NotChange; } } } numberOfChanges = 0; return result; } private ELICIT increaseCaseTranslation(ELICIT elicit) { FuzzySet domain = elicit.getDomain(); if (elicit.isPrimary()) { TwoTuple label = elicit.getTwoTupleLabel(); label.calculateDelta((label.getAlpha() + CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(label.getLabel())); } else if (elicit.isUnary()) { TwoTuple term = elicit.getTwoTupleTerm(); term.calculateDelta((term.getAlpha() + CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(term.getLabel())); if(elicit.getUnaryRelation().equals(EUnaryRelationType.AtLeast)) { if(domain.getLabelSet().getPos(term.getLabel()) < (domain.getLabelSet().getCardinality() - 1) / 2) elicit.setTwoTupleLabel(term); } else { if(domain.getLabelSet().getPos(term.getLabel()) > (domain.getLabelSet().getCardinality() - 1) / 2) elicit.setTwoTupleLabel(term); } } else { TwoTuple lowerTerm = elicit.getTwoTupleLowerTerm(); TwoTuple upperTerm = elicit.getTwoTupleUpperTerm(); lowerTerm.calculateDelta((lowerTerm.getAlpha() + CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(lowerTerm.getLabel())); if(lowerTerm.compareTo(upperTerm) > 0) elicit.setTwoTupleLabel(lowerTerm); } elicit.createRelation(elicit.calculateFuzzyEnvelope()); return elicit; } private ELICIT decreaseCaseTranslation(ELICIT elicit) { FuzzySet domain = elicit.getDomain(); if (elicit.isPrimary()) { TwoTuple label = elicit.getTwoTupleLabel(); label.calculateDelta((label.getAlpha() - CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(label.getLabel())); } else if (elicit.isUnary()) { TwoTuple term = elicit.getTwoTupleTerm(); term.calculateDelta((term.getAlpha() - CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(term.getLabel())); if(elicit.getUnaryRelation().equals(EUnaryRelationType.AtLeast)) { if(domain.getLabelSet().getPos(term.getLabel()) < (domain.getLabelSet().getCardinality() - 1) / 2) elicit.setTwoTupleLabel(term); } else { if(domain.getLabelSet().getPos(term.getLabel()) > (domain.getLabelSet().getCardinality() - 1) / 2) elicit.setTwoTupleLabel(term); } } else { TwoTuple lowerTerm = elicit.getTwoTupleLowerTerm(); TwoTuple upperTerm = elicit.getTwoTupleUpperTerm(); upperTerm.calculateDelta((upperTerm.getAlpha() - CHANGE_DEGREE_TRANSLATION) + domain.getLabelSet().getPos(upperTerm.getLabel())); if(upperTerm.compareTo(lowerTerm) < 0) elicit.setTwoTupleLabel(upperTerm); } elicit.createRelation(elicit.calculateFuzzyEnvelope()); return elicit; } private ELICIT increaseCaseLabel(ELICIT elicit) { FuzzySet fuzzySet = (FuzzySet) elicit.getDomain(); if (elicit.isPrimary()) { int posLabel = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleLabel().getLabel()); if(posLabel + CHANGE_DEGREE_LABEL < fuzzySet.getLabelSet().getCardinality() - 1) { TwoTuple label = elicit.getTwoTupleLabel(); label.setLabel(posLabel + CHANGE_DEGREE_LABEL);//Keep the symbolic translation } } else if (elicit.isUnary()) { int posTerm = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleTerm().getLabel()), cardinality = fuzzySet.getLabelSet().getCardinality(); if(posTerm + CHANGE_DEGREE_LABEL < fuzzySet.getLabelSet().getCardinality() - 1) {//Is it possible the change? if((elicit.getUnaryRelation().equals(EUnaryRelationType.AtMost) || elicit.getUnaryRelation().equals(EUnaryRelationType.LowerThan)) && (posTerm + CHANGE_DEGREE_LABEL > (cardinality + 1) / 2)) {//Too many labels in the unary expression elicit.setTwoTupleLabel(posTerm + CHANGE_DEGREE_LABEL);//Restart symbolic translation } else if((posTerm + CHANGE_DEGREE_LABEL == cardinality - 1) && (elicit.getUnaryRelation().equals(EUnaryRelationType.GreaterThan))) elicit.setTwoTupleLabel(cardinality - 1); else { TwoTuple term = elicit.getTwoTupleTerm(); term.setLabel(posTerm + CHANGE_DEGREE_LABEL);//Keep the symbolic translation } } } else { int posTerm1 = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleLowerTerm().getLabel()); int posTerm2 = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleUpperTerm().getLabel()); if (posTerm1 + CHANGE_DEGREE_LABEL == posTerm2) elicit.setTwoTupleLabel(posTerm2); else if (posTerm1 + CHANGE_DEGREE_LABEL < posTerm2) { TwoTuple lowerTerm = elicit.getTwoTupleLowerTerm(); lowerTerm.setLabel(posTerm1 + CHANGE_DEGREE_LABEL); } } elicit.createRelation(elicit.calculateFuzzyEnvelope()); return elicit; } private ELICIT decreaseCaseLabel(ELICIT elicit) { FuzzySet fuzzySet = (FuzzySet) elicit.getDomain(); if (elicit.isPrimary()) { int posLabel = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleLabel().getLabel()); if(posLabel - CHANGE_DEGREE_LABEL >= 0) { TwoTuple label = elicit.getTwoTupleLabel(); label.setLabel(posLabel - CHANGE_DEGREE_LABEL);//Keep the symbolic translation } } else if (elicit.isUnary()) { int posTerm = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleTerm().getLabel()), cardinality = fuzzySet.getLabelSet().getCardinality(); if(posTerm - CHANGE_DEGREE_LABEL >= 0) { if((elicit.getUnaryRelation().equals(EUnaryRelationType.AtLeast) || elicit.getUnaryRelation().equals(EUnaryRelationType.GreaterThan)) && (posTerm - CHANGE_DEGREE_LABEL < (cardinality - 1) / 2)) {//To many labels in the unary expression elicit.setTwoTupleLabel(posTerm - CHANGE_DEGREE_LABEL);//Restart symbolic translation } else if((posTerm - CHANGE_DEGREE_LABEL == 0) && (elicit.getUnaryRelation().equals(EUnaryRelationType.LowerThan))) { elicit.setTwoTupleLabel(0);//Restart symbolic translation } else { TwoTuple term = elicit.getTwoTupleTerm(); term.setLabel(posTerm - CHANGE_DEGREE_LABEL);//Keep the symbolic translation } } } else { int posTerm1 = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleLowerTerm().getLabel()); int posTerm2 = fuzzySet.getLabelSet().getPos(elicit.getTwoTupleUpperTerm().getLabel()); if (posTerm2 - CHANGE_DEGREE_LABEL == posTerm1) elicit.setTwoTupleLabel(posTerm1);//Restart symbolic translation else if(posTerm2 - CHANGE_DEGREE_LABEL > posTerm1) { TwoTuple upperTerm = elicit.getTwoTupleUpperTerm(); upperTerm.setLabel(posTerm2 - CHANGE_DEGREE_LABEL); } } elicit.createRelation(elicit.calculateFuzzyEnvelope()); return elicit; } @Override protected void posSaveRoundResults() { computeConsensusDegree(); posSaveRoundResult(preferencesAux, obtainVisualizeValues(), cr, advises, preferencesAux[preferencesAux.length - 1]); } @Override protected boolean mustBeCarriedOutAnotherRound() { return (cr < mu) && (round < h_max); } @Override protected Float[][][] obtainVisualizeValues() { Structure[] auxPreferences = clonePreferencesUnion(preferencesAux, preferencesAux[0].groupPreferences(numberOfExperts, numberOfAlternatives, numberOfCriteria, Arrays.copyOfRange(preferencesAux, 0, preferencesAux.length - 1))); Float[][][] preferencesGroupVisualization = new Float[numberOfExperts + 1][numberOfAlternatives][numberOfAlternatives]; for (int i = 0; i < numberOfExperts + 1; i++) preferencesGroupVisualization[i] = auxPreferences[i].obtainVisualizeValues(); return preferencesGroupVisualization; } @Override protected void saveExecutionResults() { this.configuration.setValue(PREFERENCES, preferencesAux); result.put(EResultElements.number_of_rounds_required, round); result.put(EResultElements.consensus_degree_achieved, cr); } }