|
|
|
@@ -0,0 +1,396 @@
|
|
|
|
|
package flintstones.method.linguistic.topsis.phase.collective;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
|
|
|
|
|
import org.eclipse.e4.core.contexts.IEclipseContext;
|
|
|
|
|
import org.eclipse.e4.core.services.nls.Translation;
|
|
|
|
|
|
|
|
|
|
import flintstones.domain.fuzzyset.FuzzySet;
|
|
|
|
|
import flintstones.domain.fuzzyset.label.LabelLinguisticDomain;
|
|
|
|
|
import flintstones.entity.domain.Domain;
|
|
|
|
|
import flintstones.entity.method.phase.PhaseMethod;
|
|
|
|
|
import flintstones.entity.problemelement.entities.Alternative;
|
|
|
|
|
import flintstones.entity.problemelement.entities.Expert;
|
|
|
|
|
import flintstones.entity.problemelement.entities.ProblemElement;
|
|
|
|
|
import flintstones.entity.valuation.Valuation;
|
|
|
|
|
import flintstones.method.linguistic.topsis.phase.collective.messages.Messages;
|
|
|
|
|
import flintstones.model.domain.service.IDomainService;
|
|
|
|
|
import flintstones.model.problemelement.service.IProblemElementService;
|
|
|
|
|
import flintstones.valuation.twoTuple.TwoTupleValuation;
|
|
|
|
|
|
|
|
|
|
public class CollectiveInfo extends PhaseMethod {
|
|
|
|
|
|
|
|
|
|
private FuzzySet domainWeights;
|
|
|
|
|
private FuzzySet valuationDomain;
|
|
|
|
|
private FuzzySet distanceDomain;
|
|
|
|
|
|
|
|
|
|
private Map<Expert, Valuation[]> closenessCoefficientsExperts = new HashMap<Expert, Valuation[]>();
|
|
|
|
|
private Map<Domain, LabelLinguisticDomain[]> weights = new HashMap<Domain, LabelLinguisticDomain[]>();
|
|
|
|
|
private Valuation[][] decisionMatrix;
|
|
|
|
|
private Valuation[][] distancesPositiveIdealSolution;
|
|
|
|
|
private Valuation[][] distancesNegativeIdealSolution;
|
|
|
|
|
private Valuation[] positiveIdealSolution;
|
|
|
|
|
private Valuation[] negativeIdealSolution;
|
|
|
|
|
private Valuation[] globalDistancesPositiveIdealSolution;
|
|
|
|
|
private Valuation[] globalDistancesNegativeIdealSolution;
|
|
|
|
|
private Valuation[] closenessCoefficients;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
IEclipseContext context;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
@Translation
|
|
|
|
|
private Messages messages;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private IProblemElementService problemService;
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
|
private IDomainService domainService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getName() {
|
|
|
|
|
return messages.Phase_Name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ProblemElement[] getExperts() {
|
|
|
|
|
return problemService.getAll(Expert.Type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getNumberExperts() {
|
|
|
|
|
return getExperts().length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getExpertName(int pos) {
|
|
|
|
|
return getExperts()[pos].getName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getNumberAlternatives() {
|
|
|
|
|
return getAlternatives().length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ProblemElement[] getAlternatives() {
|
|
|
|
|
return problemService.getAll(Alternative.Type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getAlternativeName(int pos) {
|
|
|
|
|
return getAlternatives()[pos].getName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String[] getLinguisticDomainNames() {
|
|
|
|
|
ArrayList<String> names = new ArrayList<String>();
|
|
|
|
|
|
|
|
|
|
Domain[] domains = domainService.getAll();
|
|
|
|
|
for(Domain domain: domains) {
|
|
|
|
|
if(domain instanceof FuzzySet)
|
|
|
|
|
names.add(domain.getName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return names.toArray(new String[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String[] getLinguisticLabelsNameDomain() {
|
|
|
|
|
String[] labels = new String[domainWeights.getLabelSet().getCardinality()];
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < labels.length; ++i)
|
|
|
|
|
labels[i] = domainWeights.getLabelSet().getLabel(i).getName();
|
|
|
|
|
|
|
|
|
|
return labels;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setDomainWeights(String domainName) {
|
|
|
|
|
this.domainWeights = (FuzzySet) domainService.getByName(domainName);
|
|
|
|
|
|
|
|
|
|
if(weights.get(domainWeights) == null)
|
|
|
|
|
initializeWeights();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void initializeWeights() {
|
|
|
|
|
LabelLinguisticDomain[] weights = new LabelLinguisticDomain[getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
LabelLinguisticDomain maxLabel = domainWeights.getLabelSet().getLabel(domainWeights.getLabelSet().getCardinality() - 1);
|
|
|
|
|
for(int i = 0; i < weights.length; ++i)
|
|
|
|
|
weights[i] = maxLabel;
|
|
|
|
|
|
|
|
|
|
this.weights.put(domainWeights, weights);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void execute() {
|
|
|
|
|
setValuationDomain();
|
|
|
|
|
setDistanceDomain();
|
|
|
|
|
setClosenessCoefficientExperts();
|
|
|
|
|
|
|
|
|
|
buildCollectiveDecisionMatrix();
|
|
|
|
|
computeSolutions();
|
|
|
|
|
computeDistanceSolutions();
|
|
|
|
|
computeGlobalDistancesIdealSolutions();
|
|
|
|
|
computeClosenessCoefficients();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setValuationDomain() {
|
|
|
|
|
this.valuationDomain = (FuzzySet) importData("valuationDomain");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setDistanceDomain() {
|
|
|
|
|
this.distanceDomain = (FuzzySet) importData("distanceDomain");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
private void setClosenessCoefficientExperts() {
|
|
|
|
|
this.closenessCoefficientsExperts = (Map<Expert, Valuation[]>) importData("coefficients");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void buildCollectiveDecisionMatrix() {
|
|
|
|
|
decisionMatrix = new Valuation[getNumberAlternatives()][getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
ProblemElement[] experts = getExperts();
|
|
|
|
|
|
|
|
|
|
LabelLinguisticDomain maxLabel = domainWeights.getLabelSet().getLabel(domainWeights.getLabelSet().getCardinality() - 1);
|
|
|
|
|
TwoTupleValuation maxLabelTwoTuple = new TwoTupleValuation(domainWeights, maxLabel);
|
|
|
|
|
|
|
|
|
|
Valuation[] coefficients;
|
|
|
|
|
TwoTupleValuation coef, weight, weightedValuation;
|
|
|
|
|
for(int i = 0; i < closenessCoefficientsExperts.size(); ++i) {
|
|
|
|
|
coefficients = closenessCoefficientsExperts.get(experts[i]);
|
|
|
|
|
weight = new TwoTupleValuation(domainWeights, weights.get(domainWeights)[i]);
|
|
|
|
|
for(int j = 0; j < coefficients.length; ++j) {
|
|
|
|
|
coef = (TwoTupleValuation) coefficients[j];
|
|
|
|
|
weightedValuation = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
weightedValuation.calculateDelta(coef.calculateInverseDelta() * (weight.calculateInverseDelta() / maxLabelTwoTuple.calculateInverseDelta()));
|
|
|
|
|
|
|
|
|
|
decisionMatrix[j][i] = weightedValuation;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeSolutions() {
|
|
|
|
|
computePositiveIdealSolution();
|
|
|
|
|
computeNegativeIdealSolution();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computePositiveIdealSolution() {
|
|
|
|
|
positiveIdealSolution = new Valuation[getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
List<Valuation> valuationsExpert;
|
|
|
|
|
|
|
|
|
|
for (int exp = 0; exp < getNumberExperts(); ++exp) {
|
|
|
|
|
|
|
|
|
|
valuationsExpert = getValuationsExpert(exp);
|
|
|
|
|
|
|
|
|
|
Collections.sort(valuationsExpert);
|
|
|
|
|
|
|
|
|
|
positiveIdealSolution[exp] = valuationsExpert.get(valuationsExpert.size() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Valuation> getValuationsExpert(int exp) {
|
|
|
|
|
List<Valuation> valuations = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
for(int alt = 0; alt < getNumberAlternatives(); ++alt)
|
|
|
|
|
valuations.add(decisionMatrix[alt][exp]);
|
|
|
|
|
|
|
|
|
|
return valuations;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeNegativeIdealSolution() {
|
|
|
|
|
negativeIdealSolution = new Valuation[getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
List<Valuation> valuationsExpert;
|
|
|
|
|
|
|
|
|
|
for (int exp = 0; exp < getNumberExperts(); ++exp) {
|
|
|
|
|
|
|
|
|
|
valuationsExpert = getValuationsExpert(exp);
|
|
|
|
|
|
|
|
|
|
Collections.sort(valuationsExpert);
|
|
|
|
|
|
|
|
|
|
negativeIdealSolution[exp] = valuationsExpert.get(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeDistanceSolutions() {
|
|
|
|
|
computeDistanceIdealPositiveSolution();
|
|
|
|
|
computeDistanceIdealNegativeSolution();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeDistanceIdealPositiveSolution() {
|
|
|
|
|
distancesPositiveIdealSolution = new Valuation[getNumberAlternatives()][getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
TwoTupleValuation distance;
|
|
|
|
|
|
|
|
|
|
double dist;
|
|
|
|
|
for(int i = 0; i < decisionMatrix.length; ++i) {
|
|
|
|
|
for(int j = 0; j < decisionMatrix[i].length; ++j) {
|
|
|
|
|
dist = computeDistanceTwoTuple(decisionMatrix[i][j], positiveIdealSolution[j]);
|
|
|
|
|
|
|
|
|
|
distance = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
distance.calculateDelta(dist);
|
|
|
|
|
|
|
|
|
|
distancesPositiveIdealSolution[i][j] = distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Float computeDistanceTwoTuple(Valuation valuation1, Valuation valuation2) {
|
|
|
|
|
return (float) Math.abs(((TwoTupleValuation) valuation1).calculateInverseDelta() - ((TwoTupleValuation) valuation2).calculateInverseDelta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeDistanceIdealNegativeSolution() {
|
|
|
|
|
distancesNegativeIdealSolution = new Valuation[getNumberAlternatives()][getNumberExperts()];
|
|
|
|
|
|
|
|
|
|
TwoTupleValuation distance;
|
|
|
|
|
|
|
|
|
|
double dist;
|
|
|
|
|
for(int i = 0; i < decisionMatrix.length; ++i) {
|
|
|
|
|
for(int j = 0; j < decisionMatrix[i].length; ++j) {
|
|
|
|
|
dist = computeDistanceTwoTuple(decisionMatrix[i][j], negativeIdealSolution[j]);
|
|
|
|
|
|
|
|
|
|
distance = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
distance.calculateDelta(dist);
|
|
|
|
|
|
|
|
|
|
distancesNegativeIdealSolution[i][j] = distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeGlobalDistancesIdealSolutions() {
|
|
|
|
|
computeGlobalPositiveIdealSolutionDistances();
|
|
|
|
|
computeGlobalNegativeIdealSolutionDistances();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeGlobalPositiveIdealSolutionDistances() {
|
|
|
|
|
globalDistancesPositiveIdealSolution = new Valuation[getNumberAlternatives()];
|
|
|
|
|
|
|
|
|
|
TwoTupleValuation distance;
|
|
|
|
|
|
|
|
|
|
double acum;
|
|
|
|
|
for(int i = 0; i < distancesPositiveIdealSolution.length; ++i) {
|
|
|
|
|
acum = 0;
|
|
|
|
|
for(int j = 0; j < distancesPositiveIdealSolution[i].length; ++j)
|
|
|
|
|
acum += ((TwoTupleValuation) distancesPositiveIdealSolution[i][j]).calculateInverseDelta();
|
|
|
|
|
|
|
|
|
|
distance = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
distance.calculateDelta(acum /distancesPositiveIdealSolution[i].length);
|
|
|
|
|
|
|
|
|
|
globalDistancesPositiveIdealSolution[i] = distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeGlobalNegativeIdealSolutionDistances() {
|
|
|
|
|
globalDistancesNegativeIdealSolution = new Valuation[getNumberAlternatives()];
|
|
|
|
|
|
|
|
|
|
TwoTupleValuation distance;
|
|
|
|
|
|
|
|
|
|
double acum;
|
|
|
|
|
for(int i = 0; i < distancesNegativeIdealSolution.length; ++i) {
|
|
|
|
|
acum = 0;
|
|
|
|
|
for(int j = 0; j < distancesNegativeIdealSolution[i].length; ++j)
|
|
|
|
|
acum += ((TwoTupleValuation) distancesNegativeIdealSolution[i][j]).calculateInverseDelta();
|
|
|
|
|
|
|
|
|
|
distance = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
distance.calculateDelta(acum / distancesNegativeIdealSolution[i].length);
|
|
|
|
|
|
|
|
|
|
globalDistancesNegativeIdealSolution[i] = distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void computeClosenessCoefficients() {
|
|
|
|
|
closenessCoefficients = new Valuation[getNumberAlternatives()];
|
|
|
|
|
|
|
|
|
|
TwoTupleValuation closeness;
|
|
|
|
|
|
|
|
|
|
double posDist, negDist, coeff;
|
|
|
|
|
for(int i = 0; i < globalDistancesPositiveIdealSolution.length; ++i) {
|
|
|
|
|
posDist = ((TwoTupleValuation) globalDistancesPositiveIdealSolution[i]).calculateInverseDelta();
|
|
|
|
|
negDist = ((TwoTupleValuation) globalDistancesNegativeIdealSolution[i]).calculateInverseDelta();
|
|
|
|
|
coeff = (distanceDomain.getLabelSet().getCardinality() - 1) * (negDist / (posDist + negDist));
|
|
|
|
|
|
|
|
|
|
closeness = new TwoTupleValuation(distanceDomain);
|
|
|
|
|
closeness.calculateDelta(coeff);
|
|
|
|
|
closenessCoefficients[i] = closeness;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setExpertWeight(int posExpert, String labelName) {
|
|
|
|
|
weights.get(domainWeights)[posExpert] = domainWeights.getLabelSet().getLabel(labelName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean distanceDomainChanged() {
|
|
|
|
|
FuzzySet oldDomain = (FuzzySet) this.distanceDomain.clone();
|
|
|
|
|
setDistanceDomain();
|
|
|
|
|
return (!oldDomain.equals(this.distanceDomain)) ? true:false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean valuationDomainChanged() {
|
|
|
|
|
FuzzySet oldDomain = (FuzzySet) this.valuationDomain.clone();
|
|
|
|
|
setValuationDomain();
|
|
|
|
|
return (!oldDomain.equals(this.valuationDomain)) ? true:false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringExpertWeight(int posExpert) {
|
|
|
|
|
return weights.get(domainWeights)[posExpert].getName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringDecisionMatrixValuation(int posExp, int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) decisionMatrix[posAlt][posExp];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringPositiveIdealSolutionExpert(int posExp) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) positiveIdealSolution[posExp];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringNegativeIdealSolutionExpert(int posExp) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) negativeIdealSolution[posExp];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringCollectiveDistancePositiveIdealSolutionValuation(int posExpert, int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) distancesPositiveIdealSolution[posAlt][posExpert];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringCollectiveDistanceNegativeIdealSolutionValuation(int posExpert, int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) distancesNegativeIdealSolution[posAlt][posExpert];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringCollectiveGlobalDistancePositiveIdealSolutionValuation(int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) globalDistancesPositiveIdealSolution[posAlt];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringCollectiveGlobalDistanceNegativeIdealSolutionValuation(int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) globalDistancesNegativeIdealSolution[posAlt];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringCollectiveClosenessCoefficient(int posAlt) {
|
|
|
|
|
TwoTupleValuation v = (TwoTupleValuation) closenessCoefficients[posAlt];
|
|
|
|
|
return v.changeFormatValuationToString() + "(" + Math.round(v.calculateInverseDelta() * 1000d) / 1000d + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getStringRankingPositionAlternative(int posAlt) {
|
|
|
|
|
double[] values = new double[closenessCoefficients.length];
|
|
|
|
|
for(int i = 0; i < values.length; ++i)
|
|
|
|
|
values[i] = ((TwoTupleValuation) closenessCoefficients[i]).calculateInverseDelta();
|
|
|
|
|
|
|
|
|
|
return Integer.toString(findRank(values)[posAlt] + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int[] findRank(double[] inp) {
|
|
|
|
|
int[] outp = new int[inp.length];
|
|
|
|
|
for(int i = 0; i < inp.length; i++) {
|
|
|
|
|
for(int k = 0; k < inp.length; k++) {
|
|
|
|
|
if(inp[k] > inp[i]) outp[i]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return outp;
|
|
|
|
|
}
|
|
|
|
|
}
|