source: trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/ModelFlattener.java @ 927

Last change on this file since 927 was 927, checked in by sherbold, 12 years ago
  • added copyright under the Apache License, Version 2.0
  • Property svn:mime-type set to text/plain
File size: 5.7 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.usageprofiles;
16
17import java.util.LinkedList;
18import java.util.List;
19import java.util.Random;
20
21import de.ugoe.cs.autoquest.eventcore.Event;
22import de.ugoe.cs.autoquest.eventcore.StringEventType;
23
24/**
25 * <p>
26 * This class provides functions to create flattened first-order Markov models from
27 * {@link HighOrderMarkovModel}s and {@link PredictionByPartialMatch} models through state
28 * splitting.
29 * </p>
30 * <p>
31 * If possible, the normal high-order markov model should be used, as the Events may be broken by
32 * the flattener, as, e.g., the information {@link ReplayableEvent}s contain is not preserved.
33 * </p>
34 *
35 * @author Steffen Herbold
36 * @version 1.0
37 */
38public class ModelFlattener {
39
40    private static final String EVENT_SEPARATOR = "-=-";
41
42    Trie<Event> firstOrderTrie;
43
44    /**
45     * <p>
46     * Takes a {@link HighOrderMarkovModel} and returns a {@link FirstOrderMarkovModel} that
47     * conserves the high-order memory through state splitting.
48     * </p>
49     *
50     * @param model
51     *            model that is flattened
52     * @return flattened first-order Markov model
53     */
54    public FirstOrderMarkovModel flattenHighOrderMarkovModel(HighOrderMarkovModel model) {
55        int markovOrder = model.trieOrder - 1;
56        FirstOrderMarkovModel firstOrderModel = new FirstOrderMarkovModel(new Random());
57        firstOrderModel.trieOrder = 2;
58        if (markovOrder == 1) {
59            firstOrderModel.trie = new Trie<Event>(model.trie);
60            firstOrderModel.trieOrder = 2;
61        }
62        else {
63            firstOrderTrie = new Trie<Event>();
64            TrieNode<Event> rootNode = model.trie.find(null);
65            generateFirstOrderTrie(rootNode, new LinkedList<String>(), markovOrder);
66            firstOrderTrie.updateKnownSymbols();
67            firstOrderModel.trie = firstOrderTrie;
68        }
69
70        return firstOrderModel;
71    }
72
73    /**
74     * <p>
75     * <b>This method is not available yet and always return null!</b>
76     * </p>
77     * <p>
78     * Takes a {@link PredictionByPartialMatch} model and returns a {@link FirstOrderMarkovModel}
79     * that conserves the high-order memory through state splitting.
80     * </p>
81     *
82     * @param model
83     *            model that is flattened
84     * @return flattened first-order Markov model
85     */
86    public FirstOrderMarkovModel flattenPredictionByPartialMatch(PredictionByPartialMatch model) {
87        // TODO implement method
88        return null;
89    }
90
91    /**
92     * <p>
93     * Converts all nodes of the given depth into first-order node through state-splitting. For each
94     * node at the given depth a new node is created and appropriate transitions will be added.
95     * </p>
96     * <p>
97     * This method traverses through the tree recursively. If the recursion reaches the desired
98     * depth in the tree, node are added.
99     * </p>
100     *
101     * @param currentNode
102     *            node whose sub-trie is currently traversed
103     * @param parentIDs
104     *            ID strings of the ancestors of the currentNode
105     * @param depth
106     *            depth to go - NOT the current depth.
107     */
108    private void generateFirstOrderTrie(TrieNode<Event> currentNode,
109                                        List<String> parentIDs,
110                                        int depth)
111    {
112        for (TrieNode<Event> child : currentNode.getChildren()) {
113            String currentId = child.getSymbol().getId();
114            if (depth > 1) {
115                List<String> childParentIDs = new LinkedList<String>(parentIDs);
116                childParentIDs.add(currentId);
117                generateFirstOrderTrie(child, childParentIDs, depth - 1);
118
119            }
120            else {
121                StringBuilder firstOrderID = new StringBuilder();
122                for (String parentID : parentIDs) {
123                    firstOrderID.append(parentID + EVENT_SEPARATOR);
124                }
125                firstOrderID.append(currentId);
126                TrieNode<Event> firstOrderNode =
127                    firstOrderTrie.getChildCreate(new Event(new StringEventType(firstOrderID
128                        .toString())));
129                firstOrderNode.setCount(child.getCount());
130                for (TrieNode<Event> transitionChild : child.getChildren()) {
131                    StringBuilder transitionID = new StringBuilder();
132                    for (String parentID : parentIDs.subList(1, parentIDs.size())) {
133                        transitionID.append(parentID + EVENT_SEPARATOR);
134                    }
135                    transitionID.append(currentId + EVENT_SEPARATOR);
136                    transitionID.append(transitionChild.getSymbol().getId());
137                    TrieNode<Event> firstOrderTransitionChild =
138                        firstOrderNode.getChildCreate(new Event(new StringEventType(transitionID
139                            .toString())));
140                    firstOrderTransitionChild.setCount(transitionChild.getCount());
141                }
142            }
143        }
144    }
145}
Note: See TracBrowser for help on using the repository browser.