[1572] | 1 | package de.ugoe.cs.autoquest.tasktrees.alignment.matrix; |
---|
[1324] | 2 | |
---|
[1707] | 3 | import java.io.Serializable; |
---|
[1554] | 4 | import java.util.HashMap; |
---|
[1707] | 5 | import java.util.concurrent.ExecutorService; |
---|
| 6 | import java.util.concurrent.Executors; |
---|
| 7 | import java.util.concurrent.TimeUnit; |
---|
[1692] | 8 | import java.util.HashSet; |
---|
[1331] | 9 | import java.util.Iterator; |
---|
[1695] | 10 | import java.util.LinkedList; |
---|
| 11 | import java.util.logging.Level; |
---|
[1331] | 12 | |
---|
| 13 | import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; |
---|
[1553] | 14 | import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentHelpers; |
---|
[1578] | 15 | import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Constants; |
---|
[1695] | 16 | import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; |
---|
[1553] | 17 | import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; |
---|
[1554] | 18 | import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; |
---|
| 19 | import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; |
---|
[1695] | 20 | import de.ugoe.cs.util.console.Console; |
---|
[1324] | 21 | |
---|
[1702] | 22 | |
---|
| 23 | |
---|
[1707] | 24 | public class ObjectDistanceSubstitionMatrix implements SubstitutionMatrix,Serializable { |
---|
[1324] | 25 | |
---|
[1707] | 26 | /** |
---|
| 27 | * |
---|
| 28 | */ |
---|
| 29 | private static final long serialVersionUID = -4253258274617754083L; |
---|
[1695] | 30 | private HashMap<Integer, Integer> idmapping; |
---|
[1702] | 31 | private ITriangleMatrix matrix; |
---|
[1692] | 32 | private HashSet<ITask> uniqueTasks; |
---|
[1702] | 33 | private float gapPenalty; |
---|
[1676] | 34 | private int index = 0; |
---|
[1695] | 35 | private HashMap<Integer, LinkedList<IEventTaskInstance>> etisOfTasks; |
---|
| 36 | private boolean calculateNonTaskInstances = true; |
---|
[1702] | 37 | private int firstRoundMaxIndex = 0; |
---|
[1695] | 38 | |
---|
[1568] | 39 | private double positiveThreshold; |
---|
[1695] | 40 | |
---|
[1698] | 41 | public ObjectDistanceSubstitionMatrix( |
---|
[1702] | 42 | float positiveThreshold, int gapPenalty, |
---|
| 43 | boolean calculateNonTaskInstances) { |
---|
[1558] | 44 | this.positiveThreshold = positiveThreshold; |
---|
[1554] | 45 | idmapping = new HashMap<Integer, Integer>(); |
---|
[1695] | 46 | etisOfTasks = new HashMap<Integer, LinkedList<IEventTaskInstance>>(); |
---|
[1620] | 47 | this.gapPenalty = gapPenalty; |
---|
[1695] | 48 | this.calculateNonTaskInstances = calculateNonTaskInstances; |
---|
| 49 | |
---|
[1324] | 50 | } |
---|
| 51 | |
---|
[1702] | 52 | public float getGapPenalty() { |
---|
[1555] | 53 | return gapPenalty; |
---|
[1324] | 54 | } |
---|
[1695] | 55 | |
---|
[1702] | 56 | public void setGapPenalty(float gapPenalty) { |
---|
[1615] | 57 | this.gapPenalty = gapPenalty; |
---|
| 58 | } |
---|
[1324] | 59 | |
---|
[1699] | 60 | //TODO: Merge this with updateEventTaskInstances |
---|
[1695] | 61 | private void searchEventTaskInstances() { |
---|
| 62 | for (Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { |
---|
| 63 | ITask task = it.next(); |
---|
| 64 | if (!(task instanceof IEventTask)) { |
---|
| 65 | EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); |
---|
| 66 | task.accept(etlg); |
---|
| 67 | LinkedList<IEventTaskInstance> eventTaskInstances = etlg |
---|
| 68 | .getEventlist(); |
---|
| 69 | etisOfTasks.put(task.getId(), eventTaskInstances); |
---|
| 70 | } |
---|
| 71 | } |
---|
| 72 | } |
---|
[1698] | 73 | |
---|
[1699] | 74 | public void updateEventTaskInstances(LinkedList<ITask> newTasks){ |
---|
| 75 | for (Iterator<ITask> it = newTasks.iterator();it.hasNext();) { |
---|
| 76 | ITask task = it.next(); |
---|
| 77 | if (!(task instanceof IEventTask)) { |
---|
| 78 | EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); |
---|
| 79 | task.accept(etlg); |
---|
| 80 | LinkedList<IEventTaskInstance> eventTaskInstances = etlg |
---|
| 81 | .getEventlist(); |
---|
| 82 | etisOfTasks.put(task.getId(), eventTaskInstances); |
---|
| 83 | } |
---|
| 84 | } |
---|
| 85 | } |
---|
| 86 | |
---|
[1698] | 87 | //Just Calculate the distance between the new tasks and the matrix. |
---|
| 88 | public void update(LinkedList<ITask> newTasks) { |
---|
[1702] | 89 | |
---|
[1698] | 90 | if (this.calculateNonTaskInstances) { |
---|
[1702] | 91 | try { |
---|
| 92 | matrix.increaseSize(newTasks.size()); |
---|
| 93 | System.out.println("Subsitution matrix size is now " + matrix.size()*(matrix.size()+1)/2); |
---|
| 94 | Console.traceln(Level.INFO, "searching EventTasks in Tasks"); |
---|
| 95 | } catch (Exception e) { |
---|
| 96 | Console.logException(e); |
---|
| 97 | } |
---|
[1699] | 98 | this.updateEventTaskInstances(newTasks); |
---|
[1702] | 99 | |
---|
[1707] | 100 | int nThreads = de.ugoe.cs.autoquest.tasktrees.temporalrelation.SequenceForTaskDetectionRuleAlignment.nThreads; |
---|
| 101 | ExecutorService executor = Executors.newFixedThreadPool(nThreads); |
---|
| 102 | |
---|
| 103 | |
---|
| 104 | int count=0; |
---|
| 105 | int size=uniqueTasks.size(); |
---|
| 106 | |
---|
| 107 | for(Iterator<ITask> it = newTasks.iterator();it.hasNext();) { |
---|
| 108 | ITask task1 = it.next(); |
---|
| 109 | for (Iterator<ITask> jt = uniqueTasks.iterator(); jt.hasNext();) { |
---|
| 110 | ITask task2 = jt.next(); |
---|
| 111 | Runnable worker = new DistanceCalculator(task1,task2); |
---|
| 112 | executor.execute(worker); |
---|
[1698] | 113 | } |
---|
| 114 | } |
---|
[1707] | 115 | |
---|
| 116 | executor.shutdown(); |
---|
| 117 | // Wait until all threads are finish |
---|
| 118 | try { |
---|
| 119 | executor.awaitTermination(60, TimeUnit.MINUTES); |
---|
| 120 | } catch (InterruptedException e) { |
---|
| 121 | e.printStackTrace(); |
---|
| 122 | } |
---|
| 123 | System.out.println("Finished all threads"); |
---|
| 124 | |
---|
[1698] | 125 | } |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | public void generate(HashSet<ITask> uniqueTasks) { |
---|
| 129 | this.uniqueTasks = uniqueTasks; |
---|
[1695] | 130 | if (this.calculateNonTaskInstances) { |
---|
[1702] | 131 | matrix = new DynamicTriangleMatrix(uniqueTasks.size() + 1); |
---|
[1698] | 132 | Console.traceln(Level.INFO, "searching EventTasks in Tasks"); |
---|
[1695] | 133 | searchEventTaskInstances(); |
---|
| 134 | } |
---|
[1702] | 135 | else{ |
---|
| 136 | matrix = new StaticTriangleMatrix(uniqueTasks.size()+1); |
---|
| 137 | } |
---|
| 138 | matrix.initialize(0); |
---|
[1707] | 139 | |
---|
| 140 | |
---|
| 141 | int nThreads = de.ugoe.cs.autoquest.tasktrees.temporalrelation.SequenceForTaskDetectionRuleAlignment.nThreads; |
---|
| 142 | Console.traceln(Level.INFO, "calculating distances with " + nThreads + " threads"); |
---|
| 143 | ExecutorService executor = Executors.newFixedThreadPool(nThreads); |
---|
| 144 | |
---|
| 145 | |
---|
| 146 | int count=0; |
---|
| 147 | int size=uniqueTasks.size(); |
---|
[1692] | 148 | for (Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) { |
---|
| 149 | ITask task1 = it.next(); |
---|
[1707] | 150 | count++; |
---|
| 151 | if((size%count*100)==0) { |
---|
| 152 | Console.traceln(Level.INFO,(Math.round((float) count/size*100))+ "%"); |
---|
| 153 | } |
---|
[1692] | 154 | for (Iterator<ITask> jt = uniqueTasks.iterator(); jt.hasNext();) { |
---|
| 155 | ITask task2 = jt.next(); |
---|
[1707] | 156 | Runnable worker = new DistanceCalculator(task1,task2); |
---|
| 157 | executor.execute(worker); |
---|
[1554] | 158 | } |
---|
[1331] | 159 | } |
---|
[1707] | 160 | executor.shutdown(); |
---|
| 161 | // Wait until all threads are finish |
---|
| 162 | try { |
---|
| 163 | executor.awaitTermination(60, TimeUnit.MINUTES); |
---|
| 164 | } catch (InterruptedException e) { |
---|
| 165 | e.printStackTrace(); |
---|
| 166 | } |
---|
| 167 | System.out.println("Finished all threads"); |
---|
| 168 | |
---|
[1702] | 169 | this.firstRoundMaxIndex=index; |
---|
[1324] | 170 | } |
---|
[1698] | 171 | |
---|
[1702] | 172 | |
---|
[1707] | 173 | |
---|
[1698] | 174 | |
---|
[1702] | 175 | |
---|
[1677] | 176 | |
---|
[1696] | 177 | private float distanceBetweenTaskAndInstance(ITask task1, |
---|
[1695] | 178 | IEventTaskInstance eti1) { |
---|
| 179 | if (this.calculateNonTaskInstances) { |
---|
| 180 | float tmpDistance = 0; |
---|
[1699] | 181 | //System.out.println(etisOfTasks); |
---|
[1695] | 182 | LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks |
---|
| 183 | .get(task1.getId()); |
---|
| 184 | for (Iterator<IEventTaskInstance> it = eventTaskInstances |
---|
| 185 | .iterator(); it.hasNext();) { |
---|
| 186 | IEventTaskInstance eti2 = it.next(); |
---|
[1707] | 187 | //int taskId1 = eti1.getTask().getId(); |
---|
| 188 | //int taskId2 = eti2.getTask().getId(); |
---|
| 189 | //if (scoreExists(taskId1, taskId2)) { |
---|
| 190 | // tmpDistance += getScore(taskId1, taskId2); |
---|
| 191 | //} else { |
---|
[1696] | 192 | float dist = distanceBetweenInstances(eti1, eti2); |
---|
[1695] | 193 | matrix.set(getIndex(eti1), getIndex(eti2), dist); |
---|
| 194 | tmpDistance += dist; |
---|
[1707] | 195 | //} |
---|
[1695] | 196 | } |
---|
| 197 | return tmpDistance / eventTaskInstances.size(); |
---|
| 198 | } else { |
---|
| 199 | return 0; |
---|
| 200 | } |
---|
[1677] | 201 | } |
---|
[1695] | 202 | |
---|
[1707] | 203 | //public boolean scoreExists(int id, int id2) { |
---|
[1698] | 204 | //return idmapping.containsKey(id) && idmapping.containsKey(id2); |
---|
[1707] | 205 | // return false; |
---|
| 206 | //} |
---|
[1677] | 207 | |
---|
[1696] | 208 | private float distanceBetweenTasks(ITask task1, ITask task2) { |
---|
[1695] | 209 | if (this.calculateNonTaskInstances) { |
---|
| 210 | LinkedList<IEventTaskInstance> eventTaskInstances = etisOfTasks |
---|
| 211 | .get(task1.getId()); |
---|
| 212 | float tmpDistance = 0; |
---|
| 213 | for (Iterator<IEventTaskInstance> it = eventTaskInstances |
---|
| 214 | .iterator(); it.hasNext();) { |
---|
| 215 | IEventTaskInstance eti1 = it.next(); |
---|
| 216 | tmpDistance += distanceBetweenTaskAndInstance(task2, eti1); |
---|
| 217 | } |
---|
[1677] | 218 | |
---|
[1695] | 219 | return tmpDistance / eventTaskInstances.size(); |
---|
| 220 | } else { |
---|
| 221 | return 0; |
---|
| 222 | } |
---|
| 223 | } |
---|
| 224 | |
---|
[1707] | 225 | synchronized private int getIndex(ITask task) { |
---|
[1695] | 226 | int tempindex = -1; |
---|
| 227 | |
---|
| 228 | if (!idmapping.containsKey(task.getId())) { |
---|
[1707] | 229 | |
---|
[1677] | 230 | idmapping.put(task.getId(), index); |
---|
| 231 | tempindex = index; |
---|
| 232 | index++; |
---|
[1695] | 233 | } else { |
---|
[1677] | 234 | tempindex = idmapping.get(task.getId()); |
---|
| 235 | } |
---|
[1695] | 236 | |
---|
[1677] | 237 | return tempindex; |
---|
| 238 | } |
---|
[1695] | 239 | |
---|
[1707] | 240 | synchronized private int getIndex(IEventTaskInstance eti) { |
---|
[1676] | 241 | int tempindex = -1; |
---|
[1695] | 242 | if (!idmapping.containsKey(eti.getTask().getId())) { |
---|
[1676] | 243 | idmapping.put(eti.getTask().getId(), index); |
---|
| 244 | tempindex = index; |
---|
| 245 | index++; |
---|
[1695] | 246 | } else { |
---|
[1676] | 247 | tempindex = idmapping.get(eti.getTask().getId()); |
---|
| 248 | } |
---|
| 249 | return tempindex; |
---|
[1677] | 250 | }; |
---|
[1695] | 251 | |
---|
[1696] | 252 | private float distanceBetweenInstances(IEventTaskInstance eti1, |
---|
[1695] | 253 | IEventTaskInstance eti2) { |
---|
[1676] | 254 | IGUIElement first = (IGUIElement) eti1.getEvent().getTarget(); |
---|
| 255 | IGUIElement second = (IGUIElement) eti2.getEvent().getTarget(); |
---|
[1695] | 256 | float distance = -1 * AlignmentHelpers.distanceBetween(first, second); |
---|
[1676] | 257 | distance += positiveThreshold; |
---|
| 258 | return distance; |
---|
| 259 | } |
---|
[1695] | 260 | |
---|
| 261 | public String toString() { |
---|
[1558] | 262 | return matrix.toString(); |
---|
| 263 | } |
---|
[1554] | 264 | |
---|
[1702] | 265 | public float getScore(int taskId1, int taskId2) { |
---|
[1695] | 266 | if (taskId1 == Constants.GAP_SYMBOL |
---|
| 267 | || taskId1 == Constants.UNMATCHED_SYMBOL |
---|
| 268 | || taskId2 == Constants.GAP_SYMBOL |
---|
| 269 | || taskId2 == Constants.UNMATCHED_SYMBOL) { |
---|
[1702] | 270 | return 0; |
---|
| 271 | } else if(this.calculateNonTaskInstances==false && |
---|
| 272 | (taskId1>this.firstRoundMaxIndex |
---|
| 273 | || taskId2>this.firstRoundMaxIndex)) { |
---|
| 274 | return 0; |
---|
[1695] | 275 | } else { |
---|
[1687] | 276 | Integer first = idmapping.get(taskId1); |
---|
| 277 | Integer second = idmapping.get(taskId2); |
---|
[1695] | 278 | return matrix.get(first, second); |
---|
[1578] | 279 | } |
---|
[1695] | 280 | |
---|
[1554] | 281 | } |
---|
[1707] | 282 | |
---|
| 283 | |
---|
| 284 | private class DistanceCalculator implements Runnable { |
---|
[1554] | 285 | |
---|
[1707] | 286 | private ITask task1; |
---|
| 287 | private ITask task2; |
---|
| 288 | |
---|
| 289 | public DistanceCalculator(ITask task1, ITask task2){ |
---|
| 290 | this.task1 = task1; |
---|
| 291 | this.task2 = task2; |
---|
| 292 | } |
---|
| 293 | |
---|
| 294 | |
---|
| 295 | @Override |
---|
| 296 | public void run() { |
---|
| 297 | computeDistance(task1,task2); |
---|
| 298 | } |
---|
| 299 | private void computeDistance(ITask task1, ITask task2) { |
---|
| 300 | int index1 = -1; |
---|
| 301 | int index2 = -1; |
---|
| 302 | float distance = 0; |
---|
| 303 | ITaskInstance ti1 = null; |
---|
| 304 | ITaskInstance ti2 = null; |
---|
| 305 | // We just need to the first instance here |
---|
| 306 | if (task1.getInstances().size() > 0) { |
---|
| 307 | ti1 = (ITaskInstance) task1.getInstances().iterator() |
---|
| 308 | .next(); |
---|
| 309 | } |
---|
| 310 | if (task2.getInstances().size() > 0) { |
---|
| 311 | ti2 = (ITaskInstance) task2.getInstances().iterator() |
---|
| 312 | .next(); |
---|
| 313 | } |
---|
| 314 | IEventTaskInstance eti1 = null; |
---|
| 315 | IEventTaskInstance eti2 = null; |
---|
| 316 | |
---|
| 317 | if (ti1 instanceof IEventTaskInstance |
---|
| 318 | && ti2 instanceof IEventTaskInstance) { |
---|
| 319 | eti1 = (IEventTaskInstance) ti1; |
---|
| 320 | index1 = getIndex(eti1); |
---|
| 321 | eti2 = (IEventTaskInstance) ti2; |
---|
| 322 | index2 = getIndex(eti2); |
---|
| 323 | distance = distanceBetweenInstances(eti1, eti2); |
---|
| 324 | } else if (ti1 instanceof IEventTaskInstance |
---|
| 325 | && !(ti2 instanceof IEventTaskInstance)) { |
---|
| 326 | task1 = ((ITaskInstance) ti1).getTask(); |
---|
| 327 | index2 = getIndex(task2); |
---|
| 328 | eti1 = (IEventTaskInstance) ti1; |
---|
| 329 | index1 = getIndex(eti1); |
---|
| 330 | distance = distanceBetweenTaskAndInstance(task2, eti1); |
---|
| 331 | } else if (!(ti1 instanceof IEventTaskInstance) |
---|
| 332 | && ti2 instanceof IEventTaskInstance) { |
---|
| 333 | index1 = getIndex(task1); |
---|
| 334 | eti2 = (IEventTaskInstance) ti2; |
---|
| 335 | index2 = getIndex(eti2); |
---|
| 336 | distance = distanceBetweenTaskAndInstance(task1, eti2); |
---|
| 337 | } else if (!(ti1 instanceof IEventTaskInstance) |
---|
| 338 | && !(ti2 instanceof IEventTaskInstance)) { |
---|
| 339 | index1 = getIndex(task1); |
---|
| 340 | index2 = getIndex(task2); |
---|
| 341 | distance = distanceBetweenTasks(task1, task2); |
---|
| 342 | } else { |
---|
| 343 | System.out.println("Unknown error"); |
---|
| 344 | } |
---|
| 345 | matrix.set(index1, index2, distance); |
---|
| 346 | //return distance; |
---|
| 347 | |
---|
| 348 | } |
---|
| 349 | |
---|
| 350 | |
---|
| 351 | } |
---|
| 352 | |
---|
[1324] | 353 | } |
---|