拟阵及其应用(带有oj例题讲解)

Matroid

introduction

这篇文章主要是写拟阵及其应用。虽然拟阵的出现并不是因为贪心算法,但是它在贪心算法有着非常重要的地位。

一些概念

  1. 线性相关和线性无关:
    在线性代数里,矢量空间的一组元素中,若没有矢量可用有限个其他矢量的线性组合所表示,则称为线性无关线性独立 (linearly independent),反之称为线性相关(linearly dependent)。

  2. 集族:
    设{ EααI E α : α ∈ I }是一个以集合 Eα E α 为元素的集合,这种以集合为元素的集合常称为集合类或者集合族, α α 称为指标, I I 是由全体指标构成的指标集。

  3. 拟阵(matroid):
    一个拟阵就是一个满足如下条件的序偶M=(S,T):

    • S是一个有限集合,T是S的一个非空子集,这些子集称为独立子集。
    • 具有遗传性,即B T且A B,则A T.
    • 具有交换性质,如果A T,B T,且|A|<|B|,那么存在某个元素x B-A,使得A {x} T,则称M满足交换性质。
  4. 图拟阵:
    图拟阵 MG=(SG,TG) M G = ( S G , T G ) 它定义在一个给定的无向图G=(V,E)之上:

    • SG S G 定义为E,即G的边集合。
    • 如果A是E的子集,则A TG ∈ T G 当且仅当A是无圈的。也就是说,一组边A边是独立的当且仅当子图 GA G A =(V,A)形成一个森林。
  5. 拓展:
    给定一个拟阵M=(S,T),如果对一个集合A T和一个元素x A,将x加入A会保持独立性质,则称x是A的一个拓展。对于拟阵中的一个独立子集,如果它不存在拓展,则称它是最大的

  6. 加权拟阵:
    如果一个拟阵M=(S,T)关联一个权重函数w,为每个元素x S赋予一个严格大于0权值w(x),则称拟阵M是加权的。通过求和,可将权重函数w拓展到S的任何一个子集A:

    例如令w(e)表示图拟阵 MG M G 中边e的权重,那么w(A)就表示边集合A中所有边的权重之和。

两个定理

  1. 如果G=(V,E)是一个无向图,则 MG=(SG,TG) M G = ( S G , T G ) 是一个拟阵。

  2. 拟阵中所有最大独立子集都具有相同的大小。

加权拟阵上的贪心算法

很多可以使用贪心算法得到最优解的问题都可以形式化为一个加权拟阵中寻找最大权重独立子集的问题。也就是说,给定一个加权拟阵M=(S,T),我们希望寻找独立集A T,使得W(A)最大。我们称这种独立且具有最大可能权重的子集为拟阵的最优子集。由于任何元素x S的权重都是正的,最优子集必定是最大独立自己——它总是有助于使得A尽可能大。

下面开始给出是适用于任何加权拟阵的算法:

GREEDY(M,w)
    A={}
    sort M.S into monotonicially decreasing order weight w
    for x in M.S, taken in monotonically decreasing order by weight w(x)
        if A+{X} in M.T
            A=A+{X}
    return A

拟阵的贪心算法的正确性也是从greedy choice property和optimal substruture这两个方面来证明的。下面我们来分别证明:

  1. greedy choice property

    引理1.(拟阵具有贪心选择性质)假定M=(S,T)是一个加权拟阵,加权函数w,且S已经按照权重单调递减顺序排序。令x是S中第一个满足{x}独立的元素(如果存在)。如果存在这样的x,那么存在S的一个最优子集A包括x。

    证明:

    假设B是最优子集,A不是最优子集,B中将x换成y,因为x是降序排序的第一个元素,所以w(x)>w(y),B=A-{x}+{y}
    所以w(B)=w(A)-w(x)+w(y) < w(A),所以假设不成立,最优子集必定包含x。

  2. optimal substructure

    引理2.令M=(S,T)是一个加权拟阵,x是S中第一个被greedy算法选出的元素,则接下来寻找包含x的最大权重独立子集的问题归结于寻找加权拟阵M’=(S’,T’)的一个最大权重独立子集的问题,其中:

    • S’={y S:{x,y T}}

    • T’={B S-{x}:B {x} T}

    证明:若A是M的任意一个包含x的最大权重独立子集,则A’=A-{x}是M‘的一个独立子集。相反,任何独立子集A’可生成M的独立子集A=A‘ {x}。由于对两种情况均有w(A)=w(A’)+w(x),因此M的包含x的最大权重子集必然生成M’的最大权重子集,反之依然。

Example

最小生成树算法

最小生成树问题是在无向图上进行的。对于无向图G=(V,E)。

  1. 我们可以定义一个这样的M=(S,T):

    • S是边集E
    • L={x:x E且x组成的图无环}
  2. 下面来证明这个M满足拟阵的条件:同证明无向图是拟阵。

  3. 下面我们就开始定义加权函数,w(x)表示边x的长度,w’(x)=w0-w(x),其中w0=max(w(x))+1,使得w‘(x)大于0,当w’(x)最大的时候,w(x)取得最小值。

  4. 然后我们将S根据w’(x)进行升序排序,如果x S可以加入A(这里需要判断:A所组成的图无环),则A=A {x}

  5. 得到最大独立边集合A

  6. Accepted code

// poj 1258
#include
#include
using namespace std;

const int maxn=105;

struct Edge{
    int u,v,w,key;
    Edge(){}
    Edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){
        key= 100000-ww;
    }

    bool operator<(const Edge& obj)const{
        return key>obj.key;
    }
}edge[maxn*maxn];

int f[maxn];

void Init(){
    for(int i=0;iint Find(int x){
    if(f[x]==x){
        return x;
    }else{
        return f[x]=Find(f[x]);
    }
}

void Union(int x,int y){
    int fx=Find(x),fy=Find(y);
    f[fy]=fx;
}


int main(int argc, char const *argv[])
{
    int n;
    while(~scanf("%d",&n)){
        Init();
        for(int i=0;ifor(int j=0;jint w;
                scanf("%d",&w);
                edge[i*n+j]=Edge(i,j,w);
            }
        }

        sort(edge,edge+n*n);

        long long int res=0;
        int cnt=0;

        for(int i=0;i1;i++){
            int u=edge[i].u,fu=Find(u);
            int v=edge[i].v,fv=Find(v);
            int w=edge[i].w;
            if(fu!=fv){
                cnt++;
                res+=w;
                Union(u,v);
                //printf("%d\n",w);
            }
        }

        printf("%lld\n",res);
    }
    return 0;
}

Referenence

  1. Introduction to algorithm
  2. 《对拟阵的初步研究》

你可能感兴趣的:(数据结构,Graph,贪心)