From 3a278b0673bb1aca794d33d1767209d9bc2c2a9b Mon Sep 17 00:00:00 2001 From: Anton Antonov Date: Mon, 13 Feb 2017 23:59:40 -0500 Subject: [PATCH] Implemented randomChoice. --- .../TriesWithFrequencies/src/Experiments.java | 6 ++ .../src/TrieFunctions.java | 93 ++++++++++++++++--- 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Java/TriesWithFrequencies/src/Experiments.java b/Java/TriesWithFrequencies/src/Experiments.java index 1d3fd0c5..332e1007 100644 --- a/Java/TriesWithFrequencies/src/Experiments.java +++ b/Java/TriesWithFrequencies/src/Experiments.java @@ -149,6 +149,12 @@ public static void basic() { System.out.println( TrieFunctions.leafProbabilitiesJSON( pstrie ) ); System.out.println(); + System.out.println( "randomChoice :"); + System.out.println( TrieFunctions.randomChoice( pstrie, true ) ); + System.out.println(); + System.out.println( TrieFunctions.randomChoice( pstrie, false ) ); + System.out.println(); + // sampleSeq = new ArrayList() {{ add("ar"); add("as"); }}; // List< List > sampleSeqList = new ArrayList<>(); diff --git a/Java/TriesWithFrequencies/src/TrieFunctions.java b/Java/TriesWithFrequencies/src/TrieFunctions.java index 4e65f22e..6ca1181c 100644 --- a/Java/TriesWithFrequencies/src/TrieFunctions.java +++ b/Java/TriesWithFrequencies/src/TrieFunctions.java @@ -281,15 +281,17 @@ public static List> mapPosition(Trie tr, List> words) return res; } + //! @description Retrieval of a sub-trie corresponding to a "word". //! @param tr a trie object //! @param word a list of strings + //! @param public static Trie retrieve(Trie tr, List word) { if (word == null || word.isEmpty()) { return tr; } else { - if (tr.getChildren() == null) { + if (tr.getChildren() == null || tr.getChildren().isEmpty() ) { return tr; } Trie pos = tr.getChildren().get(word.get(0)); @@ -301,16 +303,6 @@ public static Trie retrieve(Trie tr, List word) { } } - //! @description Optimization of retrieve over a list of words. - //! @param tr a trie object - //! @param words a list of lists of strings - public static List mapRetrieve(Trie tr, List> words) { - List res = new ArrayList<>(); - for (List s : words) { - res.add(retrieve(tr, s)); - } - return res; - } //! @description For a given trie finds if the retrievable part of a word is complete match. //! @param tr a trie object @@ -698,7 +690,7 @@ public static List nodeCounts(Trie tr) { Pair res = nodeCountsRec(tr, 0, 0); return new ArrayList() - {{ add(res.getKey() + res.getValue()); add(res.getKey()); add(res.getValue()); }}; + {{ add(res.getKey() + res.getValue()); add(res.getKey()); add(res.getValue()); }}; } //! @description Finding the counts of internal nodes and leaf nodes in a trie. @@ -804,7 +796,7 @@ public static Trie map( Trie tr, TrieNodeFunction preFunc, TrieNodeFunction pos res = tr; } - if ( tr.getChildren() == null || tr.getChildren().isEmpty()) { + if ( res.getChildren() == null || res.getChildren().isEmpty()) { resChildren = null; @@ -1063,4 +1055,79 @@ public static Trie removeByParetoFraction( Trie tr, double paretoFraction, boole return map( tr, removalObj, null ); } + + ///************************************************************** + /// Random choice functions + ///************************************************************** + + private static class ChildRandomChoice implements TrieNodeFunction { + ChildRandomChoice( boolean wsQ ) { weightedQ = wsQ; keyPath = new ArrayList(); } + + public boolean weightedQ; + public List keyPath; + + private Trie randomSelection( Collection children ) { + + // Compute the total weight of all items together + double totalWeight = 0.0d; + if ( weightedQ ) { + for (Trie elem : children) { + totalWeight += elem.getValue(); + } + } else { + for (Trie elem : children) { + totalWeight += 1.0; + } + } + // Now choose a random trie + Trie randomTrie = null; + double random = Math.random() * totalWeight; + int i = 0; + for ( Trie elem : children ) { + random -= elem.getValue(); + if( randomTrie == null ) { randomTrie = elem; } + if (random <= 0.0d) { + randomTrie = elem; + break; + } + i++; + } + + return randomTrie; + } + + public Trie apply( Trie tr ) { + + keyPath.add( tr.getKey() ); + + if( tr.getChildren() == null || tr.getChildren().isEmpty() ) { + return tr.clone(); + } else { + + Trie res = new Trie( tr.getKey(), tr.getValue() ); + Trie sel = randomSelection( tr.getChildren().values() ); + + Map resChildren = new HashMap(); + resChildren.put( sel.getKey(), sel ); + res.setChildren( resChildren ); + + return res; + } + } + } + + + //! @description Random choice of a root-to-leaf path. + //! @param tr a trie object + //! @param weightedQ should a weighted random choice be used or not + public static List randomChoice( Trie tr, boolean weightedQ ) { + + ChildRandomChoice selectObj = new ChildRandomChoice( weightedQ ); + + Trie res = map( tr, selectObj, null ); + + return selectObj.keyPath; + } + + } \ No newline at end of file