Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BENCHMARK] Preparing for inclusion #6

Merged
merged 3 commits into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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