/* * */ package de.ugoe.cs.autoquest.tasktrees.alignment.matrix; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.logging.Level; import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentHelpers; import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Constants; import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; import de.ugoe.cs.util.console.Console; // TODO: Auto-generated Javadoc /** * The Class ObjectDistanceSubstitionMatrix. */ public class ObjectDistanceSubstitionMatrix implements SubstitutionMatrix, Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = -4253258274617754083L; /** The idmapping. */ private final HashMap idmapping; /** The matrix. */ private ITriangleMatrix matrix; /** The unique tasks. */ private Collection uniqueTasks; /** The gap penalty. */ private float gapPenalty; /** The index. */ private int index = 0; /** The etis of tasks. */ private final HashMap> etisOfTasks; /** The calculate non task instances. */ private boolean calculateNonEventTaskInstances = false; /** The first round max index. */ private int firstRoundMaxIndex = 0; /** The positive threshold. */ private final double positiveThreshold; /** * Instantiates a new object distance substition matrix. * * @param positiveThreshold the positive threshold * @param gapPenalty the gap penalty * @param calculateNonTaskInstances the calculate non task instances */ public ObjectDistanceSubstitionMatrix(float positiveThreshold, int gapPenalty, boolean calculateNonTaskInstances) { this.positiveThreshold = positiveThreshold; idmapping = new HashMap(); etisOfTasks = new HashMap>(); this.gapPenalty = gapPenalty; this.calculateNonEventTaskInstances = calculateNonTaskInstances; } /** * Compute distance. * * @param task1 the task1 * @param task2 the task2 */ private void computeDistance(ITask task1, ITask task2) { int index1 = -1; int index2 = -1; float distance = 0; ITaskInstance ti1 = null; ITaskInstance ti2 = null; // We just need to the first instance here if (task1.getInstances().size() > 0) { ti1 = task1.getInstances().iterator().next(); } if (task2.getInstances().size() > 0) { ti2 = task2.getInstances().iterator().next(); } IEventTaskInstance eti1 = null; IEventTaskInstance eti2 = null; if ((ti1 instanceof IEventTaskInstance) && (ti2 instanceof IEventTaskInstance)) { eti1 = (IEventTaskInstance) ti1; index1 = getIndex(eti1); eti2 = (IEventTaskInstance) ti2; index2 = getIndex(eti2); distance = distanceBetweenInstances(eti1, eti2); } else if ((ti1 instanceof IEventTaskInstance) && !(ti2 instanceof IEventTaskInstance)) { task1 = ti1.getTask(); index2 = getIndex(task2); eti1 = (IEventTaskInstance) ti1; index1 = getIndex(eti1); distance = distanceBetweenTaskAndInstance(task2, eti1)-3; } else if (!(ti1 instanceof IEventTaskInstance) && (ti2 instanceof IEventTaskInstance)) { index1 = getIndex(task1); eti2 = (IEventTaskInstance) ti2; index2 = getIndex(eti2); distance = distanceBetweenTaskAndInstance(task1, eti2); } else if (!(ti1 instanceof IEventTaskInstance) && !(ti2 instanceof IEventTaskInstance)) { index1 = getIndex(task1); index2 = getIndex(task2); distance = distanceBetweenTasks(task1, task2)-3; } else { System.out.println("Unknown error"); } matrix.set(index1, index2, distance); } /** * Distance between instances. * * @param eti1 the eti1 * @param eti2 the eti2 * @return the float */ private float distanceBetweenInstances(IEventTaskInstance eti1, IEventTaskInstance eti2) { final IGUIElement first = (IGUIElement) eti1.getEvent().getTarget(); final IGUIElement second = (IGUIElement) eti2.getEvent().getTarget(); float distance = -1 * AlignmentHelpers.distanceBetween(first, second); distance += positiveThreshold; return distance; } /** * Distance between task and instance. * * @param task1 the task1 * @param eti1 the eti1 * @return the float */ private float distanceBetweenTaskAndInstance(ITask task1, IEventTaskInstance eti1) { if (this.calculateNonEventTaskInstances) { float tmpDistance = 0; final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); task1.accept(etlg); final LinkedList eventTaskInstances = etlg .getEventlist(); for (final Iterator it = eventTaskInstances .iterator(); it.hasNext();) { final IEventTaskInstance eti2 = it.next(); // int taskId1 = eti1.getTask().getId(); // int taskId2 = eti2.getTask().getId(); // if (scoreExists(taskId1, taskId2)) { // tmpDistance += getScore(taskId1, taskId2); // } else { final float dist = distanceBetweenInstances(eti1, eti2); matrix.set(getIndex(eti1), getIndex(eti2), dist); tmpDistance += dist; // } } return tmpDistance / eventTaskInstances.size(); } else { return 0; } } /** * Distance between tasks. * * @param task1 the task1 * @param task2 the task2 * @return the float */ private float distanceBetweenTasks(ITask task1, ITask task2) { if (this.calculateNonEventTaskInstances) { final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); task1.accept(etlg); final LinkedList eventTaskInstances = etlg .getEventlist(); float tmpDistance = 0; for (final Iterator it = eventTaskInstances .iterator(); it.hasNext();) { final IEventTaskInstance eti1 = it.next(); tmpDistance += distanceBetweenTaskAndInstance(task2, eti1); } return tmpDistance / eventTaskInstances.size(); } else { return 0; } } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.SubstitutionMatrix#generate(java.util.HashSet) */ @Override public void generate(Collection uniqueTasks) { this.uniqueTasks = uniqueTasks; if (this.calculateNonEventTaskInstances) { matrix = new PreallocatedDynamicTriangleMatrix(uniqueTasks.size() + 1); Console.traceln(Level.INFO, "searching EventTasks in Tasks"); //searchEventTaskInstances(); } else { matrix = new StaticTriangleMatrix(uniqueTasks.size() + 1); } matrix.initialize(0); //int count = 0; //final int size = uniqueTasks.size(); for (final Iterator it = uniqueTasks.iterator(); it.hasNext();) { final ITask task1 = it.next(); //count++; //if (((count % (size / 100)) == 0)) { // Console.traceln(Level.INFO, // (Math.round(((float) count / size) * 100)) + "%"); //} for (final Iterator jt = uniqueTasks.iterator(); jt .hasNext();) { final ITask task2 = jt.next(); computeDistance(task1, task2); } } this.firstRoundMaxIndex = index; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.SubstitutionMatrix#getGapPenalty() */ @Override public float getGapPenalty() { return gapPenalty; } /** * Gets the index. * * @param eti the eti * @return the index */ synchronized private int getIndex(IEventTaskInstance eti) { int tempindex = -1; if (!idmapping.containsKey(eti.getTask().getId())) { idmapping.put(eti.getTask().getId(), index); tempindex = index; index++; } else { tempindex = idmapping.get(eti.getTask().getId()); } return tempindex; } /** * Gets the index. * * @param task the task * @return the index */ synchronized private int getIndex(ITask task) { int tempindex = -1; if (!idmapping.containsKey(task.getId())) { idmapping.put(task.getId(), index); tempindex = index; index++; } else { tempindex = idmapping.get(task.getId()); } return tempindex; } // public boolean scoreExists(int id, int id2) { // return idmapping.containsKey(id) && idmapping.containsKey(id2); // return false; // } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.SubstitutionMatrix#getScore(int, int) */ @Override public float getScore(int taskId1, int taskId2) { if ((taskId1 == Constants.GAP_SYMBOL) || (taskId1 == Constants.UNMATCHED_SYMBOL) || (taskId2 == Constants.GAP_SYMBOL) || (taskId2 == Constants.UNMATCHED_SYMBOL)) { return 0; } else if ((this.calculateNonEventTaskInstances == false) && ((taskId1 > this.firstRoundMaxIndex) || (taskId2 > this.firstRoundMaxIndex))) { return 0; } else { final Integer first = idmapping.get(taskId1); final Integer second = idmapping.get(taskId2); return matrix.get(first, second); } } // TODO: Merge this with updateEventTaskInstances /** * Search event task instances. */ private void searchEventTaskInstances() { for (final Iterator it = uniqueTasks.iterator(); it.hasNext();) { final ITask task = it.next(); if (!(task instanceof IEventTask)) { final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); task.accept(etlg); final LinkedList eventTaskInstances = etlg .getEventlist(); etisOfTasks.put(task.getId(), eventTaskInstances); } } } /** * Sets the gap penalty. * * @param gapPenalty the new gap penalty */ public void setGapPenalty(float gapPenalty) { this.gapPenalty = gapPenalty; }; /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return matrix.toString(); } // Just Calculate the distance between the new tasks and the matrix. /* (non-Javadoc) * @see de.ugoe.cs.autoquest.tasktrees.alignment.matrix.SubstitutionMatrix#update(java.util.LinkedList) */ @Override public void update(LinkedList newTasks) { if (this.calculateNonEventTaskInstances) { try { matrix.increaseSize(newTasks.size()); System.out.println("Subsitution matrix size is now " + ((matrix.size() * (matrix.size() + 1)) / 2)); Console.traceln(Level.INFO, "searching EventTasks in Tasks"); } catch (final Exception e) { Console.logException(e); } //this.updateEventTaskInstances(newTasks); for (final Iterator it = newTasks.iterator(); it.hasNext();) { final ITask task1 = it.next(); for (final Iterator jt = uniqueTasks.iterator(); jt .hasNext();) { final ITask task2 = jt.next(); computeDistance(task1, task2); } } } } /** * Update event task instances. * * @param newTasks the new tasks */ public void updateEventTaskInstances(LinkedList newTasks) { for (final Iterator it = newTasks.iterator(); it.hasNext();) { final ITask task = it.next(); if (!(task instanceof IEventTask)) { final EventTaskInstancesListGenerator etlg = new EventTaskInstancesListGenerator(); task.accept(etlg); final LinkedList eventTaskInstances = etlg .getEventlist(); etisOfTasks.put(task.getId(), eventTaskInstances); } } } }