package afryca.hlpr; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.preferences.InstanceScope; import afryca.ase.RunnableScript; import afryca.domain.Domain; import afryca.domain.fuzzyset.FuzzySet; import afryca.domain.fuzzyset.function.types.TrapezoidalFunction; import afryca.domain.fuzzyset.labelset.Label; import afryca.hlpr.command.GenerateRandomHLPR; import afryca.hlpr.preferences.PreferenceConstants; import afryca.hlpr.ranking.NonDominanceRanking; import afryca.hlpr.valuation.HesitantLinguisticValuation; import afryca.pr.PR; import afryca.structure.Structure; import afryca.hlpr.addon.E4DIAddon; import afryca.structure.ranking.AbstractDominanceRanking; import afryca.twotuple.TwoTuple; public class HLPR extends PR { public static final String ID = "afryca.hlpr"; public final static HesitantLinguisticValuation MISSING_VALUE = new HesitantLinguisticValuation(); public final static HesitantLinguisticValuation INDIFFERENCE_VALUE = new HesitantLinguisticValuation(); private FuzzySet fuzzySet; /** * Build a empty HPR */ public HLPR() { prepareStructureForNAlternatives(0); } /** * Build a HPR for numberOfAlternatives * * @param numberOfAlternatives * Number of alternatives * * @throws IllegalArgumentException * if numberOfAlternatives is negative */ public HLPR(int numberOfAlternatives) { this.numberOfAlternatives = numberOfAlternatives; prepareStructureForNAlternatives(numberOfAlternatives); setIndifferenceAtDiagonal(); } @Override public void preparePreferencesStructure() { preferences = new Object[numberOfAlternatives][numberOfAlternatives]; for (int i = 0; i < numberOfAlternatives; i++) { for (int j = 0; j < numberOfAlternatives; j++) { preferences[i][j] = MISSING_VALUE; } } } @Override public void setIndifferenceAtDiagonal() { setIndifferenceDiagonal(null); } private void setIndifferenceDiagonal(Domain domain){ for (int i = 0; i < numberOfAlternatives; i++) { if(domain!=null){ HesitantLinguisticValuation diagonal=new HesitantLinguisticValuation((FuzzySet) domain); diagonal.setLabel(((FuzzySet)domain).getLabelSet().getCardinality()/2); preferences[i][i] = diagonal; }else{ preferences[i][i] = INDIFFERENCE_VALUE; } } } @Override public void setDomain(Object...fuzzySet) { updatePreferences((FuzzySet) fuzzySet[2]); this.fuzzySet = (FuzzySet) fuzzySet[2]; changes.firePropertyChange(FIELD_PREFERENCES, null, preferences); } public void setDomain(FuzzySet fuzzySet) { updatePreferences(fuzzySet); this.fuzzySet = fuzzySet; changes.firePropertyChange(FIELD_PREFERENCES, null, preferences); } private void updatePreferences(FuzzySet domain) { if(domain != null) { if(this.fuzzySet != domain) { prepareStructureForNAlternatives(numberOfAlternatives); setIndifferenceDiagonal(domain); } }else{ prepareStructureForNAlternatives(numberOfAlternatives); } } @Override public Object getDomain(Object...indexes) { return fuzzySet; } @Override public boolean isValidForPreferences(Object value) { if (value == null) { return false; } return ((HesitantLinguisticValuation) value).equals(MISSING_VALUE) || checkHesitantValuation((HesitantLinguisticValuation) value); } private boolean checkHesitantValuation(HesitantLinguisticValuation value) { if(fuzzySet == null || value == null) { return true; } else { if(value.isUnary()) { Label term = value.getTerm(); return fuzzySet.getLabelSet().containsLabel(term); } else if(value.isBinary()) { Label lowerTerm = value.getLowerTerm(); Label upperTerm = value.getUpperTerm(); return fuzzySet.getLabelSet().containsLabel(lowerTerm) && fuzzySet.getLabelSet().containsLabel(upperTerm); } else if(value.isPrimary()) { Label label = value.getLabel(); return fuzzySet.getLabelSet().containsLabel(label); } } return false; } @Override public void setValueSymmetrically(int i, int j, Object value) { notInvalidPairOfAlternatives(i, j); setValueToSymmetricallyPairOfAlternatives(i, j, value); } private void setValueToSymmetricallyPairOfAlternatives(int i, int j, Object value) { checkHesitantValuation((HesitantLinguisticValuation) value); if (i != j) { preferences[i][j] = value; preferences[j][i] = ((HesitantLinguisticValuation) value).getReciprocalHesitantValues(); changes.firePropertyChange(FIELD_PREFERENCES, null, preferences); } } public void setValueToPairOfAlternatives(int i, int j, Object value) { checkHesitantValuation((HesitantLinguisticValuation) value); if (i != j) { preferences[i][j] = value; changes.firePropertyChange(FIELD_PREFERENCES, null, preferences); } } /** * Initialize FPR with missing values */ @Override public void initialize() {; for (int row = 0; row < numberOfAlternatives; row++) { for (int col = 0; col < numberOfAlternatives; col++) { preferences[row][col] = (row == col) ? INDIFFERENCE_VALUE : MISSING_VALUE; } } changes.firePropertyChange(FIELD_PREFERENCES, null, preferences); } @Override public Object createDefaultStructure(Object...numberOfAlternatives) { return new HLPR((int) numberOfAlternatives[0]); } @Override public Object clone() throws CloneNotSupportedException { HLPR result = new HLPR(); result.preferences = clonePreferences(); if(fuzzySet == null) { result.fuzzySet = null; } else { result.fuzzySet = (FuzzySet) fuzzySet.clone(); } result.numberOfAlternatives = numberOfAlternatives; return result; } private Object[][] clonePreferences() { Object[][] result = new Object[preferences.length][]; for (int i = 0; i < preferences.length; i++) { result[i] = clonePreferencesRow(i); } return result; } private Object[] clonePreferencesRow(int row) { Object[] result = new Object[preferences[row].length]; for (int i = 0; i < preferences[row].length; i++) { if(preferences[row][i] == null){ result[i]=null; }else{ if(preferences[row][i] instanceof HesitantLinguisticValuation){ result[i] = (HesitantLinguisticValuation) ((HesitantLinguisticValuation) preferences[row][i]).clone(); }else if(preferences[row][i] instanceof TwoTuple){ result[i] = (TwoTuple) ((TwoTuple) preferences[row][i]).clone(); } } } return result; } @Override public Object getValue(Object... indexes) { int i, j; i = (Integer) indexes[0]; j = (Integer) indexes[1]; notInvalidPairOfAlternatives(i, j); return preferences[i][j]; } public String getHesitantValuationName(int i, int j) { notInvalidPairOfAlternatives(i, j); return preferences[i][j].toString(); } public HesitantLinguisticValuation getHesitantLinguisticValuation(int i, int j) { notInvalidPairOfAlternatives(i, j); return (HesitantLinguisticValuation) preferences[i][j]; } @Override public Structure parseStructure(String readablePreference, String readableDomains, List domains) { HLPRParser textForGenerateHPR = HLPRParser.discover(readablePreference); return textForGenerateHPR.parse(readablePreference, readableDomains, domains, this); } /** * Group preferences * * @param experts * Number of experts * @param alternatives * Number of alternatives * @param preferences * All HPR * @return Group HPR */ @Override public Structure groupPreferences(int numberOfExperts, int numberOfAlternatives, int numberOfCriteria, Structure[] preferences) { String function = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.AGGREGATE_HLPR_FUNCTION_KEY, null); boolean missing=false; for (int i = 0; i < preferences.length; i++) { try { missing=(boolean) E4DIAddon.aseService .createFragmentBuilder() .putVariable("collective", preferences[i]) //$NON-NLS-1$ .putVariable("row", ((Object[][]) preferences[i].getPreferences()).length) .putVariable("col", ((Object[][]) preferences[i].getPreferences())[0].length) .setCode("consistency.containsMissingValues(collective, row, col)") //$NON-NLS-1$ .setOutputType(Boolean.class.getName()) .eval() .getResult(); } catch (Exception e) {} if(missing) return new HLPR(numberOfAlternatives); } FuzzySet blts = (FuzzySet) E4DIAddon.aseService .createFragmentBuilder() .putVariable("preferences", preferences) //$NON-NLS-1$ .setCode("unification.getBLTS(preferences)") //$NON-NLS-1$ .setOutputType(FuzzySet.class.getName()) .eval() .getResult(); Object[][] collective = (Object[][]) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder() .setFunction(function) .putVariable("preferences", preferences) .putVariable("alternatives", numberOfAlternatives) .putVariable("criteria", numberOfCriteria) .putVariable("experts", numberOfExperts) .execute()) .getResult(); if ((collective != null)) { HLPR result = new HLPR(numberOfAlternatives); result.setDomain(0,0,blts); result.setPreferences(collective); return result; } return new HLPR(numberOfAlternatives); } /** * Generate random HPR * * @param n * Number of alternatives */ @Override public Structure random(int n) { HLPR hlprRandom = new HLPR(n); hlprRandom.setDomain(null, null, this.fuzzySet); hlprRandom.setNumberOfAlternatives(n); for (int i = 0; i < n-1; i++) { for (int j = (i+1); j < n; j++) { HesitantLinguisticValuation hesitant = ((HesitantLinguisticValuation) preferences[i][j]).generateHesitantValuationRandom(fuzzySet); hlprRandom.setValueSymmetrically(i, j, hesitant); } } return hlprRandom; } @Override public AbstractDominanceRanking createRanking() { return new NonDominanceRanking(this); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + numberOfAlternatives; result = prime * result + Arrays.deepHashCode(preferences); result = prime * result + ((fuzzySet == null) ? 0 : fuzzySet.hashCode()); return result; } @Override public String[] getRandomKeys() { String [] result=new String[2]; result[0] = GenerateRandomHLPR.NUMBER_OF_ALTERNATIVES; result[1] = GenerateRandomHLPR.ID; return result; } @Override public String [] getPreferencesKeys() { String [] result=new String[2]; result[0]=PreferenceConstants.CHART_FUNCTION_KEY; result[1]=PreferenceConstants.MODULE_BINDINGS_KEY; return result; } @Override public boolean hasDomain() { return true; } @SuppressWarnings("unchecked") @Override public Float[][] obtainVisualizeValues() { Float[][] result = new Float[numberOfAlternatives][numberOfAlternatives]; if(preferences[0][0] instanceof TrapezoidalFunction) {//Preferences represented by fuzzy numbers for (int i = 0; i < preferences.length; i++) { for (int j = 0; j < preferences[i].length; j++) result[i][j] = ((Double) ((TrapezoidalFunction) preferences[i][j]).centroid()).floatValue(); } } else {//Preferences represented by CLEs List preferencesDM = new ArrayList(); preferencesDM.add(this); ArrayList unifiedValuations = (ArrayList) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder() .setFunction("Unification") .putVariable("preferences", preferencesDM) .putVariable("blts", getDomain(null,null)) .execute()) .getResult(); ArrayList twoTuplePreferencesDM = (ArrayList) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder() .setFunction("Disunification") .putVariable("preferences", unifiedValuations) .execute()) .getResult(); for (int i = 0; i < preferences.length; i++) { for (int j = 0; j < preferences[i].length; j++) result[i][j] = (float)((TwoTuple)(twoTuplePreferencesDM.get(0).getValue(i,j))).calculateInverseDelta(); } } return result; } @Override public Object getIndifferenceValue() { return INDIFFERENCE_VALUE; } }