Repository /Rseslib/rseslib-3.0.1.jar:rseslib.processing.reducts.PartialReductsProvider


Back

No file description

Source code

/*
 * $RCSfile: PartialReductsProvider.java,v $
 * $Revision: 1.1 $
 * $Date: 2009/01/09 09:51:47 $
 * $Author: wojna $
 * 
 * Copyright (C) 2008 Marcin Piliszczuk, Beata Zielosko
 * 
 *  This file is part of Rseslib.
 *
 *  Rseslib 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
 *  (at your option) any later version.
 *
 *  Rseslib 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 rseslib.processing.reducts;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
//import java.util.Properties;

import rseslib.structure.data.DoubleData;
import rseslib.structure.data.DoubleDataWithDecision;
import rseslib.structure.table.DoubleDataTable;

/** 
 * Constructs local and global partial decision reducts by a greedy algorithm.
 * 
 * @author Marcin Piliszczuk & Beata Zielosko
 */
public class PartialReductsProvider implements ReductsProvider {
    protected int NumberOfSubsets = 0;  //num_vars
    protected int NumberOfRows = 0;
    protected int NumberOfElements = 0; //t.total_diff_rows
    ArrayList<DoubleData> T;
    protected boolean[] PartialCover;
    long ElementsCovered = 0;//card_pcover

     /**
     *  Constructor
     * 
     * @param DoubleDataTable 
     * @param row       if row < 0 then construct global reduct for table t; if row >= 0 construct local reduct for this row 
     * @param alpha     0 <= alpha < 1      covering precision
     */
    public PartialReductsProvider(DoubleDataTable t, int row, double alpha) throws Exception {
        NumberOfSubsets = t.attributes().noOfAttr()-1;
        PartialCover = new boolean[NumberOfSubsets];   
        NumberOfRows = t.noOfObjects();
        if (row < 0) {
            T = t.getDataObjects();
            countPTCardinality();
        } else {
            T = t.getDataObjects();
            T = createU(t.getDataObjects(), row);
            NumberOfElements = T.size() -1;
            NumberOfRows = T.size();
        }

        int[] card = new int[NumberOfSubsets];
        ElementsCovered = 0;
        long M = (long) Math.ceil((double) NumberOfElements * (1 - alpha));
        while (M > ElementsCovered) {

            if (row < 0) {
                card = count_reduct_card();
            } else {
                card = count_rule_card();
            }
            short set = findBestSet(card);
            if (card[set] == 0) {
                throw new Exception("greedy algorithm: best set is empty");
            }
            insertAttribute(set, card);
            card = new int[NumberOfSubsets];
        } // while

        minimizeCover(alpha);
    }
        /**
     * Returns  partial cover as a Collection<BitSet>
     * @return
     */
    public Collection<BitSet> getReducts(){
        Collection<BitSet> reducts = new ArrayList<BitSet>();
        
        BitSet b = new BitSet(PartialCover.length);
        for(int i = 0; i < PartialCover.length; i++)
            if (PartialCover[i] == true) b.set(i);
        
        reducts.add(b);
        return reducts;
    };

    /**
     * Returns  partial cover in form of boolean array 
     * @return
     */
    public boolean[] getPartialCover(){
        return PartialCover;
    }
    
/**
 * Creates set U containing rows from table t which have different decisions and different description from row r 
 * @param t     decision table
 * @param r     row for which we want to make a decision rule
 * @return      Set U containing rows different from r
 */
    protected ArrayList<DoubleData> createU(ArrayList<DoubleData> t, int r) {
        ArrayList<DoubleData> tmp = new ArrayList<DoubleData>();
        tmp.add(t.get(r));

        for (int i = 0; i < NumberOfRows; i++) {
            if (differentDecisions(r, i)) {
                if (differentRows(r, i)) {
                    tmp.add(t.get(i));
                /*
                for(int j=0; j<num_vars; j++)
                tmp.w[j]=w[j];
                 */
                }
            }
        }
        return tmp;
    }
    
    /**  Computes number of pairs of different rows with different decisions from decision table
     *    |P(T)|   
     * @return
     */
    protected void countPTCardinality() { //count_diff_rows()
        NumberOfElements = 0;
        for (int i = 0; i < NumberOfRows - 1; i++) {
            for (int j = i + 1; j < NumberOfRows; j++) {
                if (differentDecisions(i, j) && differentRows(i, j)) {
                    NumberOfElements++;
                //if((tab[num_vars][i]!=tab[num_vars][j]) && (differentRows(i,j)==1)) NumberOfElements++;         
                }
            }
        }
    }
  
    protected boolean differentDecisions(int i, int j) {
        if (((DoubleDataWithDecision) T.get(i)).getDecision() != ((DoubleDataWithDecision) T.get(j)).getDecision()) {
            return true;
        } else {
            return false;
        }
    }

    protected boolean pairCovered(int i, int j, int atr) {  //pairSeparatedbyAttr
        if (T.get(i).get(atr) != T.get(j).get(atr) /*wykluczyc missingi&& t.tab[c][i] >= 0 && t.tab[c][j] >= 0*/) {
            return true;
        } else {
            return false;
        }
    }

    protected boolean pairCovered(int i, int j) {
        boolean result = false;
        for (int c = 0; c < NumberOfSubsets; c++) {
            if (pairCovered(i, j, c)) {
                if (PartialCover[c] == true) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }

    protected boolean differentRows(int i, int j) {
        boolean result = false;
        for (int c = 0; c < NumberOfSubsets; c++) {
            if (pairCovered(i, j, c)) {
                result = true;
                break;
            }
        }
        return result;
    }

    protected void add_card(int[] c1, int[] c2) {
        for (int i = 0; i < c1.length; i++) {
            c1[i] += c2[i];
        }
    }

    protected synchronized int[] count_local_card(int i) {
        int[] card = new int[NumberOfSubsets];
        for (int j = i + 1; j < T.size(); j++) {
            if (differentDecisions(i, j) && !pairCovered(i, j) && differentRows(i, j)) {
                for (int c = 0; c < NumberOfSubsets; c++) {
                    if (PartialCover[c] == false) {
                        if (pairCovered(i, j, c)) {
                            card[c]++;
                        }
                    }
                }
            }
        }
        return card;
    }

    protected int[] count_rule_card() {
        return count_local_card(0);
    }

    /**
     * 
     * @return
     */
    protected int[] count_reduct_card() {
        int[] card = new int[NumberOfSubsets];
        for (int i = 0; i < NumberOfRows - 1; i++) {
            int[] c = count_local_card(i);
            add_card(card, c);
        }
        return card;
    }

    /**
     * Finds set which covers maximal number of elements
     * @param card      array of numbers of elements covered by each set
     * @return
     */
    protected short findBestSet(int[] card) {
        short set = 0;
        for (short c = 1; c < NumberOfSubsets; c++) {
            if (card[set] < card[c]) {
                set = c;
            }
        }
        return (set);
    }
    
    /**
     * Adds set to partial cover
     * @param set       choosen set 
     * @param card      array of numbers of elements covered by each set
     */
    protected void insertAttribute(short set, int[] card) {
        PartialCover[set] = true;
        ElementsCovered += card[set];
//    gamma = t.total_diff_rows - card_pcover;
//    gamma /=(double) t.total_diff_rows;
    }

    /**
     * Transforms alpha-cover to irreducible alpha-cover
     * @param alpha     covering precision
     */
    protected void minimizeCover(double alpha) {
        for (int i = 0; i < NumberOfSubsets; i++) {
            if (PartialCover[i] == true) {
                PartialCover[i] = false;
                if (!alphaCover(alpha)) {
                    PartialCover[i] = true;
                }
            }
        }
    }

    /**
     * Method checks if we have an alpha-cover
     * @param alpha     covering precision  
     * @return          true when we cover no less than (1-alpha)|A| elements (pairs of rows)
     */
    protected boolean alphaCover(double alpha) {
        boolean result = true;
        //    System.out.println("alpha = " + alpha);
        //    System.out.println("tdr = " + t.total_diff_rows);
        //    System.out.println("num unsep ok = " + Math.floor(alpha*t.total_diff_rows));
        long nuo = (long) Math.floor(alpha * NumberOfElements);
        long curr_unsep = 0;

        for (int i = 0; i < NumberOfRows - 1; i++) {
            //System.out.println("partialSetCoverProvider::alphaCover i = " + i);
            for (int j = i + 1; j < NumberOfRows; j++) {
                //System.out.println("partialSetCoverProvider::alphaCover j = " + j);
                if (differentDecisions(j, i)) 
                    if (differentRows(j, i)) {
                        //sprawdzamy czy redukt oddziela pare
                        //int atr = 0;
                        int separated = 0;
                        for (int k = 0; k < NumberOfSubsets; k++) 
                            if (PartialCover[k] == true) 
                                if (pairCovered(i,j,k))/*(t.tab[atr][i] != t.tab[atr][j])*/ {
                                    separated = 1;
                                    break;
                                }                        
                            //atr++;                    
                        if (separated == 0) curr_unsep++;                    
                        if (curr_unsep > nuo) return false;                    
                    }            
            } 
        }   
        return result;
    }

 
}

Copyright © 2008-2011 by TunedIT
Design by luksite