From 6ddf690f29f87e3cd5b7c69caf8b667d63d9f0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Walter?= <juergen.walter@uni-wuerzburg.de> Date: Fri, 4 May 2018 19:36:59 +0200 Subject: [PATCH] Added permutations when resolving recurring DoFs Calculate permutations matching recurring DoFs instead of full permutation. Illustrative example: 'cpu cores'<8>, 'users'<50,75,100, 150>, 'Probability dropRequests'<0.0>, 'users'<300>, 'Probability dropRequests'<0.1>, 'users'<400>, 'Probability dropRequests'<0.3>, Generates 6 permutations: <8, (((50|75|100|150),0.0) | (300,0.1) | (400,0.2))> --- .../engine/util/DoFCrossProductHelper.java | 109 +++++++++++++++--- 1 file changed, 91 insertions(+), 18 deletions(-) diff --git a/core/tools.descartes.dql.core.engine/src/tools/descartes/dql/core/engine/util/DoFCrossProductHelper.java b/core/tools.descartes.dql.core.engine/src/tools/descartes/dql/core/engine/util/DoFCrossProductHelper.java index 82cda653..f586f065 100644 --- a/core/tools.descartes.dql.core.engine/src/tools/descartes/dql/core/engine/util/DoFCrossProductHelper.java +++ b/core/tools.descartes.dql.core.engine/src/tools/descartes/dql/core/engine/util/DoFCrossProductHelper.java @@ -42,18 +42,84 @@ public class DoFCrossProductHelper { Map<DoF, String[]> possibleDofValues; List<HashMap<DoF, String>> result; + int distinctDoFs; + Map<String, List<Integer>> map; + EntityMapping request; + String[] dofss; + int maxOccurences; + int mostFrequentDoFIndex; /** - * calculates the X-Product for DoFs of the EntityMapping input + * Calculates the permutations for DoFs of the EntityMapping * * @param input * @return List of DoF-combination. Each list element contains one possible * combination */ public static List<HashMap<DoF, String>> calculateCrossProduct(EntityMapping input) { - DoFCrossProductHelper helper = new DoFCrossProductHelper(); - helper.possibleDofValues = helper.getPossibleDofValues(input); - List<HashMap<DoF, String>> result = helper.recursiveCrossProduct(); + return (new DoFCrossProductHelper()).calculatePermutations(input); + + } + + private List<HashMap<DoF, String>> calculatePermutations(EntityMapping request) { + this.request = request; + map = new HashMap<String, List<Integer>>(); + for (int i = 0; i < request.getDoF().size(); i++) { + DoF dof = request.getDoF().get(i); + String key = dof.getIdentifier(); + if (!map.containsKey(key)) { + List<Integer> list = new LinkedList<Integer>(); + list.add(i); + map.put(dof.getIdentifier(), list); + } else { + List<Integer> list = map.get(key); + list.add(i); + map.put(key, list); + } + } + int repeatedDoFs = 0; + maxOccurences = 1; + for (String key : map.keySet()) { + System.out.println("" + key + " " + map.get(key)); + if (map.get(key).size() > 1) { + maxOccurences = Math.max(map.get(key).size(), maxOccurences); + mostFrequentDoFIndex = 1; + repeatedDoFs++; + + } + } + distinctDoFs = map.keySet().size(); + + if (repeatedDoFs == 0) { + /** calculate cross product */ + possibleDofValues = getPossibleDofValues(request); + this.result = new ArrayList<HashMap<DoF, String>>(); + this.recursiveCrossProduct(0, new HashMap<DoF, String>()); + + } else { + /** + * Calculate permutations matching recurring DoFs instead of full permutation + * Illustrative example: + * + * 'cpu cores'<8>, + * + * 'users'<50,75,100, 150>, 'Probability dropRequests'<0.0>, + * + * 'users'<300>, 'Probability dropRequests'<0.1>, + * + * 'users'<400>, 'Probability dropRequests'<0.3>, + * + * Generates 6 permutations: <8, (((50|75|100|150),0.0) | (300,0.1) | (400,0.2)> + * + */ + this.possibleDofValues = getPossibleDofValues(request); + this.dofss = (String[]) map.keySet().toArray(new String[map.keySet().size()]); + + this.result = new ArrayList<HashMap<DoF, String>>(); + for (int i = 0; i < maxOccurences; i++) { + generatePermutations(new HashMap<DoF, String>(), 0, i); + } + } return result; } @@ -72,15 +138,6 @@ public class DoFCrossProductHelper { return possibleDofValues; } - /** - * Starting point for recursion - */ - private List<HashMap<DoF, String>> recursiveCrossProduct() { - this.result = new ArrayList<HashMap<DoF, String>>(); - recursiveCrossProduct(0, new HashMap<DoF, String>()); - return result; - } - /** * recursive traversal of possible options */ @@ -89,7 +146,7 @@ public class DoFCrossProductHelper { if (counter == possibleDofValues.size()) result.add((HashMap<DoF, String>) temporaryResult.clone()); else { - Entry<DoF, String[]> entry = getElementNumber(possibleDofValues, counter); + Entry<DoF, String[]> entry = getDoFPair(possibleDofValues, counter); for (String string : entry.getValue()) { temporaryResult.put(entry.getKey(), string); recursiveCrossProduct(counter + 1, temporaryResult); @@ -97,10 +154,27 @@ public class DoFCrossProductHelper { } } + private void generatePermutations(HashMap<DoF, String> temporaryResult, int dofNumber, int occurence) { + + if (dofNumber >= distinctDoFs) { + result.add((HashMap<DoF, String>) temporaryResult.clone()); + } else { + String key = dofss[dofNumber]; + DoF dof = request.getDoF().get(map.get(key).get(Math.min(occurence, map.get(key).size() - 1))); + String[] values = possibleDofValues.get(dof); + dofNumber = dofNumber + 1; + for (String dofValue : values) { + temporaryResult.put(dof, dofValue); + generatePermutations((HashMap<DoF, String>) temporaryResult.clone(), dofNumber, occurence); + } + } + + } + /** * returns element number i for a map, treating it like a map */ - private Entry<DoF, String[]> getElementNumber(Map<DoF, String[]> map, int counter) { + private Entry<DoF, String[]> getDoFPair(Map<DoF, String[]> map, int counter) { int i = 0; for (Entry<DoF, String[]> entry : map.entrySet()) { @@ -113,8 +187,8 @@ public class DoFCrossProductHelper { } /** - * Creates an String[] with the values of the requested DoF. Calculation - * depends on if it is an IntervalVariationClause or a ValueVariationClause + * Creates an String[] with the values of the requested DoF. Calculation depends + * on if it is an IntervalVariationClause or a ValueVariationClause * * @param doFProperties * @return DoF values as String[] @@ -140,7 +214,6 @@ public class DoFCrossProductHelper { arrayString = arrayString.substring(0, arrayString.length() - 1); } else if (doFProperties.get("function").equals("fixed")) { - arrayString = (String) doFProperties.get("value"); arrayString = arrayString.replace("]", ""); arrayString = arrayString.replace("[", ""); -- GitLab