導航:首頁 > 源碼編譯 > 凍結掃描演算法例題

凍結掃描演算法例題

發布時間:2022-12-27 00:47:45

1. 卡巴掃描時在「事件」里的「原因」是iswift這個iswift是什麼意思

這並不是什麼蠕蟲、木馬之類的病毒文件,是因為你的系統里有不安全的數據源文件,沒事的,一般盜版的系統里經常會有此類問題,只要設置卡巴斯基不用再提醒,就沒事了

iSwift technology (iSwift技術)

Features: Use technology that can increase scan speed by only scanning new and altered objects. iSwift Works only for NTFS partitions. It identifies files by internal descriptors of the NTFS. The "footprint" of each file is stored in the dedicated database called FIDBOX.

特徵:使用此技術能夠增加掃描的速度,經由只有掃描新的和變更過的檔案。
iSwift只能於NTFS分割磁區下運作。他是由NTFS內部的描述符號來識別檔案。
每個檔案的「痕跡」會被儲存於專用的資料庫,被稱為FIDBOX。

Benefits: The algorithm is fast because no checksum has to be calculated. Works independent of format and size of the file.

優點:因為沒有效驗總和被計算,運演算法則是快速的。
此運作與檔案的格式與大小無關。

Limitations: it only applies to objects in NTFS file systems. Using the iSwift technology is not possible on computers running Microsoft Windows 98SE/ME/XP64 operating system. If the object is moved, it has to be re-scanned. iSwift requires a special driver.

限制:他只適用於NTFS檔案系統中的物件。
在Microsoft Windows 98SE/ME/XP64的作業系統下是不可能使用iSwift技術的。
假如檔案被移動時,它必須再次被掃瞄。iSwift需要特別的驅動程式。

iCheckertechnology(iChecker技術)
文件保護默認只掃描新建或者修改的文件,也就是說,在掃描前文件被添加或者修改過。 iCheckerТМ 和iStreamsТМ 技術使這成為可能。這些技術使用了一個統計表來檢查文件。文件會根據以下的演算法來執行掃描:
用戶或者程序處理的每個文件被組件中斷
文件保護掃描 iChecker和 iStreams資料庫信息來攔截文件。對於這點,如下操作都是可能的:
如果沒有信息在資料庫中被攔截,它會被進行深層病毒掃描。所檢測的文件總數會記錄到一個資料庫中。
如果資料庫有相關文件的信息,那麼文件保護在掃描期間對文件的當前狀態和資料庫記錄的信息進行對比。如果信息是完全匹配,那麼用戶訪問這些文件就不會被掃描。如果文件有某些改變,那就會對它進行詳細掃描,然後把新信息記錄到資料庫中。

主要功能特性是:減少反病毒軟體處理的時間。通過在將來檢測時排除已檢測過的對象來實現。

iChecker技術把反病毒檢測的結果存儲在特殊的資料庫中。只能存儲iChecker模塊所支持的格式的文件信息。
包括:EXE,COM,LNK,TTF,ELF,INF,SYS,CHM,ZIP這些格式。

此項技術的意義在於「為了檢查出哪些文件是已經檢測過並且沒有變化的」。此項技術基於KAV Inspector的原理而運作。資料庫中存儲了已檢測過的文件的CRC記錄。

當用戶打開某文件時,反病毒軟體對此文件進行CRC校驗,處理資料庫里CRC記錄(這里檢查文件是否被修改?)。如果文件沒有變動則不檢測。如果文件感染了未知病毒,採用這種技術也可以檢查出來。

實際上進行CRC校驗庫的比對,會比全面進行文件病毒檢測節省3-5倍的時間。

2. 啟發式掃描技術的避免虛報

正如任何其他的通用檢測技術一樣,啟發式掃描技術有時也會把一個本無病毒的程序指證為染毒程序,這就是所謂的查毒程序虛警或謊報現象。原因很簡單。被檢測程序中含有病毒所使用或含有的可疑功能。例如,QEMM所提供的一個LOADHI.COM程序就會含有以下可疑功能調用。 LoadHi程序中確實含有以上功能調用,而這些功能調用足以觸發檢毒程序的報警裝置。因為LoadHi的作用就是為了分配高端內存,將駐留程序(通常如設備驅動程序等等)裝入內存,然後移入高端內存,等等……,所有這些功能調用都可以找到一個合理的解釋和確認,然而,檢毒程序並不能分辨這些功能調用的真正用意,況且這些功能調用又常常被應用在病毒程序中,因此,可憐的檢測程序只能判定Load Hi程序為「可能是病毒程序」。 虛警(謊報)的後果有多嚴重 如果某個基於上述啟發式代碼掃描技術的病毒檢測程序在檢測到某個文件時彈出報警窗口「該程序可以格式化磁碟且駐留內存」而你自己確切地知道當前被檢測的程序是一個駐留式格式化磁碟工具軟體,這算不算虛警謊報呢? 因為一個這樣的工具軟體顯然應當具備格式化盤以及駐留內存的能力。啟發式代碼檢測程序的判斷顯然正確無誤,這可算做虛警,但不能算做謊報(誤報)。問題在於這個報警是否是「發現病毒」, 如果報警窗口只是說「該程序具備格式化盤和駐留功能」,好,100%正確,但它如果說「發現病毒」,那麼顯然是100%的錯了。關鍵是我們片怎樣看待和理解它真正的報警的含義。檢測程序的使命在於發現和闡述程序內部代碼執行的真正動機,到底這個程序會進行哪些操作,關於這些操作是否預期或合法,尚需要用戶方面的判斷。不幸的是,對於一個一的新手來說,要做出這樣的判斷仍然是有困難的。
不管是虛警也好,誤報或謊報也好,拋開具體的名稱叫法不談,我們決不希望在每次掃描檢測的時候我們的檢測程序無緣由地狂喊「狼來了」,我們要盡力減少和避免這種人為的緊張狀況,那麼如何實現呢?必須努力做好以下幾點:
1、 對於病毒行為的准確把握而給定的關於可疑功能調用集合的精確的定義。除非滿足兩個以上的病毒重要特徵,否則不予報警。
2、 對於常規的程序代碼的和識別能力。某些編譯器提供運行時實時解壓或解碼的功能及服務常式,而這些情形往往是導致檢測時誤報警的原因,應當在檢測程序中加入認知和識別這些情狀的功能模塊,以避免再次誤報。
3、 對於特定程序的識別能力。如上面涉及到的LoadHi及駐留式格式化工具軟體等等。
4、 類似「無罪假定」的功能,首先假定程序和電腦是不含病毒的。許多啟發式代碼分析檢毒軟體具有自學習功能,能夠記信那些並非病毒的文件並在以後的檢測過程中避免再報警。
如何處理虛警謊報
不管採用什麼樣的措施,虛警謊報現象總是要存在的。因此不可避免地用戶要在某些報警信息出現時作出自己的抉擇:是真正病毒還是誤報?也許會有人說:「我怎麼知道被報警的程序到底是病毒還是屬於無辜誤報?」大多數人在問及這個問題的第一反應,是「誰也無法證明和判斷。」事實上是有辦法作出最終判決的,但是這還要取決於應用啟發式代碼分析檢測技術的查病毒程序的具體解釋。 假如檢測軟體僅僅給出「發現可疑病毒功能調用」這樣簡單的警告,信息而沒有更多的輔助信息,對於用戶來說幾乎沒有什麼可資判斷是否真正病毒的實際幫助價值,換個說法,「可能是病毒」似乎永遠沒錯,不必擔負任何責任,而用戶不希望得到這樣模稜兩可的解釋。 相反地,如果檢測軟體把更為具體和實際的信息報告給用戶,比如「警告,當前被檢測程序含有駐留內存和格式化軟硬碟的功能」,類似的情況更能幫助用戶擴清楚到底會發生什麼?該採取怎樣應對措施。比如這種報警是出現在一個字處理編輯軟體中,那麼用戶幾乎可以斷定這是一個病毒。當然如果這種報警是出現在一個駐留格式化盤工具軟體上,用戶大可不必緊張萬分了。這樣以來,報警的可疑病毒常用功能調用都能得到合理的解釋,因而也會得到圓滿正確的處理結果。 自然地, 需要一個有經驗的用戶從同樣的報警信息中推理出一個 「染毒」還是「無毒」的,結論並非每一個用機者可以完全勝任的。因此,如果把這類軟體設計成有某種學習記憶的能力,在第一次掃描時由有經驗的用戶逐一對有疑問的報警信息作好「是」與「非」的判斷,而在以後的各次掃描檢測時,由於軟體學習並記憶了第一次檢測時處理結果,將不再出現同樣的煩人的提示警報。因為不論在什麼情況下,偶爾請教一下某個有經驗的「高手」並不,難難堪的是每次就同樣的問題去麻煩別人。 不管怎樣的缺點和不足,和其它的掃描識別技術相比起來,啟發式代碼分析掃描技術幾乎總能提供足夠的輔助判斷,信息讓我們最終判定被檢測的目標對象是染毒的,亦或是干凈的。啟發式代碼分析檢測技術的實用應用效果如何?啟發式掃描技術仍然是一種正在發展和不斷完善中的新技術,但已經在大量優秀的反病毒軟體中得到迅速的推廣和應用。按照最保守的估計,一個精心設計的演算法支持的啟發式掃描軟體,在不依賴任何對病毒預先的學習和了解的輔助,信息如特徵代碼,指紋字串,校驗和等等的支持下,可以毫不費力地檢查出90%以上的對它來說是完全未知的新病毒。 可能會出現一些個虛報、謊報的情況,適當加以控制,這種誤報的概率可以很容易地被降低在0.1%以下。 傳統掃描技術與啟發式代碼分析掃描技術的結合運用 前面論述了簋多啟發式代碼分析技術的優點和長處,會不會引起某些人的誤解,以為傳統的檢測掃描技術就可以丟棄了呢?情況當然不是這樣。從實際應用的效果看來,傳統的手法由於基於對已知病毒的分析和研究,在檢測時能夠更准確,減少誤報;但如果是對待此前根本沒有見過的新病毒,由於傳統手段的知識庫並不存在該類(種)病毒的特徵數據,則有可能毫無瓜,產生漏報的嚴重後果。而這時基於規則和定義的啟發式代碼分析技術則正好可以大顯身手,使這類新病毒不至成為漏網之魚。傳統與啟發式技術的結合支用,可以使病毒檢測軟體的檢出率提高到前所未有的水平,而另一方面,又大大降低了總的誤報率。
詳見以下測試實驗結果對比數據:
啟發式判定結果 傳統式判定結果 可能的真正結果 干凈 干凈 非常可能就是干凈的 干凈 有毒 很可能誤報 有毒 干凈 很可能有毒 有毒 有毒 極有可能確實染毒 三種技術結合使用 虛報率 10% 1% 1% 漏報率 0.1% 0.001% 0.00001% 某種病毒能夠同時逃脫傳統和啟發式掃描分析的可能性是小的,如果兩種分析的結論相一,致那麼真實的結果往往就如同其判斷結論一樣砍無,疑兩種不同技術對同一檢測樣分析的結果不一致的情況比較少見,這種情形下需藉助另外的分析去得出最後結論。 仍然以 TbScan 6.02為測試舉例,下面是分別使用不同技術和結合應用的測試結果: 測試用技術 總數為7210個樣本的病毒檢出數 檢出率 傳統的 7056 97.86% 啟發式 6465 89.67% 結合應用 7194 99.78% 啟發式反毒技術的未來展望 研究的逐步深入,使技術發展不斷進步。一方面絕大多數反病毒廠家的產品中還未能引入一個較為成功和可靠的啟發式檢測技術的內核,另一方面,即使是在少數依靠的知名反病毒產品中這項技術的運用也還需要經受不斷的完善和發展。任何改良的努力都會有不同程度的質量提高,但是不能企望在沒有虛報為代價的前提下使檢出率達到100%,或者反過來說,大約在相當長的時間里虛報和漏報的概率不可能達到0%。 這聽上去或許有些不可思議,其實不難理解。100%正確的檢測結果只所以不存在,是因為有相當一部分程序(或代碼)介乎於病毒與非病毒之間,即便對於人腦來說,合乎邏輯又合乎病毒定義的結論往往會截然相反。隨便舉一個例子,如果依據廣為接受的病毒的定義:「病毒,就是復制自身的拷貝或改良的復本的一些程序。」那麼,眾所周知的磁碟復製程序 DiskCopy豈不是也落入病毒的分類中了嗎?但是,情況顯然並非如此…… 病毒技術與反病毒技術恰如「道」與「魔」的關系,也許用「道高一尺,魔高一丈」來形容這對矛盾的斗爭和發展進程再為恰當不過了。當反病毒技術的專家學者在研究啟發式代碼分析技術對傳統的特徵代碼掃描法查毒技術進行改革的時候,也確實收到了很顯著的效果,甚至可以說,相對於病毒技術的加密變換(Mutation),尤其是多形、無定形病毒技術(Polymorphsm) 對於傳統反毒技術的沉重打擊,殺了一個漂亮的回馬槍。但是,反毒技術的進步也會從另一方面激發和促使那些喪心病狂的病毒製作者的不斷研製出更新的病毒,具有某種反啟發式掃描技術功能,可以逃避這類檢測技術的新型病毒。但是,值得慶幸的是,即便能夠寫出具有這種能力的病毒,它所需要的技術水準和編程能力要復雜得多,絕不可能象對搞傳統的基於特徵值掃描技術的反毒軟體,那麼容易,任何一個程序的新手只要將原有的病毒稍加改動, 哪怕只是一個位元組,只要恰 好改變了所謂「特徵位元組」, 就可使這種舊病毒的新變種從未經升級的傳統查毒軟體的眼皮底下逃之夭夭。

3. C/C++三角形的掃描轉換演算法誰知道嗎

解:由題意知,a^2c^2-b^2c^2=a^4-b^4
可以化為(a^2-b^2)c^2=(a^2+b^2)(a^2-b^2)
分析:
1)當a^2-b^2不等於0時,上式可化為c^2=a^2+b^2,這時,此三角形為直角三角形,c為斜邊
2)當a^2-b^2=0時,即:a^2=b^2,由於a,b,c均為正數,所以a=b,此三角形是等腰三角形。

4. 運用NStepScan演算法來實現磁碟的掃描!我是要搞磁碟的調度!你能給出這種演算法的VB源代碼嗎

我有C++版本的源碼,你也可以拿去修改成VB的。如果你真的需要,可以聯系我。

5. 哪位高手能給我解釋解釋單片機點陣掃描原理不謝謝

談LED點陣的掃描原理,只要一看LED點陣的原理圖就一目瞭然了,如下圖:

圖中,A--H可以看做行,1--7看做列;假如我們給點陣送人一個列數據0x80(1000 0000),並且同時送人一個行數據0x7f(0111 1111),此時我們就點亮了這個點陣左上角的那顆LED發光管,如果我們不停的行數據:0111 1111;1011 1111;1101 1111;1110 1111;1111 0111;1111 1011;1111 1101;1111 1110,這8個數據周而復始的送人點陣就是行掃描的過程,這個過程一般採用74HC138等解碼器來完成,而在對應的行數據送人的同時也送人1--7的列數據,例如:

行=0111 1111,列=1000 0000

行=1011 1111,列=0100 0000

行=1101 1111,列=1010 0000

行=1110 1111,列=1001 0000

行=1111 0111,列=1000 1000

行=1111 1011,列=1000 0100

行=1111 1101,列=1000 0010

行=1111 1110,列=1000 0001

此時程序循環執行的結果會在點陣屏上顯示左上至右下的對角斜線。

仔細想想應該不難理解。

在代碼編寫上,實現上述功能有很多方法,最長用的就是for循環,如果你網路資料會發現,大凡點陣顯示代碼中都會在顯示函數中引用for循環,而且根據點陣數的不同會有:

for(i=0;i<8;i++)或for(i=0;i<16;i++)或for(i=0;i<32;i++)這就是對於8行、16行、32行點陣的掃描演算法。

就說到這里吧,更多的知識請網路搜索吧。

6. 磁碟調度演算法中的~掃描演算法~還有~循環掃描演算法~,需要移動到0磁軌再返回碼麻煩高手指點,學校發的破書寫

總是按一個方向移動磁碟臂(向0反方向移動),處理完編號最高的磁軌後,移動到具有讀寫請求的編號最低的磁軌,然後繼續向上移動。

這里你反過來理解就好了,就是從高到低

這里先訪問168,然後是140,117,小於117的磁軌已經沒有請求了,此時磁碟臂應該回到288,然後向0方向移動

7. 掃描演算法和電梯調度演算法區別

掃描演算法和電梯調度演算法沒有區別。掃描演算法通常稱為電梯調度演算法,但是會出現餓死現象。

8. 計算機圖形學:直線段掃描轉換演算法

//數值微分演算法(DDA演算法)
#include<iostream>
using namespace std;
int main()
{
float x0,y0,x1,y1,x2,y2;
cin>>x1>>y1;
cin>>x0>>y0;
float k;
k=(y1-y0)/(x1-x0);
if(k<1)
{
x2=x1+1;
y2=y2+k;
}
else if(k>=1)
{
y2=y1+1;
x2=1/k+x1;
}
cout<<x2<<" "<<y2<<endl;
return 0;
}
//中點劃線演算法
#include<iostream>
using namespace std;
int main()
{ float x,y;
float x0,y0,x1,y1;
cin>>x0>>y0>>x1>>y1;
float a,b,c;
a=y0-y1;
b=x1-x0;
c=x0*y1-x1*y0;
float sum;
sum=a*x+b*y+c;
float Xq,Yq;
float Xm,Ym;
Xm=x0+1;
Ym=y0+0.5;
float d;
d=a*Xm+b*Ym+c;
if(d<0)
{Xq=x0+1; Yq=y0+1; }
else if(d>0)
{ Xq=x0+1; Yq=y0; }
else if(d=0)
{ Xq=x0+1; Yq=y0; }
cout<<Xq<<" "<<Yq<<endl;return 0;
}
//Bresenham演算法//有一個整數數組,請求出兩兩之差絕對值最大的值(最小的值)
#include<iostream>
using namespace std;
int jisuan(int a,int b)
{ int des=0; des=a-b; if(des<0)
des=-des;
return des;}
int main()
{ int dec=0; int max=0; int a[5]={0,2,5,9,4}; for(int i=1;i<5;i++)
{ dec=jisuan(a[i],a[i-1]); if(max<dec) max=dec; }
cout<<max<<endl;
return 0;
}
不好意思,最後一個是我寫的另一個代碼,貼錯了

9. pascal題目

2003年國家集訓隊論文,王知昆,淺談用極大化思想解決最大子矩形問題
網上有的,O(n²)的復雜度,n,m是5000都能1秒出解

淺談用極大化思想解決最大子矩形問題

福州第三中學 王知昆

【摘要】
本文針對一類近期經常出現的有關最大(或最優)子矩形及相關變形問題,介紹了極大化思想在這類問題中的應用。分析了兩個具有一定通用性的演算法。並通過一些例題講述了這些演算法選擇和使用時的一些技巧。

【關鍵字】 矩形,障礙點,極大子矩形

【正文】
一、 問題
最大子矩形問題:在一個給定的矩形網格中有一些障礙點,要找出網格內部不包含任何障礙點,且邊界與坐標軸平行的最大子矩形。

這是近期經常出現的問題,例如冬令營2002的《奶牛浴場》,就屬於最大子矩形問題。

Winter Camp2002,奶牛浴場
題意簡述:(原題見論文附件)
John要在矩形牛場中建造一個大型浴場,但是這個大型浴場不能包含任何一個奶牛的產奶點,但產奶點可以出在浴場的邊界上。John的牛場和規劃的浴場都是矩形,浴場要完全位於牛場之內,並且浴場的輪廓要與牛場的輪廓平行或者重合。要求所求浴場的面積盡可能大。
參數約定:產奶點的個數S不超過5000,牛場的范圍N×M不超過30000×30000。

二、 定義和說明
首先明確一些概念。

1、 定義有效子矩形為內部不包含任何障礙點且邊界與坐標軸平行的子矩形。如圖所示,第一個是有效子矩形(盡管邊界上有障礙點),第二個不是有效子矩形(因為內部含有障礙點)。

2、 極大有效子矩形:一個有效子矩形,如果不存在包含它且比它大的有效子矩形,就稱這個有效子矩形為極大有效子矩形。(為了敘述方便,以下稱為極大子矩形)

3、 定義最大有效子矩形為所有有效子矩形中最大的一個(或多個)。以下簡稱為最大子矩形。

三、 極大化思想
【定理1】在一個有障礙點的矩形中的最大子矩形一定是一個極大子矩形。
證明:如果最大子矩形A不是一個極大子矩形,那麼根據極大子矩形的定義,存在一個包含A且比A更大的有效子矩形,這與「A是最大子矩形」矛盾,所以【定理1】成立。

四、 從問題的特徵入手,得到兩種常用的演算法
定理1雖然很顯然,但卻是很重要的。根據定理1,我們可以得到這樣一個解題思路:通過枚舉所有的極大子矩形,就可以找到最大子矩形。下面根據這個思路來設計演算法。
約定:為了敘述方便,設整個矩形的大小為n×m,其中障礙點個數為s。

演算法1
演算法的思路是通過枚舉所有的極大子矩形找出最大子矩形。根據這個思路可以發現,如果演算法中有一次枚舉的子矩形不是有效子矩形、或者不是極大子矩形,那麼可以肯定這個演算法做了「無用功」,這也就是需要優化的地方。怎樣保證每次枚舉的都是極大子矩形呢,我們先從極大子矩形的特徵入手。

【定理2】:一個極大子矩形的四條邊一定都不能向外擴展。更進一步地說,一個有效子矩形是極大子矩形的充要條件是這個子矩形的每條邊要麼覆蓋了一個障礙點,要麼與整個矩形的邊界重合。

定理2的正確性很顯然,如果一個有效子矩形的某一條邊既沒有覆蓋一個障礙點,又沒有與整個矩形的邊界重合,那麼肯定存在一個包含它的有效子矩形。根據定理2,我們可以得到一個枚舉極大子矩形的演算法。為了處理方便,首先在障礙點的集合中加上整個矩形四角上的點。每次枚舉子矩形的上下左右邊界(枚舉覆蓋的障礙點),然後判斷是否合法(內部是否有包含障礙點)。這樣的演算法時間復雜度為O(S5),顯然太高了。考慮到極大子矩形不能包含障礙點,因此這樣枚舉4個邊界顯然會產生大量的無效子矩形。
考慮只枚舉左右邊界的情況。對於已經確定的左右邊界,可以將所有處在這個邊界內的點按從上到下排序,如圖1中所示,每一格就代表一個有效子矩形。這樣做時間復雜度為O(S3)。由於確保每次得到的矩形都是合法的,所以枚舉量比前一種演算法小了很多。但需要注意的是,這樣做枚舉的子矩形雖然是合法的,然而不一定是極大的。所以這個演算法還有優化的餘地。通過對這個演算法不足之處的優化,我們可以得到一個高效的演算法。
回顧上面的演算法,我們不難發現,所枚舉的矩形的上下邊界都覆蓋了障礙點或者與整個矩形的邊界重合,問題就在於左右邊界上。只有那些左右邊界也覆蓋了障礙點或者與整個矩形的邊界重合的有效子矩形才是我們需要考察的極大子矩形,所以前面的演算法做了不少「無用功」。怎麼減少「無用功」呢,這里介紹一種演算法(演算法1),它可以用在不少此類題目上。
演算法的思路是這樣的,先枚舉極大子矩形的左邊界,然後從左到右依次掃描每一個障礙點,並不斷修改可行的上下邊界,從而枚舉出所有以這個定點為左邊界的極大子矩形。考慮如圖2中的三個點,現在我們要確定所有以1號點為左邊界的極大矩形。先將1號點右邊的點按橫坐標排序。然後按從左到右的順序依次掃描1號點右邊的點,同時記錄下當前的可行的上下邊界。
開始時令當前的上下邊界分別為整個矩形的上下邊界。然後開始掃描。第一次遇到2號點,以2號點作為右邊界,結合當前的上下邊界,就得到一個極大子矩形(如圖3)。同時,由於所求矩形不能包含2號點,且2號點在1號點的下方,所以需要修改當前的下邊界,即以2號點的縱坐標作為新的下邊界。第二次遇到3號點,這時以3號點的橫坐標作為右邊界又可以得到一個滿足性質1的矩形(如圖4)。類似的,需要相應地修改上邊界。以此類推,如果這個點是在當前點(確定左邊界的點)上方,則修改上邊界;如果在下方,則修改下邊界;如果處在同一行,則可中止搜索(因為後面的矩形面積都是0了)。由於已經在障礙點集合中增加了整個矩形右上角和右下角的兩個點,所以不會遺漏右邊界與整個矩形的右邊重合的極大子矩形(如圖5)。需要注意的是,如果掃描到的點不在當前的上下邊界內,那麼就不需要對這個點進行處理。
這樣做是否將所有的極大子矩形都枚舉過了呢?可以發現,這樣做只考慮到了左邊界覆蓋一個點的矩形,因此我們還需要枚舉左邊界與整個矩形的左邊界重合的情況。這還可以分為兩類情況。一種是左邊界與整個舉行的左邊界重合,而右邊界覆蓋了一個障礙點的情況,對於這種情況,可以用類似的方法從右到左掃描每一個點作為右邊界的情況。另一種是左右邊界均與整個矩形的左右邊界重合的情況,對於這類情況我們可以在預處理中完成:先將所有點按縱坐標排序,然後可以得到以相鄰兩個點的縱坐標為上下邊界,左右邊界與整個矩形的左右邊界重合的矩形,顯然這樣的矩形也是極大子矩形,因此也需要被枚舉到。
通過前面兩步,可以枚舉出所有的極大子矩形。演算法1的時間復雜度是O(S2)。這樣,可以解決大多數最大子矩形和相關問題了。

雖然以上的演算法(演算法1)看起來是比較高效的,但也有使用的局限性。可以發現,這個演算法的復雜度只與障礙點的個數s有關。但對於某些問題,s最大有可能達到n×m,當s較大時,這個演算法就未必能滿足時間上的要求了。能否設計出一種依賴於n和m的演算法呢?這樣在演算法1不能奏效的時候我們還有別的選擇。我們再重新從最基本的問題開始研究。

演算法2
首先,根據定理1:最大有效子矩形一定是一個極大子矩形。不過與前一種演算法不同的是,我們不再要求每一次枚舉的一定是極大子矩形而只要求所有的極大子矩形都被枚舉到。看起來這種演算法可能比前一種差,其實不然,因為前一種演算法並不是完美的:雖然每次考察的都是極大子矩形,但它還是做了一定量的「無用功」。可以發現,當障礙點很密集的時候,前一種演算法會做大量沒用的比較工作。要解決這個問題,我們必須跳出前面的思路,重新考慮一個新的演算法。注意到極大子矩形的個數不會超過矩形內單位方格的個數,因此我們有可能找出一種時間復雜度是O(N×M)的演算法。

定義:
有效豎線:除了兩個端點外,不覆蓋任何障礙點的豎直線段。
懸線:上端點覆蓋了一個障礙點或達到整個矩形上端的有效豎線。如圖所示的三個有效豎線都是懸線。

對於任何一個極大子矩形,它的上邊界上要麼有一個障礙點,要麼和整個矩形的上邊界重合。那麼如果把一個極大子矩形按x坐標不同切割成多個(實際上是無數個)與y軸垂直的線段,則其中一定存在一條懸線。而且一條懸線通過盡可能地向左右移動恰好能得到一個子矩形(未必是極大子矩形,但只可能向下擴展)。通過以上的分析,我們可以得到一個重要的定理。

【定理3】:如果將一個懸線向左右兩個方向盡可能移動所得到的有效子矩形稱為這個懸線所對應的子矩形,那麼所有懸線所對應的有效子矩形的集合一定包含了所有極大子矩形的集合。

定理3中的「盡可能」移動指的是移動到一個障礙點或者矩形邊界的位置。
根據【定理3】可以發現,通過枚舉所有的懸線,就可以枚舉出所有的極大子矩形。由於每個懸線都與它底部的那個點一一對應,所以懸線的個數=(n-1)×m(以矩形中除了頂部的點以外的每個點為底部,都可以得到一個懸線,且沒有遺漏)。如果能做到對每個懸線的操作時間都為O(1),那麼整個演算法的復雜度就是O(NM)。這樣,我們看到了解決問題的希望。
現在的問題是,怎樣在O(1)的時間內完成對每個懸線的操作。我們知道,每個極大子矩形都可以通過一個懸線左右平移得到。所以,對於每個確定了底部的懸線,我們需要知道有關於它的三個量:頂部、左右最多能移動到的位置。對於底部為(i,j)的懸線,設它的高為hight[i,j],左右最多能移動到的位置為left[i,j],right[i,j]。為了充分利用以前得到的信息,我們將這三個函數用遞推的形式給出。

對於以點(i,j)為底部的懸線:
如果點(i-1,j)為障礙點,那麼,顯然以(i,j)為底的懸線高度為1,而且左右均可以移動到整個矩形的左右邊界,即

如果點(i-1,j)不是障礙點,那麼,以(i,j)為底的懸線就等於以(i-1,j)為底的懸線+點(i,j)到點(i-1,j)的線段。因此,height[i,j]=height[i-1,j]+1。比較麻煩的是左右邊界,先考慮left[i,j]。如下圖所示,(i,j)對應的懸線左右能移動的位置要在(i-1,j)的基礎上變化。
即left[i,j]=max

right[i,j]的求法類似。綜合起來,可以得到這三個參數的遞推式:

這樣做充分利用了以前得到的信息,使每個懸線的處理時間復雜度為O(1)。對於以點(i,j)為底的懸線對應的子矩形,它的面積為(right[i,j]-left[i,j])*height[i,j]。
這樣最後問題的解就是:
Result=
max
整個演算法的時間復雜度為O(NM),空間復雜度是O(NM)。

兩個演算法的對比:
以上說了兩種具有一定通用性的處理演算法,時間復雜度分別為O(S2)和O(NM)。兩種演算法分別適用於不同的情況。從時間復雜度上來看,第一種演算法對於障礙點稀疏的情況比較有效,第二種演算法則與障礙點個數的多少沒有直接的關系(當然,障礙點較少時可以通過對障礙點坐標的離散化來減小處理矩形的面積,不過這樣比較麻煩,不如第一種演算法好),適用於障礙點密集的情況。

五、 例題
將前面提出的兩種演算法運用於具體的問題。
1、 Winter Camp2002,奶牛浴場
分析:
題目的數學模型就是給出一個矩形和矩形中的一些障礙點,要求出矩形內的最大有效子矩形。這正是我們前面所討論的最大子矩形問題,因此前兩種演算法都適用於這個問題。
下面分析兩種演算法運用在本題上的優略:
對於第一種演算法,不用加任何的修改就可以直接應用在這道題上,時間復雜度為O(S2),S為障礙點個數;空間復雜度為O(S)。
對於第二種演算法,需要先做一定的預處理。由於第二種演算法復雜度與牛場的面積有關,而題目中牛場的面積很大(30000×30000),因此需要對數據進行離散化處理。離散化後矩形的大小降為S×S,所以時間復雜度為O(S2),空間復雜度為O(S)。說明:需要注意的是,為了保證演算法能正確執行,在離散化的時候需要加上S個點,因此實際需要的時間和空間較大,而且編程較復雜。
從以上的分析來看,無論從時空效率還是編程復雜度的角度來看,這道題採用第一種演算法都更優秀。

2、 OIBH模擬賽1,提高組,Candy
題意簡述:(原題見論文附件)
一個被分為 n*m 個格子的糖果盒,第 i 行第 j 列位置的格子裡面有 a [i,j] 顆糖。但糖果盒的一些格子被老鼠洗劫。現在需要盡快從這個糖果盒裡面切割出一個矩形糖果盒,新的糖果盒不能有洞,並且希望保留在新糖果盒內的糖的總數盡量多。
參數約定:1 ≤ n,m ≤ 1000

分析
首先需要注意的是:本題的模型是一個矩陣,而不是矩形。在矩陣的情況下,由於點的個數是有限的,所以又產生了一個新的問題:最大權值子矩陣。

定義:
有效子矩陣為內部不包含任何障礙點的子矩形。與有效子矩形不同,有效子矩陣地邊界上也不能包含障礙點。
有效子矩陣的權值(只有有效子矩形才有權值)為這個子矩陣包含的所有點的權值和。
最大權值有效子矩陣為所有有效子矩陣中權值最大的一個。以下簡稱為最大權值子矩陣。

本題的數學模型就是正權值條件下的最大權值子矩陣問題。再一次利用極大化思想,因為矩陣中的權值都是正的,所以最大權值子矩陣一定是一個極大子矩陣。所以我們只需要枚舉所有的極大子矩陣,就能從中找到最大權值子矩陣。同樣,兩種演算法只需稍加修改就可以解決本題。下面分析兩種演算法應用在本題上的優略:
對於第一種演算法,由於矩形中障礙點的個數是不確定的,而且最大有可能達到N×M,這樣時間復雜度有可能達到O(N2M2),空間復雜度為O(NM)。此外,由於矩形與矩陣的不同,所以在處理上會有一些小麻煩。
對於第二種演算法,稍加變換就可以直接使用,時間復雜度為O(NM),空間復雜度為O(NM)。

可以看出,第一種演算法並不適合這道題,因此最好還是採用第二種演算法。

3、 Usaco Training, Section 1.5.4, Big Barn
題意簡述(原題見論文附件)
Farmer John想在他的正方形農場上建一個正方形谷倉。由於農場上有一些樹,而且Farmer John又不想砍這些樹,因此要找出最大的一個不包含任何樹的一塊正方形場地。每棵樹都可以看成一個點。
參數約定:牛場為N×N的,樹的棵數為T。N≤1000,T≤10000。
分析:
這題是矩形上的問題,但要求的是最大子正方形。首先,明確一些概念。
1、 定義有效子正方形為內部不包含任何障礙點的子正方形
2、 定義極大有效子正方形為不能再向外擴展的有效子正方形,一下簡稱極大子正方形
3、 定義最大有效子正方形為所有有效子正方形中最大的一個(或多個),以下簡稱最大子正方形。

本題的模型有一些特殊,要在一個含有一些障礙點的矩形中求最大子正方形。這與前兩題的模型是否有相似之處呢?還是從最大子正方形的本質開始分析。
與前面的情況類似,利用極大化思想,我們可以得到一個定理:
【定理4】:在一個有障礙點的矩形中的最大有效子正方形一定是一個極大有效子正方形。

根據【定理4】,我們只需要枚舉出所有的極大子正方形,就可以從中找出最大子正方形。極大子正方形有什麼特徵呢?所謂極大,就是不能再向外擴展。如果是極大子矩形,那麼不能再向外擴展的充要條件是四條邊上都覆蓋了障礙點(【定理2】)。類似的,我們可以知道,一個有效子正方形是極大子正方形的充要條件是它任何兩條相鄰的邊上都覆蓋了至少一個障礙點。根據這一點,可以得到一個重要的定理。
【定理5】:每一個極大子正方形都至少被一個極大子矩形包含。且這個極大子正方形一定有兩條不相鄰的邊與這個包含它的極大子矩形的邊重合。

根據【定理5】,我們只需要枚舉所有的極大子矩形,並檢查它所包含的極大子正方形(一個極大子矩形包含的極大子正方形都是一樣大的)是否是最大的就可以了。這樣,問題的實質和前面所說的最大子矩形問題是一樣的,同樣的,所採用的演算法也是一樣的。
因為演算法1和演算法2都枚舉出了所有的極大子矩形,因此,演算法1和演算法2都可以用在本題上。具體的處理方法如下:對於每一個枚舉出的極大子矩形,如圖所示,如果它的邊長為a、b,那麼它包含的極大子正方形的邊長即為min(a,b)。
考慮到N和T的大小不同,所以不同的演算法會有不同的效果。下面分析兩種演算法應用在本題上的優略。
對於第一種演算法,時間復雜度為O(T2),對於第二種演算法,時間復雜度為O(N2)。因為N<T,所以從時間復雜度的角度看,第二種演算法要比第一種演算法好。考慮到兩個演算法的空間復雜度都可以承受,所以選擇第二種演算法較好些。
以下是第一種和第二種演算法編程實現後在USACO Training Program Gateway上的運行時間。可以看出,在數據較大時,演算法2的效率比演算法1高。

演算法1:
Test 1: 0.009375
Test 2: 0.009375
Test 3: 0.009375
Test 4: 0.009375
Test 5: 0.009375
Test 6: 0.009375
Test 7: 0.021875
Test 8: 0.025
Test 9: 0.084375
Test 10: 0.3875
Test 11: 0.525
Test 12: 0.5625
Test 13: 0.690625
Test 14: 0.71875
Test 15: 0.75 演算法2:
Test 1: 0.009375
Test 2: 0.009375
Test 3: 0.009375
Test 4: 0.009375
Test 5: 0.009375
Test 6: 0.00625
Test 7: 0.009375
Test 8: 0.009375
Test 9: 0.0125
Test 10: 0.021875
Test 11: 0.028125
Test 12: 0.03125
Test 13: 0.03125
Test 14: 0.03125
Test 15: 0.034375

以上,利用極大化思想和前面設計的兩個演算法,通過轉換模型,解決了三個具有一定代表性的例題。解題的關鍵就是如何利用極大化思想進行模型轉換和如何選擇演算法。

五、小結
設計演算法要從問題的基本特徵入手,找出解題的突破口。本文介紹了兩種適用於大部分最大子矩形問題及相關變型問題的演算法,它們設計的突破口就是利用了極大化思想,找到了枚舉極大子矩形這種方法。
在效率上,兩種演算法對於不同的情況各有千秋。一個是針對障礙點來設計的,因此復雜度與障礙點有關;另一個是針對整個矩形來設計的,因此復雜度與矩形的面積有關。雖然兩個演算法看起來有著巨大的差別,但他們的本質是相通的,都是利用極大化思想,從枚舉所有的極大有效子矩形入手,找出解決問題的方法。

需要注意的是,在解決實際問題是僅靠套用一些現有演算法是不夠的,還需要對問題進行全面、透徹的分析,找出解題的突破口。
此外,如果採用極大化思想,前面提到的兩種演算法的復雜度已經不能再降低了,因為極大有效子矩形的個數就是O(NM)或O(S2)的。如果採用其他演算法,理論上是有可能進一步提高演算法效率,降低復雜度的。

七、 附錄:
1、幾個例題的原題。 見論文附件.doc

2、例題的程序。 見論文附件.doc
說明:所有程序均在Free Pascal IDE for Dos, Version 0.9.2上編譯運行

參考書目
1、 信息學奧林匹克 競賽指導
----1997~1998競賽試題解析
吳文虎 王建德 著
2、 IOI99中國集訓隊優秀論文集
3、 信息學奧林匹克(季刊)
4、 《金牌之路 競賽輔導》
江文哉主編 陝西師范大學出版社出版

10. GSP演算法的GSP演算法描述

GSP演算法 基本步驟如下:
1)掃描序列資料庫,得到長度為1的序列模式L1,作為初始的種子集
2)根據長度為i 的種子集Li ,通過連接操作和修剪操作生成長度為i+1的候選序列模式Ci+1;然後掃描序列資料庫,計算每個候選序列模式的支持度,產生長度為i+1的序列模式Li+1,並將Li+1作為新的種子集
3)重復第二步,直到沒有新的序列模式或新的候選序列模式產生為止
產生候選序列模式主要分兩步:
連接階段:如果去掉序列模式s1的第一個項目與去掉序列模式s2的最後一個項目所得到的序列相同,則可以將s1與s2進行連接,即將s2的最後一個項目添加到s1中
修切階段:若某候選序列模式的某個子序列不是序列模式,則此候選序列模式不可能是序列模式,將它從候選序列模式中刪除
候選序列模式[ 的支持度計算:對於給定的候選序列模式集合C,掃描序列資料庫,對於其中的每一條序列s,找出集合C中被s所包含的所有候選序列模式,並增加其支持度計數
GSP需要多次掃描序列資料庫,在第一次掃描中,對所有的單個項目(1—序列模式)進行計數。利用頻繁1—序列模式生成候選頻繁2—序列模式,進行第二次掃描並求候選頻繁2—序列模式的支持數。使用頻繁2—序列模式生成候選頻繁3—序列模式,重復以上過程,直到找出所有的頻繁序列模式。 哈希樹GSP 採用哈希樹存儲候選序列模式。哈希樹的節點分為三類: 1、根節點;
2、內部節點;
3、葉子節點。
根節點和內部節點中存放的是一個哈希表,每個哈希表項指向其它的節點。而葉子節點內存放的是一組候選序列模式。 從根節點開始,用哈希函數對序列的第一個項目做映射來決定從哪個分支向下,依次在第n層對序列的第n個項目作映射來決定從哪個分支向下,直到到達一個葉子節點。將序列儲存在此葉子節點。
初始時所有節點都是葉子節點,當一個葉子節點所存放的序列數目達到一個閾值,它將轉化為一個內部節點。
候選序列模式支持度的計算
給定一個序列s是序列資料庫的一個記錄:
1)對於根節點,用哈希函數對序列s的每一個單項做映射來並從相應的表項向下迭代的進行操作 2)。
2)對於內部節點,如果s是通過對單項x做哈希映射來到此節點的,則對s中每一個和x在一個元素中的單項以及在x所在元素之後第一個元素的第一個單項做哈希映射,然後從相應的表項向下迭代做操作 2)或 3)。
3)對一個葉子節點,檢查每個候選序列模式c是不是s的子序列.如果是相應的候選序列模式支持度加一。
這種計算候選序列的支持度的方法避免了大量無用的掃描,對於一條序列,僅檢驗那些最有可能成為它子序列的候選序列模式。掃描的時間復雜度由O(n*m)降為O(n*t),其中n表示序列數量,m表示候選序列模式的數量,t代表哈希樹葉子節點的最大容量

閱讀全文

與凍結掃描演算法例題相關的資料

熱點內容
程序員編迷你世界代碼 瀏覽:893
php取現在時間 瀏覽:246
單片機高吸收 瀏覽:427
怎麼區分五代頭是不是加密噴頭 瀏覽:244
hunt測試伺服器是什麼意思 瀏覽:510
2013程序員考試 瀏覽:641
畢業論文是pdf 瀏覽:736
伺服器跑網心雲劃算嗎 瀏覽:471
單片機定時器計數初值的計算公式 瀏覽:801
win7控制台命令 瀏覽:567
貓咪成年app怎麼升級 瀏覽:692
360有沒有加密軟體 瀏覽:315
清除cisco交換機配置命令 瀏覽:751
華為刪除交換機配置命令 瀏覽:473
shell打包命令 瀏覽:827
加密狗插上輸不了密碼 瀏覽:187
大學單片機相關科目 瀏覽:23
自己建了伺服器地址 瀏覽:698
命令按鈕的屬性設置 瀏覽:965
證券技術分析pdf 瀏覽:779