View Javadoc

1   /*
2    * Copyright 2006 - 2012 Christina Bohk and Roland Ewald
3    *  
4    * Licensed under the Apache License, Version 2.0 (the "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at 
7    *  
8    *  http://www.apache.org/licenses/LICENSE-2.0
9    *  
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License. 
15   */
16  package p3j.simulation.assignments.exhaustive;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.Comparator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import p3j.pppm.parameters.ParameterAssignment;
26  import p3j.pppm.parameters.ParameterInstance;
27  import p3j.pppm.sets.Set;
28  import p3j.pppm.sets.SetType;
29  
30  /**
31   * 
32   * Manages a {@link SetType} for the {@link ExhaustiveAssignmentGenerator}.
33   * Relies on a {@link SetManager} for each {@link Set} defined for its
34   * {@link SetType}.
35   * 
36   * Created: August 22, 2008
37   * 
38   * @author Christina Bohk
39   * @author Roland Ewald
40   * 
41   */
42  public class SetTypeManager {
43  
44  	/** List of sets associated with the Settype. */
45  	private List<SetManager> setManagers = new ArrayList<SetManager>();
46  
47  	/** The comparator for {@link SetManager} instances. */
48  	private SetManagerComparator smComp = new SetManagerComparator();
49  
50  	/**
51  	 * The history of past set assignment.
52  	 * 
53  	 * TODO: The first entries of the history can be deleted every now and then,
54  	 * this will otherwise cause memory problems for large projections.
55  	 */
56  	private List<SetAssignment> history = new ArrayList<SetAssignment>();
57  
58  	/**
59  	 * Default constructor.
60  	 * 
61  	 * @param setType
62  	 *          the Settype to be managed
63  	 */
64  	public SetTypeManager(SetType setType) {
65  		if (setType.getSets().isEmpty()) {
66  			throw new IllegalArgumentException("Fatal error: Settype '"
67  			    + setType.getName() + "' has no sets!");
68  		}
69  
70  		for (Set set : setType.getSets()) {
71  			if (set.isValid()) {
72  				setManagers.add(new SetManager(set, setType));
73  			}
74  		}
75  
76  		Collections.sort(setManagers, smComp);
77  		createAssignments(1);
78  	}
79  
80  	/**
81  	 * Gets i-th most probable assignment probability.
82  	 * 
83  	 * @param assignmentIndex
84  	 *          the desired index
85  	 * @return the probability of the i-th most probable assignment, -1 if there
86  	 *         is no i-th assignment
87  	 */
88  	public double getProbability(int assignmentIndex) {
89  
90  		if (assignmentIndex < history.size()) {
91  			return history.get(assignmentIndex).getProbability();
92  		}
93  
94  		if (!createAssignments(assignmentIndex + 1)) {
95  			return -1;
96  		}
97  		return history.get(assignmentIndex).getProbability();
98  	}
99  
100 	/**
101 	 * Gets i-th most probable assignment.
102 	 * 
103 	 * @param assignmentIndex
104 	 *          the desired index
105 	 * @return the i-th most probable assignment, null if nothing could be
106 	 *         found(i.e., there are no more possible assignments)
107 	 */
108 	public Map<ParameterInstance, ParameterAssignment> getAssignment(
109 	    int assignmentIndex) {
110 		if (assignmentIndex < history.size()) {
111 			return history.get(assignmentIndex).getAssignment();
112 		}
113 
114 		if (!createAssignments(assignmentIndex + 1)) {
115 			return null;
116 		}
117 		return history.get(assignmentIndex).getAssignment();
118 	}
119 
120 	/**
121 	 * Checks whether there are (at least) as many assignments as specified by the
122 	 * given index.
123 	 * 
124 	 * @param assignmentIndex
125 	 *          the desired assignment index
126 	 * @return true, if assignment with given index exists
127 	 */
128 	public boolean hasAssignment(int assignmentIndex) {
129 		if (assignmentIndex < history.size()) {
130 			return true;
131 		}
132 		return createAssignments(assignmentIndex + 1);
133 	}
134 
135 	/**
136 	 * Creates most probable assignments up to the given desired size of the
137 	 * history.
138 	 * 
139 	 * TODO: When history is truncated every once in a while, this method needs to
140 	 * be adapted. It now assumes that the history is growing constantly.
141 	 * 
142 	 * @param desiredSize
143 	 *          the desired size of the history
144 	 * @return true, if new assignments could be created, otherwise false
145 	 */
146 	protected final boolean createAssignments(int desiredSize) {
147 
148 		while (history.size() < desiredSize && !setManagers.isEmpty()) {
149 
150 			// Add assignment of top set to history
151 			history.add(new SetAssignment(setManagers.get(0).getCurrentMapping(),
152 			    setManagers.get(0).calcSetAssignmentProbability()));
153 
154 			// Create next assignment for top set (as this has already been used)
155 			boolean hasNext = setManagers.get(0).nextAssignment();
156 
157 			// Sort list or remove finished set
158 			if (!hasNext) {
159 				setManagers.remove(0);
160 				continue;
161 			}
162 			Collections.sort(setManagers, smComp);
163 		}
164 		return (history.size() == desiredSize);
165 	}
166 }
167 
168 /**
169  * Represents the assignment as generated by a {@link Set}. The probability is
170  * calculated by the {@link SetManager}, via
171  * {@link SetManager#calcSetAssignmentProbability()}.
172  * 
173  * Created: August 23, 2008
174  * 
175  * @author Christina Bohk
176  * @author Roland Ewald
177  * 
178  */
179 class SetAssignment {
180 
181 	/** The assignment. */
182 	private final Map<ParameterInstance, ParameterAssignment> assignment;
183 
184 	/** The probability of the assignment. */
185 	private final double probability;
186 
187 	/**
188 	 * Default constructor for set assignments.
189 	 * 
190 	 * @param assignm
191 	 *          the assignment chosen by the set
192 	 * @param prob
193 	 *          the probability of that assignment
194 	 */
195 	SetAssignment(Map<ParameterInstance, ParameterAssignment> assignm, Double prob) {
196 		assignment = assignm;
197 		probability = prob;
198 	}
199 
200 	public Map<ParameterInstance, ParameterAssignment> getAssignment() {
201 		return assignment;
202 	}
203 
204 	public double getProbability() {
205 		return probability;
206 	}
207 
208 }
209 
210 /**
211  * Comparator for set managers. Sorts {@link SetManager} instances in decreasing
212  * order of their set and assignment probabilities.
213  * 
214  * Created: August 23, 2008
215  * 
216  * @author Christina Bohk
217  * @author Roland Ewald
218  * 
219  */
220 class SetManagerComparator implements Comparator<SetManager>, Serializable {
221 
222 	/** The Constant serialVersionUID. */
223 	private static final long serialVersionUID = -7821654659763832183L;
224 
225 	@Override
226 	public int compare(SetManager man1, SetManager man2) {
227 		return Double.compare(man2.calcSetAssignmentProbability(),
228 		    man1.calcSetAssignmentProbability());
229 	}
230 
231 }