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,494 @@
package afryca.decisionmatrix;
import java.beans.PropertyChangeListener;
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.decisionmatrix.addon.E4DIAddon;
import afryca.decisionmatrix.command.GenerateRandomDecisionMatrix;
import afryca.decisionmatrix.ranking.ArithmeticMeanRanking;
import afryca.domain.Domain;
import afryca.domain.fuzzyset.FuzzySet;
import afryca.decisionmatrix.preferences.PreferenceConstants;
import afryca.hlpr.valuation.HesitantLinguisticValuation;
import afryca.structure.Structure;
import afryca.structure.ranking.AbstractDominanceRanking;
import afryca.twotuple.TwoTuple;
import afryca.valueforcer.ValueForcer;
public class DecisionMatrix extends Structure {
public static final String ID = "afryca.decisionmatrix";
public final static String FIELD_PREFERENCES = "preferences"; //$NON-NLS-1$
public final static char ROWS_SEPARATOR = ':';
public final static char COLS_SEPARATOR = ',';
private Object[][] preferences;
private Object[][] domains;
private int numberOfAlternatives;
private int numberOfCriteria;
public DecisionMatrix() {
prepareStructure(0, 0);
}
public DecisionMatrix(int numberCriteria, int numberAlternatives) {
prepareStructure(numberCriteria, numberAlternatives);
}
public void prepareStructure(int numberOfCriteria, int numberOfAlternatives) {
ValueForcer.notNegative(numberOfCriteria);
ValueForcer.notNegative(numberOfAlternatives);
this.numberOfCriteria = numberOfCriteria;
this.numberOfAlternatives = numberOfAlternatives;
preparePreferencesStructure();
}
private void preparePreferencesStructure() {
preferences = new Object[numberOfCriteria][numberOfAlternatives];
domains = new Object[numberOfCriteria][numberOfAlternatives];
for (int i = 0; i < numberOfCriteria; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
preferences[i][j] = null;
domains[i][j] = null;
}
}
}
@Override
public int getNumberOfAlternatives() {
return numberOfAlternatives;
}
public int getNumberOfCriteria() {
return numberOfCriteria;
}
@Override
public Object getPreferences() {
return preferences;
}
@Override
public Object getPreferenceSize() {
int[] size = new int[2];
size[0] = numberOfCriteria;
size[1] = numberOfAlternatives;
return size;
}
@Override
public Object getDomain(Object...domain) {
if(((Object[]) domain).length == 0) {
return domains;
}
int indexOfCriterion = 0, indexOfAlternative = 0;
indexOfCriterion = (Integer) domain[0];
indexOfAlternative = (Integer) domain[1];
return domains[indexOfCriterion][indexOfAlternative];
}
@Override
public Object getValue(Object... indexes) {
int i, j;
i = (Integer) indexes[0];
j = (Integer) indexes[1];
notInvalidPair(i, j);
return preferences[i][j];
}
@Override
public Float[][] obtainVisualizeValues() {
Float[][] pref = new Float[numberOfCriteria][numberOfAlternatives];
for (int i = 0; i < numberOfCriteria; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
if(preferences[i][j] instanceof TwoTuple)
pref[i][j] = ((TwoTuple) preferences[i][j]).calculateInverseDelta();
else if(preferences[i][j] instanceof HesitantLinguisticValuation)
return computeVisualizeValuesHesitant();
else if(preferences[i][j] instanceof Float)
pref[i][j] = (float) preferences[i][j];
else
pref[i][j] = ((Double) preferences[i][j]).floatValue();
}
}
return pref;
}
@SuppressWarnings("unchecked")
private Float[][] computeVisualizeValuesHesitant(){
List<Structure> preferencesDM = new ArrayList<Structure>();
preferencesDM.add(this);
ArrayList<Structure> unifiedValuations = (ArrayList<Structure>) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder()
.setFunction("Unification")
.putVariable("preferences", preferencesDM)
.putVariable("blts", getDomain(null,null))
.execute())
.getResult();
ArrayList<Structure> twoTuplePreferencesDM = (ArrayList<Structure>) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder()
.setFunction("Disunification")
.putVariable("preferences", unifiedValuations)
.execute())
.getResult();
Float[][] result=new Float[numberOfAlternatives][numberOfAlternatives];
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;
}
public void setValue(int numberCriterion, int numberAlternative, Object value) {
notInvalidPair(numberCriterion, numberAlternative);
preferences[numberCriterion][numberAlternative] = value;
changes.firePropertyChange(FIELD_PREFERENCES, null, preferences);
}
@Override
public void initialize() {
for (int row = 0; row < numberOfCriteria; row++) {
for (int col = 0; col < numberOfAlternatives; col++) {
preferences[row][col] = null;
}
}
changes.firePropertyChange(FIELD_PREFERENCES, null, preferences);
}
private void notInvalidPair(int i, int j) {
ValueForcer.notOutOfRange(i, 0, numberOfCriteria - 1);
ValueForcer.notOutOfRange(j, 0, numberOfAlternatives - 1);
}
@Override
public void setDomain(Object... domain) {
int indexOfCriterion = (int) domain[0];
int indexOfAlternative = (int) domain[1];
updatePreferences(indexOfCriterion, indexOfAlternative, (Domain) domain[2]);
domains[indexOfCriterion][indexOfAlternative] = domain[2];
changes.firePropertyChange(FIELD_PREFERENCES, null, preferences);
}
private void updatePreferences(int indexCriterion, int indexAlternative, Domain domain) {
if(domains[indexCriterion][indexAlternative] != null) {
if(domains[indexCriterion][indexAlternative] != domain) {
preferences[indexCriterion][indexAlternative] = null;
}
}
}
@Override
public void removeAlternativePreferences(int index) {
if ((index >= 0) && (index < numberOfAlternatives)) {
int newNumberOfAlternatives = numberOfAlternatives - 1;
Object[][] newPreferences = new Object[1][newNumberOfAlternatives];
int newColumn = 0;
for (int row = 0; row < numberOfCriteria; row++) {
newColumn = 0;
for (int column = 0; column < numberOfAlternatives; column++) {
if (index != column) {
newPreferences[row][newColumn] = preferences[row][column];
newColumn++;
}
}
}
numberOfAlternatives = newNumberOfAlternatives;
changes.firePropertyChange(FIELD_PREFERENCES, preferences, preferences = newPreferences);
}
}
@Override
public void backwardAlternativePreferences(int index) {
if (index >= 1) {
backwardColumn(index);
changes.firePropertyChange(FIELD_PREFERENCES, null, preferences);
}
}
private void backwardColumn(int index) {
Object aux;
for (int i = 0; i < numberOfAlternatives; i++) {
aux = preferences[i][index];
preferences[i][index] = preferences[i][index - 1];
preferences[i][index - 1] = aux;
}
}
@Override
public void forwardAlternativePreferences(int index) {
if (index < (numberOfAlternatives - 1)) {
backwardAlternativePreferences(index + 1);
}
}
/**
* Set preferences
*
* @param preferences
* Square matrix of float values between zero and one
* @throws NullPointerException
* if preferences is null
* @throws IllegalArgumentException
* if not is valid matrix preferences
*/
public void prepareStructureForPreferences(Object[][] preferences) {
ValueForcer.notNull(preferences);
numberOfAlternatives = preferences[0].length;
numberOfCriteria = preferences.length;
changes.firePropertyChange(FIELD_PREFERENCES, this.preferences, this.preferences = preferences);
}
@Override
public Structure groupPreferences(int numberOfExperts, int numberOfAlternatives, int numberOfCriteria, Structure[] preferences) {
String function = InstanceScope.INSTANCE.getNode(PreferenceConstants.NODEPATH).get(PreferenceConstants.AGGREGATE_DECISION_MATRIX_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 DecisionMatrix(numberOfCriteria, numberOfAlternatives);
}
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)) {
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();
DecisionMatrix result = new DecisionMatrix(numberOfCriteria,numberOfAlternatives);
for (int i = 0; i < numberOfCriteria; i++) {
for (int j = 0; j < numberOfAlternatives; j++)
result.setDomain(i,j,blts);
}
result.prepareStructureForPreferences(collective);
return result;
}
return new DecisionMatrix(numberOfCriteria, numberOfAlternatives);
}
@Override
public Structure parseStructure(String readablePreference, String readableDomains, List<Domain> domains) {
DecisionMatrixParser textForGenerateDecisionMatrix = DecisionMatrixParser.discover(readablePreference);
return textForGenerateDecisionMatrix.parse(readablePreference, readableDomains, domains, this);
}
@Override
public Object createDefaultStructure(Object...info) {
return new DecisionMatrix((int) info[1], (int) info[0]);
}
/**
* Add property change listener
*
* @param listener
* Property change listener
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
changes.addPropertyChangeListener(listener);
}
/**
* Remove property change listener
*
* @param listener
* Property change listener
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
changes.removePropertyChangeListener(listener);
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < preferences.length; i++) {
result.append(rowToString(i));
if (i < (preferences.length - 1)) {
result.append(ROWS_SEPARATOR);
}
}
return result.toString();
}
private StringBuilder rowToString(int row) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < preferences[row].length; i++) {
result.append(preferences[row][i]);
if (i < (preferences[row].length - 1)) {
result.append(COLS_SEPARATOR);
}
}
return result;
}
public String prettyFormat() {
StringBuilder result = new StringBuilder();
for(int i = 0; i < numberOfCriteria; ++i) {
for(int j = 0; j < numberOfAlternatives; ++j) {
result.append(preferences[i][j] + "\t" + "|");
}
result.append("\n");
}
return result.toString();
}
@Override
public Object clone() throws CloneNotSupportedException {
DecisionMatrix result = new DecisionMatrix();
result.preferences = clonePreferences();
result.domains = cloneDomains();
result.numberOfAlternatives = numberOfAlternatives;
result.numberOfCriteria = numberOfCriteria;
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 Number) {
result[i] = preferences[row][i];
} else if(preferences[row][i] instanceof HesitantLinguisticValuation) {
result[i] = ((HesitantLinguisticValuation) preferences[row][i]).clone();
} else if(preferences[row][i] instanceof TwoTuple) {
result[i] = ((TwoTuple) preferences[row][i]).clone();
}
}
}
return result;
}
private Object[][] cloneDomains() {
Object[][] result = new Object[domains.length][];
for (int i = 0; i < domains.length; i++) {
result[i] = cloneDomainsRow(i);
}
return result;
}
private Object[] cloneDomainsRow(int row) {
Object[] result = new Object[domains[row].length];
for (int i = 0; i < domains[row].length; i++) {
if(domains[row][i] == null) {
result[i] = null;
} else {
result[i] = ((Domain) domains[row][i]).clone();
}
}
return result;
}
@Override
public AbstractDominanceRanking createRanking() {
return new ArithmeticMeanRanking(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + numberOfAlternatives;
result = prime * result + numberOfCriteria;
result = prime * result + Arrays.deepHashCode(domains);
result = prime * result + Arrays.deepHashCode(preferences);
return result;
}
@Override
public String[] getRandomKeys() {
String [] result=new String[2];
result[0]=GenerateRandomDecisionMatrix.NUMBER_OF_ALTERNATIVES;
result[1]=GenerateRandomDecisionMatrix.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 Structure random(int n) {
DecisionMatrix dmRandom = new DecisionMatrix(numberOfCriteria, numberOfAlternatives);
for (int i = 0; i < numberOfCriteria; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
dmRandom.setDomain(i, j, domains[i][j]);
if(domains[i][j] instanceof FuzzySet){
preferences[i][j]=new HesitantLinguisticValuation((FuzzySet) domains[i][j]);
dmRandom.setValue(i, j,((HesitantLinguisticValuation) preferences[i][j]).generateHesitantValuationRandom((FuzzySet) domains[i][j]));
}else {
dmRandom.setValue(i, j, ((Domain) domains[i][j]).createDataRandom());
}
}
}
return dmRandom;
}
@Override
public boolean hasDomain() {
return true;
}
}
@@ -0,0 +1,217 @@
package afryca.decisionmatrix;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import afryca.domain.Domain;
import afryca.domain.fuzzyset.FuzzySet;
import afryca.domain.fuzzyset.labelset.Label;
import afryca.domain.integer.NumericIntegerDomain;
import afryca.domain.real.NumericRealDomain;
import afryca.hlpr.valuation.EBinaryRelationType;
import afryca.hlpr.valuation.EUnaryRelationType;
import afryca.hlpr.valuation.HesitantLinguisticValuation;
/**
* Decision matrix parser
*
* @author Sinbad²
* @version 3.0
*/
enum DecisionMatrixParser {
empty {
@Override
DecisionMatrix parse(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm) {
return dm;
}
},
generateDecisionMatrixInstruction {
@Override
DecisionMatrix parse(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm) {
return buildDecisionMatrixUsingDecisionMatrixInstruction(readablePreference, readableDomains, domains, dm);
}
},
toStringValue {
@Override
DecisionMatrix parse(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm) {
return buildDecisionMatrixUsingToStringValue(readablePreference, readableDomains, domains, dm);
}
};
final static String INTEGER_NUMBER_REGEX = "\\d+"; //$NON-NLS-1$
final static String FLOAT_NUMBER_REGEX = "(^0\\.\\d+$|^0$|^1$|^1\\.0+$|NaN)"; //$NON-NLS-1$
final static String NULL = "null"; //$NON-NLS-1$
final static String SEPARATOR = "separator";
abstract DecisionMatrix parse(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm);
static DecisionMatrixParser discover(String value) {
DecisionMatrixParser result = null;
if (value.isEmpty()) {
result = empty;
} else {
result = toStringValue;
}
return result;
}
static DecisionMatrix buildDecisionMatrixUsingDecisionMatrixInstruction(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm) {
dm.prepareStructure(extractRowsFromToStringValue(readablePreference).length, extractColsFromToStringValue(readablePreference).length);
extractDomains(dm, readableDomains, domains);
Object[][] preferences = extractPreferencesFromToStringValue(readablePreference, dm);
dm.prepareStructureForPreferences(preferences);
return generateRandomDecisionMatrix(dm);
}
static int extractNumberOfAlternativesFromDecisionMatrixInstruction(String value) {
Matcher matcher = generateDecisionMatrixInstructionMatcher(value);
return obtainIntegerMatcherNextValue(matcher);
}
static Matcher generateDecisionMatrixInstructionMatcher(String value) {
Pattern pattern = Pattern.compile(INTEGER_NUMBER_REGEX);
return pattern.matcher(value);
}
static Integer obtainIntegerMatcherNextValue(Matcher matcher) {
matcher.find();
return Integer.parseInt(matcher.group());
}
static DecisionMatrix generateRandomDecisionMatrix(DecisionMatrix dm) {
return (DecisionMatrix) dm.random(dm.getNumberOfAlternatives());
}
static DecisionMatrix buildDecisionMatrixUsingToStringValue(String readablePreference, String readableDomains, List<Domain> domains, DecisionMatrix dm) {
dm.prepareStructure(extractRowsFromToStringValue(readablePreference).length, extractColsFromToStringValue(readablePreference).length);
extractDomains(dm, readableDomains, domains);
Object[][] preferences = extractPreferencesFromToStringValue(readablePreference, dm);
dm.prepareStructureForPreferences(preferences);
return dm;
}
static void extractDomains(DecisionMatrix dm, String readableDomains, List<Domain> domains) {
int cont;
if(!readableDomains.isEmpty()) {
cont = 0;
String d[] = readableDomains.split(SEPARATOR);
for(int c = 0; c < 1; ++c) {
for(int a = 0; a < dm.getNumberOfAlternatives(); ++a) {
dm.setDomain(c, a, searchDomain(d[cont++], domains));
}
}
}
}
private static Domain searchDomain(String domainName, List<Domain> domains) {
for(Domain domain: domains) {
if(domain.getId().equals(domainName)) {
return domain;
}
}
return null;
}
static Object[][] extractPreferencesFromToStringValue(String value, DecisionMatrix dm) {
String[][] matrix = extractStringValues(value);
Object[][] preferences = new Object[matrix.length][];
for (int i = 0; i < matrix.length; i++) {
preferences[i] = parseRowOfPreferences(matrix[i], dm);
}
return preferences;
}
static String[][] extractStringValues(String value) {
String[] rows = extractRowsFromToStringValue(value);
return extractValuesFromRows(rows);
}
static String[] extractRowsFromToStringValue(String value) {
return value.split(String.valueOf(DecisionMatrix.ROWS_SEPARATOR));
}
static String[] extractColsFromToStringValue(String value) {
String[] split = value.split(String.valueOf(DecisionMatrix.ROWS_SEPARATOR));
return split[0].split(String.valueOf(DecisionMatrix.COLS_SEPARATOR));
}
static String[][] extractValuesFromRows(String[] rows) {
String[][] result = new String[rows.length][];
for (int i = 0; i < rows.length; i++) {
result[i] = rows[i].split(String.valueOf(DecisionMatrix.COLS_SEPARATOR));
}
return result;
}
static Object[] parseRowOfPreferences(String[] values, DecisionMatrix dm) {
Object[] result = new Object[values.length];
Domain domain;
for (int i = 0; i < values.length; i++) {
domain = (Domain) dm.getDomain(0, i);
if(domain instanceof NumericIntegerDomain) {
try {
result[i] = Integer.parseInt(values[i]);
} catch(NumberFormatException e) {
result[i] = 0;
}
} else if(domain instanceof NumericRealDomain) {
try {
result[i] = Float.parseFloat(values[i]);
} catch(NumberFormatException e) {
result[i] = Float.NaN;
}
} else if(domain instanceof FuzzySet) {
HesitantLinguisticValuation hesitant = new HesitantLinguisticValuation((FuzzySet) domain);
Label term, lowerTerm, upperTerm;
String termString;
String[] relation=values[i].split(HesitantLinguisticValuation.SEPARATOR);
if(relation[0].equals(EUnaryRelationType.AtLeast.name())) {
termString = relation[1];
term = ((FuzzySet) domain).getLabelSet().getLabel(termString);
hesitant.setUnaryRelation(EUnaryRelationType.AtLeast, term);
} else if(relation[0].equals(EUnaryRelationType.AtMost.name())) {
termString = relation[1];
term = ((FuzzySet) domain).getLabelSet().getLabel(termString);
hesitant.setUnaryRelation(EUnaryRelationType.AtMost, term);
} else if(relation[0].equals(EUnaryRelationType.LowerThan.name())) {
termString = relation[1];
term = ((FuzzySet) domain).getLabelSet().getLabel(termString);
hesitant.setUnaryRelation(EUnaryRelationType.LowerThan, term);
} else if(relation[0].equals(EUnaryRelationType.GreaterThan.name())) {
termString = relation[1];
term = ((FuzzySet) domain).getLabelSet().getLabel(termString);
hesitant.setUnaryRelation(EUnaryRelationType.GreaterThan, term);
} else if(relation[0].equals(EBinaryRelationType.Between.name())) {
lowerTerm = ((FuzzySet) domain).getLabelSet().getLabel(relation[1]);
upperTerm = ((FuzzySet) domain).getLabelSet().getLabel(relation[3]);
hesitant.setBinaryRelation(lowerTerm, upperTerm);
} else if(((FuzzySet) domain).getLabelSet().getLabel(values[i]) != null) {
hesitant.setLabel(((FuzzySet) domain).getLabelSet().getLabel(values[i]));
} else {
hesitant = null;
}
result[i] = hesitant;
} else {
result[i] = null;
}
}
return result;
}
static boolean containsValues(String[][] matrix) {
if (matrix.length > 0) {
for (String[] line : matrix) {
if (line.length > 0) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,21 @@
package afryca.decisionmatrix.addon;
import javax.annotation.PostConstruct;
import afryca.ase.service.IASEService;
/**
* Add-on to obtain Eclipse 4 DI container objects
*
* @author Sinbad²
* @version 3.0
*/
public class E4DIAddon {
public static IASEService aseService;
@PostConstruct
private void initialize(IASEService aseService) {
E4DIAddon.aseService = aseService;
}
}
@@ -0,0 +1,145 @@
package afryca.decisionmatrix.addon;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.core.runtime.preferences.BundleDefaultsScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.EventTopic;
import org.eclipse.e4.core.di.extensions.Preference;
import org.eclipse.e4.core.services.log.ILoggerProvider;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.core.services.nls.Translation;
import org.osgi.service.prefs.BackingStoreException;
import afryca.ase.Function;
import afryca.ase.service.IASEService;
import afryca.decisionmatrix.l10n.Messages;
import afryca.decisionmatrix.preferences.PreferenceConstants;
import afryca.workspace.service.events.IWorkspaceServiceEvents;
/**
* Add-on to manage preferences changes
*
* @author Sinbad²
* @version 3.0
*/
@SuppressWarnings("restriction")
public class PreferencesAddon {
private IASEService aseService;
private IEclipsePreferences preferences;
private Logger logger;
private Messages messages;
private Map<String, String> functionsFiles;
@PostConstruct
private void initialize(
@Translation Messages messages,
ILoggerProvider loggerProvider,
IASEService aseService,
@Preference(nodePath = PreferenceConstants.NODEPATH) IEclipsePreferences preferences) {
logger = loggerProvider.getClassLogger(this.getClass());
this.aseService = aseService;
this.preferences = preferences;
setFunctions();
}
private void setFunctions() {
functionsFiles = new HashMap<>();
setPreferenceValidFunction(PreferenceConstants.RANDOM_DECISION_MATRIX_FUNCTION_KEY);
setPreferenceValidFunction(PreferenceConstants.AGGREGATE_DECISION_MATRIX_FUNCTION_KEY);
addPreferenceChangeListener();
}
private void setPreferenceValidFunction(String key) {
String functionName = getPreferencesValue(key);
java.util.Optional<Function> optionalFunction = getFunction(functionName);
Consumer<? super Function> saveFunctionFile = function -> functionsFiles.put(function.getFile(), key);
optionalFunction.ifPresent(saveFunctionFile);
if (!optionalFunction.isPresent()) {
restorePreferenceFunction(key).ifPresent(saveFunctionFile);
};
}
private String getPreferencesValue(String key) {
return preferences.get(key, null);
}
private java.util.Optional<Function> getFunction(String name) {
return aseService
.getFunctions()
.values()
.stream()
.filter(f -> f.getName().equals(name))
.findFirst();
}
private java.util.Optional<Function> restorePreferenceFunction(String key) {
String functionName = getPreferencesDefaultValue(key);
java.util.Optional<Function> function = getFunction(functionName);
if (!function.isPresent()) {
removePreference(key);
} else {
putPreference(key, functionName);
}
return function;
}
private String getPreferencesDefaultValue(String key) {
return BundleDefaultsScope
.INSTANCE
.getNode(PreferenceConstants.NODEPATH)
.get(key, null);
}
private void putPreference(String key, String value) {
preferences.put(key, value);
try {
preferences.flush();
} catch (BackingStoreException e) {
logger.error(MessageFormat.format(messages.preferences_x_flush_fail, PreferenceConstants.NODEPATH));
}
}
private void removePreference(String key) {
preferences.remove(key);
try {
preferences.flush();
} catch (BackingStoreException e) {
logger.error(MessageFormat.format(messages.preferences_x_flush_fail, PreferenceConstants.NODEPATH));
}
}
private void addPreferenceChangeListener() {
preferences.addPreferenceChangeListener(event -> {
setPreferenceValidFunction(event.getKey());
});
}
@Inject
@Optional
private void subscribeTopicWorkspaceFunctionDeleted(
@EventTopic(IWorkspaceServiceEvents.WORKSPACE_FUNCTION_DELETED) Map<String, String> event) {
String file = event.get(IWorkspaceServiceEvents.FIELD_FILE);
String key = functionsFiles.get(file);
if (key != null) {
Consumer<? super Function> saveFunctionFile = function -> functionsFiles.put(function.getFile(), key);
restorePreferenceFunction(key).ifPresent(saveFunctionFile);
}
}
@Inject
@Optional
private void subscribeTopicWorkspaceChanged(
@EventTopic(IWorkspaceServiceEvents.WORKSPACE_CHANGED) Map<String, String> event) {
setFunctions();
}
}
@@ -0,0 +1,77 @@
package afryca.decisionmatrix.command;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.Preference;
import org.eclipse.e4.core.services.log.ILoggerProvider;
import org.eclipse.e4.core.services.log.Logger;
import afryca.ase.ParametersBuilder;
import afryca.ase.service.IASEService;
import afryca.decisionmatrix.DecisionMatrix;
import afryca.decisionmatrix.preferences.PreferenceConstants;
/**
* Generate random DecisionMatrix
*
* @author Sinbad²
* @version 3.0
*/
@SuppressWarnings("restriction")
public class GenerateRandomDecisionMatrix {
public static final String ID = "afryca.decisionmatrix.command.generate_random_decisionmatrix"; //$NON-NLS-1$
public static final String NUMBER_OF_ALTERNATIVES = "number_of_alternatives"; //$NON-NLS-1$
private Logger logger;
private Boolean lastCheckCanExecute;
@Inject
public void instantiateLogger(ILoggerProvider loggerProvider) {
logger = loggerProvider.getClassLogger(this.getClass());
}
@Execute
public DecisionMatrix execute(
@Named(NUMBER_OF_ALTERNATIVES) Integer numberOfAlternatives,
IASEService aseService,
@Preference(nodePath = PreferenceConstants.NODEPATH, value = PreferenceConstants.RANDOM_DECISION_MATRIX_FUNCTION_KEY) String function) {
logger.info("DecisionMatrix", ID);
return generateRandomDecisionMatrix(aseService, function, numberOfAlternatives);
}
private static DecisionMatrix generateRandomDecisionMatrix(IASEService aseService, String function, int n) {
return (DecisionMatrix) aseService.executeFunction(
function,
ParametersBuilder
.aseDefault()
.add("n", Integer.toString(n)) //$NON-NLS-1$
.join())
.getResult();
}
@CanExecute
public boolean canExecute(@Optional @Named(NUMBER_OF_ALTERNATIVES) Integer numberOfAlternatives) {
boolean can = checkCanCondition(numberOfAlternatives);
tryToLogCanExecute(can);
return can;
}
private boolean checkCanCondition(Integer numberOfAlternatives) {
return (numberOfAlternatives != null) && (numberOfAlternatives >= 2);
}
private void tryToLogCanExecute(boolean can) {
boolean log = (lastCheckCanExecute != null) ? (lastCheckCanExecute != can) : true;
lastCheckCanExecute = can;
if (log) {
logger.info("DecissionMatrix", ID, can);
}
}
}
@@ -0,0 +1,13 @@
package afryca.decisionmatrix.l10n;
/**
* Localization messages
*
* @author Sinbad²
* @version 3.0
*/
public class Messages {
public String command_can_executed_result;
public String command_executed;
public String preferences_x_flush_fail;
}
@@ -0,0 +1,3 @@
command_can_executed_result={0} can be executed? {1}
command_executed={0} executed
preferences_x_flush_fail=Preferences ''{0}'' flush fail
@@ -0,0 +1,3 @@
command_can_executed_result=¿{0} puede ser ejecutado? {1}
command_executed={0} ejecutado
preferences_x_flush_fail=El guardado de las preferencias ''{0}'' falló
@@ -0,0 +1,15 @@
package afryca.decisionmatrix.preferences;
/**
* Preference constants
*
* @author Sinbad²
* @version 3.0
*/
public interface PreferenceConstants {
public static final String NODEPATH = "afryca.decisionmatrix"; //$NON-NLS-1$
public static final String AGGREGATE_DECISION_MATRIX_FUNCTION_KEY = "aggregation.decisionmatrix.function"; //$NON-NLS-1$
public static final String RANDOM_DECISION_MATRIX_FUNCTION_KEY = "random.decisionmatrix.function"; //$NON-NLS-1$
public static final String CHART_FUNCTION_KEY = "gdmp.chart.functions.decisionmatrix"; //$NON-NLS-1$
public static final String MODULE_BINDINGS_KEY = "module.bindings.decisionmatrix"; //$NON-NLS-1$
}
@@ -0,0 +1,61 @@
package afryca.decisionmatrix.ranking;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import afryca.structure.Structure;
import afryca.structure.ranking.AlternativeRanking;
/**
* Compute ND ranking
*
* @author Sinbad²
* @version 2.1
*/
public class ArithmeticMeanRanking extends DecisionMatrixDominanceRanking {
/**
* Build ranking from Decision matrix
*
* @param collective
* Decision matrix
*/
public ArithmeticMeanRanking(Structure collective) {
super(collective);
computeDominanceValues();
computeRanking();
}
private void computeDominanceValues() {
float value;
for (int i = 0; i < numberOfAlternatives; i++) {
value = (float) cm.getValue(0, i);
values[i] = value;
}
}
private void computeRanking() {
List<Float> aux = new ArrayList<>();
for(int alt = 0; alt < values.length; ++alt) {
aux.add(values[alt]);
}
Collections.sort(aux);
Collections.reverse(aux);
AlternativeRanking alternativeRanking;
int pos;
Float value;
for (int i = 0; i < numberOfAlternatives; i++) {
value = values[i];
for(int j = 0; j < aux.size(); ++j) {
if(value == aux.get(j)) {
pos = j;
alternativeRanking = new AlternativeRanking(pos + 1, value);
alternativesRanking.add(alternativeRanking);
}
}
}
}
}
@@ -0,0 +1,191 @@
package afryca.decisionmatrix.ranking;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import afryca.ase.RunnableScript;
import afryca.decisionmatrix.DecisionMatrix;
import afryca.decisionmatrix.addon.E4DIAddon;
import afryca.domain.fuzzyset.FuzzySet;
import afryca.hlpr.valuation.HesitantLinguisticValuation;
import afryca.structure.Structure;
import afryca.structure.ranking.AbstractDominanceRanking;
import afryca.structure.ranking.AlternativeRanking;
import afryca.twotuple.TwoTuple;
/**
* Abstract dominance ranking
*
* @author Sinbad²
* @version 3.0
*/
public class DecisionMatrixDominanceRanking extends AbstractDominanceRanking {
protected Integer numberOfAlternatives;
protected Integer numberOfCriteria;
protected DecisionMatrix cm;
protected Float[] values;
/**
* Default builder
*/
private DecisionMatrixDominanceRanking() {
}
/**
* Build abstract dominance ranking from Decision matrix
*
* @param s
* Structure
*/
public DecisionMatrixDominanceRanking(Structure dm) {
this();
prepareStructures((int[]) dm.getPreferenceSize());
if (!containMissingValues(dm)) {
computeValuesAlternatives(dm);
}
}
private void prepareStructures(int[] elements) {
this.numberOfCriteria = elements[0];
this.numberOfAlternatives = elements[1];
values = new Float[numberOfAlternatives];
initialize();
}
private void initialize() {
cm = new DecisionMatrix(numberOfCriteria, numberOfAlternatives);
for (int i = 0; i < numberOfAlternatives; i++) {
for (int j = 0; j < numberOfCriteria; j++) {
cm.setValue(j, i, 0f);
}
}
}
private void computeValuesAlternatives(Structure collective) {
float acum;
for (int i = 0; i < numberOfAlternatives; i++) {
acum = 0;
for (int j = 0; j < numberOfCriteria; j++) {
if (collective.getValue(j, i) instanceof TwoTuple) { // Collective with multiple criteria
TwoTuple valuation = (TwoTuple) collective.getValue(j, i);
acum += valuation.calculateInverseDelta();
} else if (collective.getValue(j, i) instanceof HesitantLinguisticValuation) { // Collective with multiple criteria
if (((HesitantLinguisticValuation) collective.getValue(j, i)).getLabel() != null) {
HesitantLinguisticValuation valuation = (HesitantLinguisticValuation) collective.getValue(j, i);
acum += valuation.getLabel().getSemantic().centroid();
} else {
acum += computeValueHesitantToTwoTuple(collective, i, j);
}
} else if (collective.getValue(j, i) instanceof Float) {
acum += (float) collective.getValue(j, i);
}else if (collective.getValue(j, i) instanceof Integer) {
acum += (int) collective.getValue(j, i);
} else {
acum = Float.NaN;
}
}
acum /= numberOfCriteria;
cm.setValue(0, i, acum);
}
}
private boolean containMissingValues(Structure s) {
//maxMin
boolean result = false;
try {
result = (boolean) E4DIAddon.aseService.createFragmentBuilder().putVariable("collective", s) //$NON-NLS-1$
.putVariable("row", ((Object[][]) s.getPreferences()).length).putVariable("col", ((Object[][]) s.getPreferences())[0].length)
.setCode("consistency.containsMissingValues(collective, row, col)") //$NON-NLS-1$
.setOutputType(Boolean.class.getName()).eval().getResult();
return result;
} catch (Exception e) {
return false;
}
}
@SuppressWarnings({ "unchecked", "unused" })
private float computeValueHesitantToTwoTuple(Structure s, int i, int j) {
float value, value1, value2, acum = 0;
List<Structure> preferences = new ArrayList<Structure>();
FuzzySet blts;
Structure[] pr = new Structure[1];
pr[0] = s;
blts = (FuzzySet) E4DIAddon.aseService
.createFragmentBuilder()
.putVariable("preferences", pr) //$NON-NLS-1$
.setCode("unification.getBLTS(preferences)") //$NON-NLS-1$
.setOutputType(FuzzySet.class.getName())
.eval()
.getResult();
preferences.add(s);
ArrayList<Structure> unifiedValuations = (ArrayList<Structure>) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder().setFunction("Unification")
.putVariable("preferences", preferences).putVariable("blts", blts).execute()).getResult();
ArrayList<Structure> twoTuplePreferences = (ArrayList<Structure>) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder().setFunction("Disunification")
.putVariable("preferences", unifiedValuations).execute()).getResult();
TwoTuple valuation = (TwoTuple) twoTuplePreferences.get(0).getValue(j, i);
acum += valuation.calculateInverseDelta();
return acum;
}
/**
* Return alternatives order
*
* @return Alternatives order
*/
@Override
public Integer[] getAlternativesOrder() {
Integer[] result = new Integer[numberOfAlternatives];
for (int i = 0; i < numberOfAlternatives; i++) {
result[i] = alternativesRanking.get(i).getPosition();
}
return result;
}
/**
* Return alternatives values
*
* @return Alternatives values
*/
public Float[] getAlternativesValues() {
return values;
}
/**
* Return alternatives ranking
*
* @return Alternatives ranking
*/
public AlternativeRanking[] getAlternativesRanking() {
AlternativeRanking[] result = new AlternativeRanking[numberOfAlternatives];
for (int i = 0; i < numberOfAlternatives; i++) {
result[i] = alternativesRanking.get(i);
}
return result;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < numberOfAlternatives; i++) {
if (i > 0) {
result.append(","); //$NON-NLS-1$
}
result.append(alternativesRanking.get(i));
}
return MessageFormat.format("[{0}]", result); //$NON-NLS-1$
}
}