帶你了解兩種線性規划的方法:稀疏矩陣存儲和預處理


摘要:本文為大家帶來線性規划的稀疏矩陣存儲和數據預處理。

本文分享自華為雲社區《線性規划--稀疏矩陣》,原文作者:Bale10 。

隨着AI時代的發展,線性規划問題的規模越來越大是一種必然。面對大規模的線性規划問題,如何存儲數據,使得存儲空間節省以避免資源的浪費,並且使得數據的查詢、修改和增刪方便快捷,是一個急需解決的問題。本文為大家帶來線性規划的稀疏矩陣存儲和數據預處理。

稀疏矩陣

LP的規模通常是由約束矩陣A的規模決定的,矩陣的元素通常用8個字節的double型儲存,假設矩陣有m行,n列,則直接儲存A需要8mn字節。如果A有10000行,20000列(不是特別大規模的),那么需要1.6G內存儲存A,一方面內存要求高,另一方面對矩陣A的操作困難。大規模LP通常含有大量的零元,非零元占比非常小,這個性質稱為稀疏性,即A為稀疏矩陣。

稀疏矩陣儲存

稀疏矩陣的數據結構設計應該考慮下面三個因素:

  1. 僅存非零元,一個好的稀疏矩陣數據結構應該僅存A的非零元,而不存大量的零元。這樣做的優點有三。首先,節省內存,使得大型稀疏矩陣能存在內存中。其次,若僅存非零元內存也放不下,則必須借助於外存,而從外存存取數據的速度一般比從內存存取數據慢得多,因此,在使用外存的情況我們也希望僅存非零元。第三,涉及零元的操作可以不執行,從而顯著節約計算時間。
  2. 非零元的產生--填入元,一個稀疏矩陣,在高斯消去(或LU分解)過程中,原來的零元可能要變成非零元。這種在消去過程中,由零元變成的非零元,叫做填入元;在整個消去過程中產生的填入元的個數,叫做填入量。如果一個十分稀疏的矩陣,經過上述消去運算后產生大量的填入元,則稀疏性就會消失,因此,保持矩陣的稀疏性是利用其稀疏性的前提。如何設法使消去過程中產生盡可能少的填入元是算法需要考慮的。稀疏矩陣是一個動態的數據結構,特別是經常需要插入非零元或刪去非零元。因此,一個好的稀疏矩陣數據結構必須便於插入或刪除。
  3. 稀疏矩陣的數據結構和消去算法緊密相關,在考慮稀疏矩陣的數據結構時,必須同時考慮到消去算法,數據結構必須盡可能便於其算法的實現。

線性表

最簡單的稀疏矩陣存儲方案是線性表。為了具體起見,我們以下列稀疏矩陣A_5為例:

將非零元按列存放到數組CE中:

CE中相應非零元的行號記錄在數組IROW中:

為了給出每個非零元在的列號,引入一個指針數組ICFR,ICFR(j)表示第j列第一個非零元在CE中的位置。

ICFR的長度為N+1,ICFR(N+1)表示最后一個元存放在第$N$列末元位置加1的位置上,這是為了便於計算最后一列非零元個數而引入的。這種存儲方案所需要存儲量為2NZ+N+1。它的優點是存儲量小,結構簡單,單缺點是不便於插入和刪除,若要插入一個非零元,位於它下面的非零元必須向下移動一個位置,這是非常浪費時間的。

在程序中為了允許插入非零元,通常要說明一個較大的數組。上述是將A按列存放,當然也可以按行存放。經常的做法是先將A進行LU分解,然后將下三角形矩陣L按列存放,上三角矩陣U按行存放。

單鏈表

為了克服線性表不便於插入和刪除的缺點,引入鏈表數據結構。即在上述線性表中增加一個鏈表指針數組LNXT,LNXT(i)表示第i個非零元的下一個非零元的位置,同時用數組ICNZ記錄給列非零元的個數。這種鏈形表稱為單鏈表,又稱為列鏈表。仍然以上述稀疏矩陣A_5為例,並按列存放:

從上述表結構可以看出,對稀疏矩陣的每一非零元,表中有一個三元組(行號,元素,下一個元素位置),即

每列非零元,均以鏈指針$LNXT$連起來,每列最后一個非零元,鏈指針為0,表示鏈的結束。而指針數組$ICFR$指示每列的首元位置。

  1. 同一列非零元不一定要挨着存放,因為每個非零元均用$LNXT$指出下一個元的位置,所以下一個元可以放在表中任何位置。
  2. 插入和刪除一個元,不需要移動其它元素,只需要改變指針。

采用鏈表的優點是便於插入或刪除;缺點是訪問鏈表中任何一個元均需要從一列的第一個非零元開始順序找下去,而且均需要間接訪問,所以比訪問線性表要慢。

雙鏈表

雙鏈表是在單鏈表基礎上增加ICOL(i)第i個非零元列號,RNXT(i)第i個非零元行鏈指針,即該行下一非零元的位置,以及IRFR(i)第i行的第一個非零元在鏈表中的位置。

這種雙鏈表數據結構對於處理結構不對稱的稀疏矩陣是十分方便的,它具有單鏈表的優點,即便於插入和刪去。

在雙鏈表中插入或刪除一個元的操作和單鏈表時相同,只需注意插入或刪除一個元不僅要修改列鏈和空單元鏈,而且要修改行鏈。

設計好稀疏矩陣的數據結構是稀疏矩陣算法的關鍵之一。好的稀疏矩陣數據結構,不僅要節約存儲,而且要便於查找、插入和刪除,以及便於稀疏矩陣算法的實現。數據結構對算法設計有根本性影響。通常先用鏈表建立稀疏矩陣,並進行一次假高斯消去、插入填入元、求出非零元總數,然后轉換為線性表,以便快速進行求解。

數據預處理

線性規划問題的規模越來越大,含有成千上萬個約束和變量的問題非常常見,面臨着數據的儲存和處理效率問題,大規模問題一般都是由模型支持工具自動生成的,往往存在大量冗余的約束和變量,在算法求解之前進行數據預處理是必要的。

主要目的

  1. 化約冗余約束,減少約束矩陣非零元素,提高稀疏度,減少問題規模,節省內存;
  2. 改善模型的數值特征,提高問題的數值穩定性;
  3. 在不求解問題的情況下判定問題無可行解或無界。

主要挑戰

  1. 提升復雜預處理方法的性能;
  2. 確定不同預處理方法的作用次序和作用次數;
  3. 確定預處理何時停止;
  4. 設計預處理並行框架。

預處理方法

不可行性

空行和空列

固定變量

強制行

比例行

平行行

對偶規定

兩行非零元消去

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

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



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