擬陣


擬陣

(latest updated on 2020-08-10)

大量基礎定義警告,參考了wiki和2018論文《淺談擬陣的一些拓展及其應用》,如果想看大段詳細證明請移步論文

擬陣的概念比較抽象,有多種定義方法,結合這些定義方法可以更具體地了解擬陣的基礎性質

前言

很多問題可以轉化為擬陣,但是並不是所有問題都可以通過簡單的擬陣操作得到答案

在具體問題中,很多時候有着更優的算法解決擬陣運算無法解決的操作

但是對於一個奇怪的問題,如果轉化為類似擬陣的操作后,就有很多性質可以拿過來套

擬陣的應用,更多還是用 諸多的性質 把復雜,抽象問題向更簡單的方向轉化(便於亂搞)

也可以便於簡化問題的證明,所以這個東西了解一下也差不多了

(不會有人喪心病狂到專門出一個擬陣交的題吧)

\[\ \]

符號及約定

\(|S|\)集合大小

\(S-T\),刪除\(S\)中在\(T\)中的元素

\(a\Rightarrow b\)\(a\)\(b\)

\(a\Leftrightarrow b\)\(a,b\)等價

\(a\in b\)元素\(a\)是集合\(b\)中的一個元素

\(a\sube b\),集合\(a\)是集合\(b\)的子集

\(\exists\) 存在

\(\forall\) 任意

冪集

一個集合\(S\)的所有\(2^{|S|}\)個子集構成的集合是\(S\)的冪即\(P(S)\)或者\(2^S\)

集族

給定集合\(S\)一些子集構成的類\(F\)叫做\(S\)子集族(或稱S 上的集合族),\(F \sube 2^S\)

\[\ \]

用獨立集定義擬陣(似乎是最直觀的定義)

一個二元組\(M=(E,I)\),其中\(E\)基礎集\(I\)\(E\)一些子集構成的集族(即\(I\sube 2^S\)),稱之為獨立集,在獨立集中的子集稱之為獨立的

擬陣可以用獨立集\(I\)定義,則\(I\)需滿足性質:

1.空集:有\(\emptyset \in I\),所以有\(I\ne \emptyset\)

2.遺傳性:若\(A\sube B,B\in I\),則$ A\in I$

3.擴充性:若\(\exists A,B\in I,|A|>|B|\),則\(\exists i\in A,(B\cup \{i\}) \in I\)

例子:對於\(S=\{1,2,3\}\)\(\{\emptyset \},\{\emptyset,\{1\}\}\)是合法的獨立集,但\(\{\emptyset,\{1\},\{2\},\{3\},\{2,3\}\}\)不是,因為它不滿足擴充性

\(\{\{1,2\},\{2,3\},\{1\},\{2\},\{3\},\{\emptyset \}\}\)也是合法的獨立集

對於\(S=\{1,2,3,4,5\}\),\(I=\{\{1,2,3\},\{3,4,5\},\{1,2\},\{2,3\},\{1,3\},\{3,4\},\{3,5\},\{4,5\},\{1\},\{2\},\{3\},\{5\},\{\emptyset\}\}\)不是合法的獨立集,因為它不滿足擴充性(\(A=\{1,2,3\},B=\{3,4\}\)時)

\[\ \]

用基底和基定義擬陣(似乎是最簡潔的描述)

基底:\(E\)的一個獨立的極大子集稱為其的一個基底,獨立的極大子集即其加入任意元素得到的子集不獨立

基:\(E\)的基\(B\)為其所有基底構成的集合

擬陣可以用基\(B\)定義,則\(B\)需滿足性質:

1.非空:\(B\ne \emptyset\),最小的\(B=\{\emptyset\}\)

2.交換公理:對於兩個基底\(a,b\),若用\(b\)\(a\)沒有的元素換掉一個\(a\)中原先的元素,得到的集合依然是基底

推論:基底等大,即\(\forall a\in B,b\in B,|a|=|b|\)(否則就不滿足擴充性)

例如:若\(\{1,2\},\{1,3\}\)是基底,則\(\{2,3\}\)也是基底(否則不滿足擴充性)

可以得到擬陣的等價定義,且\(I=\bigcup _{T\in B} 2^T\)

\[\ \]

用環路集定義擬陣

環路:\(S\)的一個子集是環路,則這個子集是一個極小的非獨立集,即去掉任意一個元素都會稱為獨立集

所有環路構成的集合稱為環路集\(C\),如對於\(E=\{1,2\},I=\{\emptyset,\{1\}\}\),環路集為\(\{\{2\}\}\)

擬陣可以用環路集\(C\)定義,則\(C\)需滿足性質:

1.\(C\)可以為空(此時\(I=P(S)\)),且\(\emptyset \not \in C\)

2.環路互相之間不是真子集,即\(\exists a\in C,b\in C,a\sube b\Rightarrow a=b\) (否則不滿足遺傳性)

3.若\(\exists a\in C,b\in C,a\ne b\)以及一個元素\(i\in a\cap b\),則\(a\cup b-\{i\}\)不是獨立集

推論:\(A\sube I \Leftrightarrow \nexists B\in C,B\sube A\)

環路不一定等大

\[\ \]

環路和基底的一些關系

1.環路和基底之間不能通過加減一個元素轉化

2.基底加上一個元素得到的非獨立集恰好包含一個環路

\[\ \]

擬陣的秩

擬陣的秩:擬陣的任意一個基底的元素個數是其秩\(r\)

為了同下文的秩函數相對應,也可說\(\begin{aligned}r=\max_{R\in I}\{|R|\}\end{aligned}\),即最大的獨立集大小

\[\ \]

用秩函數定義擬陣

對於元素集\(S\)

若可以定義一個在\(2^S\)上的秩函數\(r(T)\),滿足以下性質:

1.大小有界:\(r(T)\in[0,|T|]\)

2.大小傳遞性:\(A\sube B\Rightarrow r(A)\le r(B)\)

3.次模性:\(r(A\cup B)+r(A\cap B)\le r(A)+r(B)\)

那么可以用這樣的一個秩函數定義一個擬陣\(M=(S,r)\),此時\(r(T)\)\(2^T\)中極大的獨立集大小,且擬陣的獨立集就是\(I=\{T|T\sube S,r(T)=|T|\}\)

\[\ \]

例子

均勻擬陣:\(U_n^k=(S,I),|S|=n,I=\{T|T\sube S,|T|\leq k\}\)

圖擬陣:

對於無向圖\(G=(V,E)\),它的生成擬陣是\(M=(E,\{T|T\sube E,T無環\})\)

它的最大獨立子集大小為\(G\)的最大生成森林邊數,每個最大生成森林都是基底

匹配擬陣:

對於無向圖\(G=(V,E)\),它的匹配擬陣是\(M=(V,\{T|T\sube V,存在一個邊匹配覆蓋T\})\)

它的最大的獨立子集大小為k最大匹配數,每個最優匹配的方案都是基底

異或線性基:

對於非負整數可重集合\(S\),擬陣是\(M=(S,\{T|T\sube S,T中的元素任意異或不會得到0\})\)

(這是向量空間的線性基問題的一種)

\[\ \]

\[\ \]


注意分清楚 定義需要滿足的條件通過條件推導得到的性質 的區別 ,上面幾種擬陣定義是等價的

\[\ \]

\[\ \]

一些應用

求最大權值獨立子集

對於擬陣\(M=(S,I)\),給每個\(S\)中每個元素一個非負權值,定義一個集合的權值為所有元素權值和,要求最大權值的獨立子集

這是一個非常簡單的問題,直接從大到小能加入就加入即可,設最終選出的集合為\(P\)

證明:

1.\(P\in B\),否則可以再加入元素

2.假設存在更優解\(Q\in B\),根據基底交換公理,一定可以用\(P\)中一個權值更大的元素換掉\(Q\)中一個元素,所以\(Q\)不是合法集合

在連通圖擬陣上使用該算法,就是\(\text{Kruskal}\)最小生成數算法

在異或線性基上使用該算法,可以求得最大權值線性基

\[\ \]

擬陣交

對於同基礎集的擬陣\(M_1=(S,I_1),M_2=(S,I_2)\),它們的交是獨立集的交

但是它們的交不一定是擬陣

求解最大交:最小最大定理:

\(\begin{aligned} \max_{A\in (I_1\cup I_2)}\{|T|\}=\min_{R\in S}\{r_1(R)+r_2(S-R)\}\end{aligned}\)

這個東西的證明分為兩步:

1.證明\(\max\leq \min\)

\(|T|=|T\cap R|+|T\cap (S-R)|\leq r_1(R)+r_2(S-R)\)

2.介紹找到兩個最值的算法

這個算法的中心是,從空集開始擴展\(T\),並且相應找到對應的\(R\)使得\(|T|=r_1(R)+r_2(S-R)\),此時答案已經充分了

求解擬陣交的算法基於一個構造的圖

對於當前的答案\(T\),構造一個有向二分圖,兩側點集分別為\(T,S-T\)

對於分別在兩側的點\(x,y\)

存在\(x\rightarrow y\)的邊: 當\(T\)中把\(x\)換成\(y\)之后是\(M_1\)的獨立子集

存在\(y\rightarrow x\)的邊: 當\(T\)中把\(y\)換成\(x\)之后是\(M_2\)的獨立子集

設對於\(I_1,I_2\)可行的增廣元素集合為$X_1,X_2 $(即加入元素后依然獨立的集合)

每次的增廣過程可以描述為:

(1.如果\(X_1\cap X_2\ne \emptyset\),直接都加入\(T\))

2.構圖,找到一條從\(X_1\)的點出發,到達\(X_2\)的的最短的路徑\(P\)(廣搜即可),將\(I\)變為\(I\bigoplus P\) (這里原文是對稱差,但是異或大家都懂哈)

當不存在增廣時,找到了最大的\(T\),此時對應合法的\(R\)\(\{e\in S|在圖中存在e到達X_2的路徑\}\)

由於每次增廣至少增加一個元素,該算法的復雜度上限為\(O(r|S|^2)\),其中\(r\)為擬陣的秩,\(|S|^2\)為邊數

\[\ \]

帶權擬陣交

每個元素帶權

在增廣時,圖上每個點加上點權(加入為正,刪除為負),每次求出點權最短路進行增廣即可

\[\ \]

擬陣交的應用

二分圖匹配問題

二分圖匹配匈牙利算法 是 求解擬陣交的問題 的一種特殊情況

對於二分圖\(G=(V_1,V_2,E)\),構造

\(M_1=(E,I=\{T\sube E|T中的邊在V_1上沒有公共點\})\)

\(M_2=(E,I=\{T\sube E|T中的邊在V_2上沒有公共點\})\)

答案就是\(M_1,M_2\)交的最大值,匈牙利算法增廣的過程是依次考慮\(X_1\)中的元素進行增廣

(帶權的二分圖匹配問題,實際也是可以用擬陣解決的,但是好像\(\text{KM}\)還是最棒的)

\[\ \]

擬陣交還可以解決一些看起來很抽象的 帶有兩個限制的 (可能帶權) 的問題,比如論文里下面的這個例子

(Colorful Tree): 對於一個無向圖,每條邊給定一個顏色和一個權值,求顏色不能重復的最大生成樹

類似這樣的問題可以轉化為擬陣交問題,但是這個東西的局限性實在太大,也沒有人敢動

\[\ \]

update:

有生之年竟然用上了這個東西?

**模擬賽有人搞了一個題:

對於一個無向圖\(G=(V,E),E=(u,v,w)\),其中\(w\)為每條邊的顏色

要求選出一個最大的邊集,滿足:

1.每種顏色\(i\)選出的邊不超過\(c_i\)

2.選出的邊不構成簡單環

然后寫了一次不太正規的擬陣交模板

\(M1\)為個數的擬陣,\(M2\)為生成樹擬陣

解釋在代碼里

int n,m,k;
int A[N],I[N];
// A為顏色個數的限制
int U[N],V[N],W[N],F[N];
// U,V,W為邊
// F 為並查集
int Find(int x){ return F[x]==x?x:F[x]=Find(F[x]); }
int X[N],Y[N],P[N];

// 處理生成樹的情況
vector <int> G[N];
int fa[N],fe[N],dep[N];
void dfs(int u,int f){
	dep[u]=dep[fa[u]=f]+1;
	for(int i:G[u]) {
		int v=U[i]==u?V[i]:U[i];
		if(v==f) continue;
		fe[v]=i,dfs(v,u);
	}
}

int main(){
	freopen("forget.in","r",stdin),freopen("forget.out","w",stdout);
	n=rd(),m=rd(),k=rd();
	rep(i,1,k) A[i]=rd();
	rep(i,1,m) U[i]=rd(),V[i]=rd(),W[i]=rd();
	rep(i,1,n) F[i]=i;
	while(1) {
		int f=0;
        // X, Y分別為 M1,M2的可拓展集合
        // I 記錄已經在選邊方案里的邊
		rep(i,1,m) if(!I[i]) {
			X[i]=A[W[i]]>0,Y[i]=Find(U[i])!=Find(V[i]);
            // 如果X,Y有交,就直接加入集合
			if(X[i] && Y[i]) {
				A[W[i]]--,F[Find(U[i])]=Find(V[i]);
				I[i]=1,f=i;
			}
		} else X[i]=Y[i]=0;
		if(f) continue;
		static queue <int> que;
		while(!que.empty()) que.pop();
        // 預處理當前的生成樹,便於處理M2的限制
		rep(i,1,n) G[i].clear();
		rep(i,1,m) if(I[i]) G[U[i]].pb(i),G[V[i]].pb(i);
		rep(i,1,n) dep[i]=0;
		rep(i,1,n) if(!dep[i]) dfs(i,0);
        // 從X中的某一個點出發
		rep(i,1,m) if(X[i]) que.push(i),P[i]=-1;
		else P[i]=0;
		f=0;
        // 廣搜找交替 替換路徑
		while(!que.empty()) {

			int u=que.front(); que.pop();
            // 找到一條滿足X->Y的交替路徑
			if(Y[u]){ f=u; break; }
			if(I[u]) {
                // u->v,交換之后滿足M1
				rep(v,1,m) if(!P[v] && !I[v] && A[W[v]]+(W[u]==W[v])) P[v]=u,que.push(v);
			} else {
                // 滿足擬陣M2,即交換這條邊之后還是生成樹,可以從目前生成樹上的環上選取能夠替換的邊
				int x=U[u],y=V[u];
				if(Find(x)!=Find(y)) {
					rep(v,1,m) if(!P[v] && I[v]) 
						P[v]=u,que.push(v);
				} else {
					while(x!=y) {
						if(dep[x]<dep[y]) swap(x,y);
						int i=fe[x];
						if(!P[i]) P[i]=u,que.push(i);
						x=fa[x];
					}
				}
			}
		}
		if(!f) break;
        // 放置交替方案
		while(~f) {
			A[W[f]]+=I[f]?1:-1;
			I[f]^=1,f=P[f];
		}
		int cnt=0;
		rep(i,1,m) if(I[i]) cnt++;
        // 重構並查集
		rep(i,1,n) F[i]=i;
		rep(i,1,m) if(I[i]) F[Find(U[i])]=Find(V[i]);
	}
	int cnt=0;
	rep(i,1,m) if(!I[i]) cnt++;
	printf("%d\n",cnt);
	rep(i,1,m) if(!I[i]) printf("%d ",i);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM