コード例 #1
0
  /**
   * Build an initial marking for a given heuristics net.
   *
   * @param net an enhanced heuristics net to which the initial marking must be built.
   * @throws java.lang.NullPointerException whenever the net has disconnected elements. An element
   *     is disconnected when its INPUT or OUTPUT set is null.
   */
  public MarkingHeuristicsNet(HeuristicsNet net, Random generator) throws NullPointerException {

    this.generator = generator;
    size = net.size();
    hNet = net;
    // checking if all input and output sets are DIFFERENT from null...
    for (int i = 0; i < size; i++) {
      if (hNet.getInputSet(i) == null || hNet.getOutputSet(i) == null) {
        throw new NullPointerException("Net has disconnected elements!!");
      }
    }
    createMarking();
  }
コード例 #2
0
  /** Creates an initial marking. */
  private void createMarking() {

    HNSet set = null;

    marking = null;
    marking = new HashMap[size];

    // Building the marking data structure. This structure is an array of
    // hashmaps.
    // For a given hashmap, we have:
    // - Key: Integer = element
    // - Value: HashMap = subsets + the number of tokens associated to them
    // The idea is to keep track of which tasks fired and the number of
    // tokens at their output subsets.
    // Initially, the number of tokens is 0.
    for (int i = 0; i < size; i++) {

      set = hNet.getOutputSet(i);
      HashMap map = new HashMap();
      for (int j = 0; j < set.size(); j++) {
        map.put(set.get(j), new Integer(0));
      }
      marking[i] = map;
    }

    auxMapping = new MappingToSubsets(hNet);
    this.reset();
  }
コード例 #3
0
  private HNSubSet getTasksWithEmptyOutputPlaces(int task) {

    HNSubSet tasksEmptyOutPlaces;
    HNSubSet inputTasks;

    int inputTask;
    HNSet outputSubsets;

    inputTasks = hNet.getAllElementsInputSet(task);

    tasksEmptyOutPlaces = new HNSubSet();

    for (int iInputTasks = 0; iInputTasks < inputTasks.size(); iInputTasks++) {
      inputTask = inputTasks.get(iInputTasks);
      outputSubsets = auxMapping.getRelatedSubsets(task, inputTask);
      if (outputSubsets != null) {
        if (!allSubsetsAreMarked(inputTask, outputSubsets)) {
          tasksEmptyOutPlaces.add(inputTask);
        }
      } else {
        tasksEmptyOutPlaces.add(inputTask);
      }
    }

    return tasksEmptyOutPlaces;
  }
コード例 #4
0
  /**
   * Adds tokens to the output places of a given element
   *
   * @param element element to fire
   */
  private void addTokensOutputPlaces(int element) {

    /*
     * Pseudo-code: 1. Retrieve all elements in the OUT set of 'element' 2.
     * Increase the number of tokens for every output element
     */

    HNSet set = null;

    // update global counter for number of tokens
    // note that OR-situations count as a single token.

    set = hNet.getOutputSet(element);
    if (set.size() == 0) { // element is connected to the end place
      numberTokens++;
      endPlace++;
    } else {
      numberTokens += set.size();
    }

    // update marking...
    for (int iSet = 0; iSet < set.size(); iSet++) {
      increaseNumberTokens(element, set.get(iSet));
    }
  }
コード例 #5
0
  /**
   * Removes one token from the marked output places (subsets) of the tasks in <i>tasks</i> that
   * contain <i>element</i>.
   *
   * @param element element to fire
   * @param tasks whose output places point to element
   */
  private void removeTokensOutputPlaces(int element, HNSubSet tasks) {

    HNSubSet subset = null;
    HNSet subsets = null;

    Integer tokens = null;
    int taskToFire;
    int task;

    // Checking if element is a start element
    if (hNet.getInputSet(element).size() == 0) {
      if (startPlace > 0) {
        startPlace--;
        numberTokens--;
      }
    } else {
      taskToFire = element;
      for (int iTasks = 0; iTasks < tasks.size(); iTasks++) {
        task = tasks.get(iTasks);
        subsets = auxMapping.getRelatedSubsets(taskToFire, task);
        if (subsets != null) {
          for (int iSubsets = 0; iSubsets < subsets.size(); iSubsets++) {
            subset = subsets.get(iSubsets);
            tokens = getNumberTokens(task, subset);
            if (tokens.intValue() > 0) {
              decreaseNumberTokens(task, subset);
              numberTokens--;
            }
          }
        }
      }
    }
  }
コード例 #6
0
  private HNSubSet getAllOutputElementsOfDuplicates(HNSubSet duplicates) {
    // Returns the union set of the output tasks of the tasks in
    // "duplicates".
    // The returned union set has already the codes mapped to the ATEs in
    // the log!
    HNSubSet union = new HNSubSet();
    HNSubSet allElements;

    for (int i = 0; i < duplicates.size(); i++) {
      allElements = hNet.getAllElementsOutputSet(duplicates.get(i));
      for (int j = 0; j < allElements.size(); j++) {
        union.add(hNet.getDuplicatesMapping()[allElements.get(j)]);
      }
    }

    return union;
  }
コード例 #7
0
  /*
   * Checks if a element is enabled at the current marking. <p> <b>Note:</b>
   * The element MUST be in the Element.
   *
   * @param element element/transition to check
   *
   * @return true if the element is enabled at the current marking. false
   * otherwise.
   */
  public boolean isEnabled(int element) {
    if (hNet.getInputSet(element) == null) {
      return false;
    }

    if (hNet.getInputSet(element).size() == 0) {
      if (startPlace < 1) {
        return false;
      }
    } else {
      bestCombination = findBestSetTasks(element);
      if (bestCombination.getNumberMissingTokens() > 0) {
        return false;
      }
    }

    return true;
  }
コード例 #8
0
  private void buildMapping(HeuristicsNet hn) {

    HNSet outputSubsets;
    HNSubSet outputSubset;
    int taskInSubset;

    mapping = new HNSet[hn.size()][hn.size()];

    for (int task = 0; task < hn.size(); task++) {
      outputSubsets = hn.getOutputSet(task);
      for (int iOutputSubsets = 0; iOutputSubsets < outputSubsets.size(); iOutputSubsets++) {
        // inserting for every element
        outputSubset = outputSubsets.get(iOutputSubsets);
        for (int iSubset = 0; iSubset < outputSubset.size(); iSubset++) {
          taskInSubset = outputSubset.get(iSubset);
          insertInMapping(taskInSubset, task, outputSubset);
        }
      }
    }
  }
コード例 #9
0
  /** Sets the marking to the initial marking. */
  public void reset() {

    Iterator outElements = null;
    HNSubSet outSubset = null;

    numberTokens = 1; // in the source place
    startPlace = 1;
    endPlace = 0;

    // initially, only the single start tasks is enabled
    possiblyEnabledElements = new HNSubSet();
    for (int i = 0; i < hNet.getStartTasks().size(); i++) {
      possiblyEnabledElements.add(hNet.getStartTasks().get(i));
    }
    for (int i = 0; i < size; i++) {
      outElements = marking[i].keySet().iterator();
      while (outElements.hasNext()) {
        outSubset = (HNSubSet) outElements.next();
        marking[i].put(outSubset, new Integer(0));
      }
      outElements = null;
    }
  }
コード例 #10
0
  private int identifyDuplicateToFire(HNSubSet duplicates, int elementInATE) {

    HNSubSet candidateDuplicates = new HNSubSet();
    HNSubSet allElements;

    for (int i = 0; i < duplicates.size(); i++) {
      allElements = hNet.getAllElementsOutputSet(duplicates.get(i));
      for (int j = 0; j < allElements.size(); j++) {
        if (elementInATE == hNet.getDuplicatesMapping()[allElements.get(j)]) {
          candidateDuplicates.add(duplicates.get(i));
          break;
        }
      }
    }

    if (candidateDuplicates.size() <= 0) {
      candidateDuplicates = duplicates; // we can choose any of the tasks
      // because none has
      // followers in the process instance...
    }

    return candidateDuplicates.get(generator.nextInt(candidateDuplicates.size()));
  }
コード例 #11
0
  private CombinationTasksToFire findBestSetTasks(int element) {
    CombinationTasksToFire bCombination = null;
    CombinationTasksToFire combination = null;
    HNSubSet noTokensFromTasks = null;
    HNSubSet treatedTasks = null;
    HNSet inputSet = null;
    HNSet temp_inputSet = null;

    HNSubSet subset = null;

    int numberMissingTokens = 0;
    int rootTask = ROOT_TASK_ID;

    bCombination = new CombinationTasksToFire();

    inputSet = hNet.getInputSet(element);

    if (inputSet.size() == 0) {
      if (startPlace <= 0) {
        numberMissingTokens++; // one token is missing
      }
    } else {
      // inputSubset is not empty. Search for tasks that "have tokens" to
      // element

      noTokensFromTasks = getTasksWithEmptyOutputPlaces(element);

      // >>>>>>>>>>>>>>>>>> Hint!!! I think that's why I don't run into
      // problems...
      // /// Idea -> shrink the subsets without using a temp variable, get
      // / the size before shrinking, shrink them, reorder the set and
      // /remove the empty set (do this via a method in the class
      // /HNSet, get the new size. This is the number of missing tokens.

      // make a copy to avoid destroying the original net
      inputSet = inputSet.deepCopy();
      temp_inputSet = new HNSet();
      // removing the tasks whose output subsets that contain element are
      // empty
      for (int iInputSubsets = 0; iInputSubsets < inputSet.size(); iInputSubsets++) {
        subset = inputSet.get(iInputSubsets);
        subset.removeAll(noTokensFromTasks);
        if (subset.size() == 0) {
          numberMissingTokens += 1;
        } else {
          temp_inputSet.add(subset);
        }
      }
      inputSet = temp_inputSet;
      // retrieving the best combination of tasks that can fire to enable
      // element

      if (inputSet.size() > 0) {
        combination = new CombinationTasksToFire();
        treatedTasks = new HNSubSet();
        bCombination =
            findBestCombination(bCombination, inputSet, rootTask, combination, treatedTasks);
      }
    }

    bCombination.setElementToFire(element);
    bCombination.setTokens(bCombination.getNumberMissingTokens() + numberMissingTokens);

    return bCombination;
  }
コード例 #12
0
 private void addToPossiblyEnabledElements(int element) {
   HNSubSet subset = hNet.getAllElementsOutputSet(element);
   for (int i = 0; i < subset.size(); i++) {
     possiblyEnabledElements.add(subset.get(i));
   }
 }
コード例 #13
0
  /**
   * Fires a element even if it is not enabled. When the element has duplicates, it looks ahead to
   * set which duplicate to fire.
   *
   * <p><b>Note:</b> The element MUST be in the net.
   *
   * @param element element to be fired.
   * @param pi process instance where the element to be fired is.
   * @param elementPositionInPi element position.
   * @return int number of tokens that needed to be added to fire this element.
   */
  public int fire(int element, ProcessInstance pi, int elementPositionInPi) {

    int addedTokens = 0;
    int elementDuplicates;

    if ((hNet.getReverseDuplicatesMapping()[element]).size() == 1) {
      elementDuplicates = hNet.getReverseDuplicatesMapping()[element].get(0);
    } else {
      // identify which duplicate to fire
      HNSubSet duplicates = hNet.getReverseDuplicatesMapping()[element].deepCopy();

      // getting the duplicates that are enabled
      for (int i = 0; i < duplicates.size(); i++) {

        if (!isEnabled(duplicates.get(i))) {
          duplicates.remove(duplicates.get(i));
        }
      }

      if (duplicates.size() > 0) {
        if (duplicates.size() == 1) {
          elementDuplicates = duplicates.get(0);
        } else {
          // getting the output tasks of the duplicates. These output
          // are used to
          // look ahead at the process instance
          HNSubSet unionMappedToATEsCode = getAllOutputElementsOfDuplicates(duplicates);
          AuditTrailEntryList ATEntriesList = pi.getAuditTrailEntryList();
          // advancing the pointer in the ATEntries till the current
          // element + 1

          AuditTrailEntry ATEntry;
          int elementInATE = -1;
          for (int i = elementPositionInPi + 1; i < ATEntriesList.size(); i++) {
            try {
              ATEntry = ATEntriesList.get(i);
              elementInATE =
                  this.hNet
                      .getLogEvents()
                      .findLogEventNumber(ATEntry.getElement(), ATEntry.getType());
              if (unionMappedToATEsCode.contains(elementInATE)) {
                break;
              }

            } catch (IOException ex) {
              break;
            } catch (IndexOutOfBoundsException ex) {
              break;
            }
          }
          elementDuplicates = identifyDuplicateToFire(duplicates, elementInATE);
        }
      } else {
        // because no duplicate is enabled, a random one is chosen to
        // fire...
        elementDuplicates =
            (hNet.getReverseDuplicatesMapping()[element])
                .get(generator.nextInt(hNet.getReverseDuplicatesMapping()[element].size()));
      }
    }

    bestCombination = findBestSetTasks(elementDuplicates);
    addedTokens += bestCombination.getNumberMissingTokens();
    removeTokensOutputPlaces(elementDuplicates, bestCombination.getTasks());
    addTokensOutputPlaces(elementDuplicates);
    addToPossiblyEnabledElements(elementDuplicates);

    // registering the firing of element...
    hNet.increaseElementActualFiring(
        elementDuplicates,
        MethodsForWorkflowLogDataStructures.getNumberSimilarProcessInstances(pi));
    // updating the arc usage for the individual...
    hNet.increaseArcUsage(
        bestCombination.getElementToFire(),
        bestCombination.getTasks(),
        MethodsForWorkflowLogDataStructures.getNumberSimilarProcessInstances(pi));

    return addedTokens;
  }