de.uni_potsdam.hpi.bpt.promnicat.analysisModules.clustering.ProcessInstance.java Source code

Java tutorial

Introduction

Here is the source code for de.uni_potsdam.hpi.bpt.promnicat.analysisModules.clustering.ProcessInstance.java

Source

/**
 * PromniCAT - Collection and Analysis of Business Process Models
 * Copyright (C) 2012 Cindy Fhnrich, Tobias Hoppe, Andrina Mascher
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.uni_potsdam.hpi.bpt.promnicat.analysisModules.clustering;

import org.jbpt.pm.ProcessModel;

import weka.core.Instance;

/**
 * Custom class of the data elements for the
 * {@link HierarchicalProcessClusterer}. Extends WEKAs {@link Instance} by the
 * {@link ProcessModel} that is to be clustered and string attributes to use.
 * 
 * @author Cindy Fhnrich
 * 
 */
public class ProcessInstance extends Instance {

    /** for serialization */
    static final long serialVersionUID = 4L;

    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    /** process model that is clustered */
    public ProcessModel process;

    /** The instance's string attribute values. */
    protected /*@spec_public non_null@*/ String[] m_StringAttValues;

    /**
     * Constructor that copies the numeric and string attribute values and the weight from the
     * given instance. Reference to the dataset is set to null. (ie. the
     * instance doesn't have access to information about the attribute types)
     * 
     * @param instance
     *            the instance from which the attribute values and the weight
     *            are to be copied
     */
    // @ ensures m_Dataset == null;
    public ProcessInstance(/* @non_null@ */ProcessInstance instance) {

        m_AttValues = instance.m_AttValues;
        m_StringAttValues = instance.m_StringAttValues;
        m_Weight = instance.m_Weight;
        this.id = instance.getId();
        m_Dataset = null;
    }

    /**
       * Merges this instance with the given instance and returns
       * the result. Dataset is set to null.
       *
       * @param inst the instance to be merged with this one
       * @return the merged instances
       */
    public ProcessInstance mergeInstance(ProcessInstance inst) {

        int m = 0;
        double[] newVals = new double[numAttributes() + inst.numAttributes()];
        for (int j = 0; j < numAttributes(); j++, m++) {
            newVals[m] = value(j);
        }
        for (int j = 0; j < inst.numAttributes(); j++, m++) {
            newVals[m] = inst.value(j);
        }

        //merge for string attributes
        int n = 0;
        String[] newStrVals = new String[numStrAttributes() + inst.numStrAttributes()];
        for (int j = 0; j < numStrAttributes(); j++, n++) {
            newStrVals[n] = strValue(j);
        }
        for (int j = 0; j < inst.numStrAttributes(); j++, n++) {
            newStrVals[n] = inst.strValue(j);
        }

        return new ProcessInstance(1.0, newVals, newStrVals);
    }

    /**
     * Sets a specific string attribute in the instance to the given value. 
     *
     * @param attIndex the string attribute's index 
     * @param value the new attribute value   
     */
    public void setStrValue(int attIndex, String value) {

        m_StringAttValues[attIndex] = value;
    }

    /**
     * Returns the number of string attributes.
     *
     * @return the number of string attributes as an integer
     */
    //@ ensures \result == m_AttValues.length;
    public /*@pure@*/ int numStrAttributes() {

        return m_StringAttValues.length;
    }

    /**
     * Returns an instance's string attribute value.
     *
     * @param attIndex the string attribute's index
     * @return the specified value as a double (If the corresponding
     * attribute is nominal (or a string) then it returns the value's index as a 
     * double).
     */
    public /*@pure@*/ String strValue(int attIndex) {

        return m_StringAttValues[attIndex];
    }

    /**
     * Tests if a specific string value is "missing".
     *
     * @param attIndex the string attribute's index
     * @return true if the value is "missing"
     */
    public /*@pure@*/ boolean isStringMissing(int attIndex) {

        if (m_StringAttValues[attIndex].equals("")) {
            return true;
        }
        return false;
    }

    /**
     * Constructor that inititalizes instance variable with given numeric attribute values.
     * Reference to the dataset is set to null. (ie. the instance doesn't have
     * access to information about the attribute types)
     * 
     * @param weight
     *            the instance's weight
     * @param attValues
     *            a vector of numeric attribute values
     */
    // @ ensures m_Dataset == null;
    public ProcessInstance(double weight, /* @non_null@ */double[] attValues) {

        m_AttValues = attValues;
        m_Weight = weight;
        m_Dataset = null;
        m_StringAttValues = null;
    }

    /**
     * Constructor that inititalizes instance variable with given numeric and 
     * string attribute values.
     * Reference to the dataset is set to null. (ie. the instance doesn't have
     * access to information about the attribute types)
     * 
     * @param weight
     *            the instance's weight
     * @param attValues
     *            a vector of attribute values
     * @param strAttValues
     *            a vector of string attribute values
     */
    // @ ensures m_Dataset == null;
    public ProcessInstance(double weight, /* @non_null@ */double[] attValues, String[] strAttValues) {

        m_AttValues = attValues;
        m_Weight = weight;
        m_Dataset = null;
        m_StringAttValues = strAttValues;
    }

    /**
     * Constructor of an instance that sets weight to one, all values to be
     * missing, and the reference to the dataset to null. (ie. the instance
     * doesn't have access to information about the attribute types)
     * 
     * @param numAttributes
     *            the number of the numeric attributes
     * @param numStrAttributes
     *            the number of the string attributes
     */
    // @ requires numAttributes > 0; // Or maybe == 0 is okay too?
    // @ ensures m_Dataset == null;
    public ProcessInstance(int numAttributes, int numStrAttributes) {

        m_StringAttValues = new String[numStrAttributes];
        m_AttValues = new double[numAttributes];
        for (int i = 0; i < m_AttValues.length; i++) {
            m_AttValues[i] = MISSING_VALUE;
        }
        for (int i = 0; i < m_StringAttValues.length; i++) {
            m_StringAttValues[i] = "";
        }
        m_Weight = 1;
        m_Dataset = null;
    }

    /**
     * Constructor of an instance that sets weight to one, all values to be
     * missing, and the reference to the dataset to null. (ie. the instance
     * doesn't have access to information about the attribute types)
     * 
     * @param numAttributes
     *            the size of the instance
     */
    // @ requires numAttributes > 0; // Or maybe == 0 is okay too?
    // @ ensures m_Dataset == null;
    public ProcessInstance(int numAttributes) {

        this(numAttributes, 0);
    }

    /**
     * Returns the description of one instance's string attributes (without weight appended). If the
     * instance doesn't have access to a dataset, it returns the internal
     * floating-point values. Quotes string values that contain whitespace
     * characters.
     * 
     * This method is used by getRandomNumberGenerator() in Instances.java in
     * order to maintain backwards compatibility with weka 3.4.
     * 
     * @return the instance's description as a string
     */
    protected String toStringNoWeight() {
        StringBuffer text = new StringBuffer();
        text.append("Numeric: ");
        for (int i = 0; i < m_AttValues.length; i++) {
            if (i > 0)
                text.append(",");
            text.append(toString(i));
        }
        text.append("Nominal: ");
        for (int i = 0; i < m_StringAttValues.length; i++) {
            if (i > 0)
                text.append(",");
            text.append(m_StringAttValues[i]);
        }

        return text.toString();
    }

    /**
     * Produces a shallow copy of this instance. The copy has access to the same
     * dataset. (if you want to make a copy that doesn't have access to the
     * dataset, use <code>new ProcessInstance(instance)</code>
     * 
     * @return the shallow copy
     */
    // @ also ensures \result != null;
    // @ also ensures \result instanceof Instance;
    // @ also ensures ((Instance)\result).m_Dataset == m_Dataset;
    public/* @pure@ */ProcessInstance copy() {

        ProcessInstance result = new ProcessInstance(this);
        result.m_Dataset = m_Dataset;
        result.process = process;
        result.m_AttValues = m_AttValues;
        result.m_StringAttValues = m_StringAttValues;
        result.m_Weight = m_Weight;
        return result;
    }

    /**
     * Deletes an attribute at the given position (0 to numAttributes() - 1).
     * 
     * @param position
     *            the attribute's position
     * @param isNumericAtt
     *            indicates whether attribute to delete is string or numeric
     */
    void forceDeleteAttributeAt(int position, boolean isNumericAtt) {

        if (isNumericAtt) {
            double[] newValues = new double[m_AttValues.length - 1];

            System.arraycopy(m_AttValues, 0, newValues, 0, position);
            if (position < m_AttValues.length - 1) {
                System.arraycopy(m_AttValues, position + 1, newValues, position,
                        m_AttValues.length - (position + 1));
            }
            m_AttValues = newValues;
        } else {
            String[] newValues = new String[m_StringAttValues.length - 1];

            System.arraycopy(m_StringAttValues, 0, newValues, 0, position);
            if (position < m_StringAttValues.length - 1) {
                System.arraycopy(m_StringAttValues, position + 1, newValues, position,
                        m_StringAttValues.length - (position + 1));
            }
            m_StringAttValues = newValues;
        }

    }
}