Skip to content

Commit

Permalink
[BENCHMARK] Preparing for inclusion (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
demid5111 committed May 3, 2022
1 parent 6074ed3 commit 858dd67
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 32 deletions.
9 changes: 6 additions & 3 deletions src/main/java/dss/lingvo/samples/TT2HFLTSCoordinator.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,12 @@ private void processMultiLevelAdvancedSample(File inputFile, File outputDirector

// Step 1. Aggregate by abstraction level
TT2HFLTSMHTWOWAMultiLevelOperator tt2HFLTSMHTWOWAMultiLevelOperator = new TT2HFLTSMHTWOWAMultiLevelOperator();
List<ArrayList<ArrayList<TT2HFLTS>>> allByLevel = tt2HFLTSMHTWOWAMultiLevelOperator.aggregateByAbstractionLevel(model.getCriteria(), model.getAbstractionLevels(), all, targetScaleSize);
List<ArrayList<ArrayList<TT2HFLTS>>> allByLevel = tt2HFLTSMHTWOWAMultiLevelOperator.aggregateByAbstractionLevel(model.getCriteria(), model.getAbstractionLevels(), all, targetScaleSize, model.getCriteriaWeightsPerGroup());

List<ArrayList<ArrayList<TT2HFLTS>>> allByExpert = tt2HFLTSMHTWOWAMultiLevelOperator.transposeByAbstractionLevel(model.getAbstractionLevels().size(), model.getAlternatives().size(), model.getExperts().size(), allByLevel);

float[] a = new float[model.getExpertWeightsRule().values().size()];
int numExperts = model.getExpertWeightsRule().values().size();
float[] a = new float[numExperts];
float curMax = 0f;
for (Map.Entry<String, Float> e : model.getExpertWeightsRule().entrySet()) {
if (e.getKey().equals("1")) {
Expand All @@ -128,7 +129,9 @@ private void processMultiLevelAdvancedSample(File inputFile, File outputDirector
}
}
a[0] = curMax;
a[1] = 1 - curMax;
if (numExperts > 1) {
a[1] = 1 - curMax;
}
List<ArrayList<TT2HFLTS>> altToLevel = tt2HFLTSMHTWOWAMultiLevelOperator.aggregateByExpert(model.getAbstractionLevels().size(), model.getAlternatives().size(), 7, allByExpert, a);

List<TT2HFLTS> altVec = tt2HFLTSMHTWOWAMultiLevelOperator.aggregateFinalAltEst(7, altToLevel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
import java.util.stream.IntStream;

public class TT2HFLTSMHTWOWAMultiLevelOperator {
public List<ArrayList<ArrayList<TT2HFLTS>>> aggregateByAbstractionLevel(Map<String, List<TTCriteriaModel>> criteria, List<TTAbstractionLevelModel> abstractionLevels, List<ArrayList<ArrayList<TT2HFLTS>>> all, int targetScaleSize) {
public List<ArrayList<ArrayList<TT2HFLTS>>> aggregateByAbstractionLevel(Map<String, List<TTCriteriaModel>> criteria,
List<TTAbstractionLevelModel> abstractionLevels,
List<ArrayList<ArrayList<TT2HFLTS>>> all,
int targetScaleSize, Map<String,
List<Float>> criteriaWeightsPerGroup) {
List<TTCriteriaModel> orderedCriteria = TTUtils.getOrderedCriteriaList(criteria, abstractionLevels);
TT2HFLTSMHTWAOperator tt2HFLTSMHTWAOperator = new TT2HFLTSMHTWAOperator();
List<ArrayList<ArrayList<TT2HFLTS>>> expEstimates = new ArrayList<>();
Expand All @@ -36,8 +40,20 @@ public List<ArrayList<ArrayList<TT2HFLTS>>> aggregateByAbstractionLevel(Map<Stri
for (int i : indices) {
tmp.add(singleAltEst.get(i));
}
// weights are currently equal
float[] weights = getEqualWeights(tmp.size());

float[] weights;
if (criteriaWeightsPerGroup == null ||
criteriaWeightsPerGroup.get(ttAbstractionLevelModel.getAbstractionLevelID()) == null) {
// weights are equal if not set in JSON
weights = getEqualWeights(tmp.size());
} else {
List<Float> jsonWeights = criteriaWeightsPerGroup.get(ttAbstractionLevelModel.getAbstractionLevelID());
weights = new float[jsonWeights.size()];
int i = 0;
for (Float f : jsonWeights) {
weights[i++] = (f != null ? f : Float.NaN);
}
}
TT2HFLTS aggRes = tt2HFLTSMHTWAOperator.calculate(tmp, weights, targetScaleSize);
levelEstimates.add(aggRes);
}
Expand Down
124 changes: 104 additions & 20 deletions src/main/java/dss/lingvo/utils/TTUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dss.lingvo.utils;

import dss.lingvo.hflts.TTHFLTS;
import dss.lingvo.t2.TTNormalizedTranslator;
import dss.lingvo.t2.TTTuple;
import dss.lingvo.t2hflts.TT2HFLTS;
Expand Down Expand Up @@ -250,7 +249,10 @@ private static float calculatePredessorsWeightsSum(float firstWeight, int curren

public static List<ArrayList<ArrayList<TT2HFLTS>>> getAllEstimationsFromMultiLevelJSONModel(TTJSONMultiLevelInputModel ttjsonModel, int targetScaleSize) {
Map<String, List<TTExpertEstimationsModel>> estimations = ttjsonModel.getEstimations();
Map<String, Integer> averages = getAverageForEachNumericCriterion(estimations);
Map<String, Double> averages = getAverageForEachNumericCriterion(
estimations,
ttjsonModel.getCriteria(),
ttjsonModel.getScales());
Map<String, List<TTCriteriaModel>> criteria = ttjsonModel.getCriteria();
List<TTAbstractionLevelModel> levels = ttjsonModel.getAbstractionLevels();
List<ArrayList<ArrayList<TT2HFLTS>>> expertsEstimationsList = new ArrayList<>();
Expand All @@ -274,16 +276,34 @@ public static List<ArrayList<ArrayList<TT2HFLTS>>> getAllEstimationsFromMultiLev
.orElse(null);

TT2HFLTS res;
if (critEst.getQualitative()) {
TTCriteriaModel criterion = getCriterion(criteriaModel.getCriteriaID(), criteria);
TTScaleModel scale = getScale(critEst.getScaleID(), ttjsonModel.getScales());

if (isQualitativeAssessment(criterion, critEst) &&
!isCrispQualitativeAssessment(scale)) {
// transform it to 2tuple as usual linguistic info
res = transformToTTHFLTS(ttjsonModel.getScales(), critEst.getScaleID(), critEst.getEstimation());
} else {
// transform numeric to tuple and then to TTHFLTS
// however, first of all we need to normalize the values
float numericEstimation = Integer.parseInt(critEst.getEstimation().get(0)) / ((float) averages.get(critEst.getCriteriaID()));
List<Float> fSet = TTNormalizedTranslator.getInstance().getFuzzySetForNumericEstimation(numericEstimation, targetScaleSize);
float resTranslation = TTNormalizedTranslator.getInstance().getTranslationFromFuzzySet(fSet);
TTTuple resTuple = TTNormalizedTranslator.getInstance().getTTupleForNumericTranslation(resTranslation, targetScaleSize);
// however, first we need to normalize the values
Float valueToRemember;
if (isQualitativeAssessment(criterion, critEst) && isCrispQualitativeAssessment(scale)) {
// transform it to number according to the specified mapping
valueToRemember = findReplacingCrispLinguisticValue(
critEst.getEstimation().get(0),
scale);
} else {
valueToRemember = Float.parseFloat(critEst.getEstimation().get(0));
}

TTNormalizedTranslator translator = TTNormalizedTranslator.getInstance();

float numericEstimation = valueToRemember / (averages.get(critEst.getCriteriaID()).floatValue());

List<Float> fSet = translator.getFuzzySetForNumericEstimation(numericEstimation, targetScaleSize);
float resTranslation = translator.getTranslationFromFuzzySet(fSet);
TTTuple resTuple = translator.getTTupleForNumericTranslation(resTranslation, targetScaleSize);

List<TTTuple> tmpL = new ArrayList<>();
tmpL.add(resTuple);
res = new TT2HFLTS(tmpL);
Expand All @@ -298,29 +318,93 @@ public static List<ArrayList<ArrayList<TT2HFLTS>>> getAllEstimationsFromMultiLev
return expertsEstimationsList;
}

private static Map<String, Integer> getAverageForEachNumericCriterion(Map<String, List<TTExpertEstimationsModel>> estimationsMap) {
Map<String, List<Integer>> averages = new TreeMap<>();
Map<String, Integer> sumFinal = new TreeMap<>();
private static Map<String, Double> getAverageForEachNumericCriterion(
Map<String, List<TTExpertEstimationsModel>> estimationsMap,
Map<String, List<TTCriteriaModel>> criteria,
List<TTScaleModel> scales
) {
Map<String, List<Float>> averages = new TreeMap<>();
for (Map.Entry<String, List<TTExpertEstimationsModel>> entry : estimationsMap.entrySet()) {
for (TTExpertEstimationsModel ttExpertEstimationsModel : entry.getValue()) {
for (TTCriteriaEstimationsModel ttCriteriaEstimationsModel : ttExpertEstimationsModel.getCriteria2Estimation()) {
if (!ttCriteriaEstimationsModel.getQualitative()) {
List<Integer> averList = averages.get(ttCriteriaEstimationsModel.getCriteriaID());
if (averList == null) {
averList = new ArrayList<>();
}
averList.add(Integer.parseInt(ttCriteriaEstimationsModel.getEstimation().get(0)));
averages.put(ttCriteriaEstimationsModel.getCriteriaID(), averList);
TTCriteriaModel criterion = getCriterion(ttCriteriaEstimationsModel.getCriteriaID(), criteria);
TTScaleModel scale = getScale(ttCriteriaEstimationsModel.getScaleID(), scales);

if (isQualitativeAssessment(criterion, ttCriteriaEstimationsModel) &&
!isCrispQualitativeAssessment(scale)) {
// this is a 2-tuple that needs different pre-processing
continue;
}

List<Float> averList = averages.get(ttCriteriaEstimationsModel.getCriteriaID());
if (averList == null) {
averList = new ArrayList<>();
}

Float valueToRemember;
if (scale != null && scale.getValues() != null) {
// this is a linguistic variable that has to be replaced with a numeric value
valueToRemember = findReplacingCrispLinguisticValue(
ttCriteriaEstimationsModel.getEstimation().get(0),
scale);
} else {
// this is a numeric value that should be parsed from string
valueToRemember = Float.parseFloat(ttCriteriaEstimationsModel.getEstimation().get(0));
}

averList.add(valueToRemember);

averages.put(ttCriteriaEstimationsModel.getCriteriaID(), averList);
}

}
}
for (Map.Entry<String, List<Integer>> entry : averages.entrySet()) {
sumFinal.put(entry.getKey(), entry.getValue().stream().mapToInt(Integer::intValue).sum());

Map<String, Double> sumFinal = new TreeMap<>();
for (Map.Entry<String, List<Float>> entry : averages.entrySet()) {
double normalized_value = Math.sqrt(entry.getValue().stream().mapToDouble(e -> Math.pow(e, 2)).sum());
sumFinal.put(entry.getKey(), normalized_value);
}
return sumFinal;
}

private static TTCriteriaModel getCriterion(String criterionID, Map<String, List<TTCriteriaModel>> criteria) {
for (Map.Entry<String, List<TTCriteriaModel>> entry : criteria.entrySet()) {
for (TTCriteriaModel criteriaModel : entry.getValue()) {
if (criteriaModel.getCriteriaID().equals(criterionID)) {
return criteriaModel;
}
}
}
return null;
}

private static TTScaleModel getScale(String scaleID, List<TTScaleModel> scales) {
for (TTScaleModel scaleModel : scales) {
if (scaleModel.getScaleID().equals(scaleID)) {
return scaleModel;
}
}
return null;
}

private static Float findReplacingCrispLinguisticValue(String label, TTScaleModel scale) {
return scale.getValues().get(scale.getLabels().indexOf(label));
}

private static boolean isQualitativeAssessment(TTCriteriaModel criterion,
TTCriteriaEstimationsModel ttCriteriaEstimationsModel) {
// in new format qualitative flag is described in criteria
if (criterion != null && criterion.isQualitative()) {
return true;
}
// in old format qualitative flag is described in each assessment
return ttCriteriaEstimationsModel.getQualitative();
}

private static boolean isCrispQualitativeAssessment(TTScaleModel scale) {
// in new format qualitative flag is described in criteria
return scale != null && scale.getValues() != null;
}

public static List<TTCriteriaModel> getOrderedCriteriaList(Map<String, List<TTCriteriaModel>> criteria,
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/dss/lingvo/utils/models/input/TTCriteriaModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public class TTCriteriaModel {
private String criteriaID;
private String criteriaName;
private boolean qualitative;
private boolean isBenefit;
private String units;

public String getCriteriaID() {
return criteriaID;
Expand All @@ -28,4 +30,20 @@ public boolean isQualitative() {
public void setQualitative(boolean qualitative) {
this.qualitative = qualitative;
}

public String getUnits() {
return units;
}

public void setUnits(String units) {
this.units = units;
}

public boolean isBenefit() {
return isBenefit;
}

public void setBenefit(boolean isBenefit) {
this.isBenefit = isBenefit;
}
}
9 changes: 9 additions & 0 deletions src/main/java/dss/lingvo/utils/models/input/TTScaleModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class TTScaleModel {
private String scaleID;
private String scaleName;
private List<String> labels;
private List<Float> values;

public List<String> getLabels() {
return labels;
Expand All @@ -30,4 +31,12 @@ public String getScaleID() {
public void setScaleID(String scaleID) {
this.scaleID = scaleID;
}

public List<Float> getValues() {
return values;
}

public void setValues(List<Float> values) {
this.values = values;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class TTCommonInputModel {
private Map<String, Float> abstractionLevelWeights;
@JsonProperty("expertWeightsRule")
private Map<String, Float> expertWeightsRule;
@JsonProperty("criteriaWeightsPerGroup")
private Map<String, List<Float> > criteriaWeightsPerGroup;

public List<TTAlternativeModel> getAlternatives() {
return alternatives;
Expand Down Expand Up @@ -73,4 +75,12 @@ public Map<String, Float> getExpertWeightsRule() {
public void setExpertWeightsRule(Map<String, Float> expertWeightsRule) {
this.expertWeightsRule = expertWeightsRule;
}

public Map<String, List<Float>> getCriteriaWeightsPerGroup() {
return criteriaWeightsPerGroup;
}

public void setCriteriaWeightsPerGroup(Map<String, List<Float>>criteriaWeightsPerGroup) {
this.criteriaWeightsPerGroup = criteriaWeightsPerGroup;
}
}
2 changes: 1 addition & 1 deletion src/main/resources/description_multilevel.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
{
"criteriaID": "К.ЭТУА.2",
"criteriaName": "Справедливость с точки зрения рабочих",
"qualitative": true
"qualitative": false
}
],
"aesthetics": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static void runOnceBeforeClass() throws IOException {
.aggregateByAbstractionLevel(model.getCriteria(),
model.getAbstractionLevels(),
all,
targetScaleSize);
targetScaleSize, model.getCriteriaWeightsPerGroup());

allByExpert = tt2HFLTSMHTWOWAMultiLevelOperator
.transposeByAbstractionLevel(model.getAbstractionLevels().size(),
Expand All @@ -66,7 +66,7 @@ public void testAggregateByAbstractionLevel(){
assertEquals(26, allByLevel.get(0).size());
assertEquals(8, allByLevel.get(0).get(0).size());
ArrayList<TTTuple> tmp = new ArrayList<>();
tmp.add(new TTTuple("p",7,0.17411518f,1));
tmp.add(new TTTuple("p",7,0.25560308f,1));

TT2HFLTS myHFLTS1 = new TT2HFLTS(tmp);
assertEquals(myHFLTS1, allByLevel.get(0).get(0).get(0));
Expand All @@ -79,7 +79,7 @@ public void testAggregateByExpert(){
assertEquals(26, altToLevel.size());
assertEquals(8, altToLevel.get(0).size());
ArrayList<TTTuple> tmp = new ArrayList<>();
tmp.add(new TTTuple("p",7,0.17411518f,1));
tmp.add(new TTTuple("p",7,0.25560308f,1));

TT2HFLTS myHFLTS1 = new TT2HFLTS(tmp);
assertEquals(myHFLTS1, allByLevel.get(0).get(0).get(0));
Expand All @@ -93,7 +93,7 @@ public void testTransposeByAbstractionLevel(){
assertEquals(26, allByExpert.get(0).size());
assertEquals(7, allByExpert.get(0).get(0).size());
ArrayList<TTTuple> tmp = new ArrayList<>();
tmp.add(new TTTuple("p",7,0.17411518f,1));
tmp.add(new TTTuple("p",7,0.25560308f,1));

TT2HFLTS myHFLTS1 = new TT2HFLTS(tmp);
assertEquals(myHFLTS1, allByExpert.get(0).get(0).get(0));
Expand All @@ -105,7 +105,7 @@ public void testAggregateFinalAltEst(){

assertEquals(26, altVec.size());
ArrayList<TTTuple> tmp = new ArrayList<>();
tmp.add(new TTTuple("p",7,0.17411518f,1));
tmp.add(new TTTuple("p",7,0.25560308f,1));

TT2HFLTS myHFLTS1 = new TT2HFLTS(tmp);
assertEquals(myHFLTS1, allByExpert.get(0).get(0).get(0));
Expand Down

0 comments on commit 858dd67

Please sign in to comment.