计算等价类

来源:互联网 发布:大麦网 数据 编辑:程序博客网 时间:2024/06/14 20:46

首先,什么是等价关系:

等价关系是集合元素间的一种代数关系,用字母E来表示,对于一个集合中的两个元素,如果他们之间存在一种等价关系,那么必须满足以下性质:

1.  自反性,对于任意一个元素x, 它与自己存在等价关系,即(x,x) 满足E

2.  对称性,如果(x,y) 满足 E, 那么 (y, x) 也属于E

3.  传递性,如果(x,y) 满足 E,(y,z)满足E,那么(x,z)也满足E.

接下来,看下面一个等价类的算法:

假设有集合S: {1, 2, … n-1}. 同时有两个数组A,B,他们的元素都来自集合S,且长度都是m, A,B 两数组用来确定集合S 中元素的等价关系,假定A[k] 与 B[k]是等价的,那么S便会被划分成几个不相交的等价类子集,例如:

n = 7,m=4,

假定:

A = {1, 5, 3, 6}

B = {2, 1, 0, 5}

于是S便会被划分成3个不相交的等价类子集:

S1 = {0, 3}

S2 = {1, 2, 5, 6}

S3 = {4}

给你一个数组S, 以及数组A,B, 要求你计算出S被划分的等价类子集。

一种方法是,用队列,把等价的各个元素链接起来,那么互相链接的类就是等价类。

另一种方法是利用等价类的传递性,如果A与B等价,B与C等价那么A与C也等价。

代码如下:

public class Number {public  int val;    public  ArrayList<Integer> set = null;    public  boolean visited = false;        public Number(int val) {    this.val = val;    set = new ArrayList<Integer>();    set.add(val);    }}public class EquivalClass {private Number[] numArray = null;    public EquivalClass(int n, int[] A, int[] B) {        numArray = new Number[n];    for (int i = 0; i < n; i++) {    numArray[i] = new Number(i);    }        for (int i = 0; i < A.length; i++) {    int  a = A[i];    int  b = B[i];        makeSet(numArray[a], numArray[b]);    }        }        private void makeSet(Number a, Number b) {    a.set.addAll(b.set);    b.set = a.set;    }        public void printAllEquivalSet() {    for (int i = numArray.length - 1; i >= 0; i--) {    printEquivalSet(numArray[i]);    }    }        private void printEquivalSet(Number number) {    if (number.visited == true) {    return;    }        number.visited = true;    System.out.print("{ ");    Iterator<Integer> it = number.set.iterator();    while (it.hasNext()) {    int v = it.next();    System.out.print(v + " ");    numArray[v].visited = true;    }    System.out.println(" }");        }       }