把一堆自然數平均分成M組,每組自然數之和爲K,如何分組才能讓各組的K值最接近?

現在要爲一個網站設計一個圖片排版。假設圖片分成三列顯示,每列垂直排列10張圖片,要求這三列的圖片高度之和最後相等。由於圖片是用戶上傳,所以圖片尺寸無法控制,且要保持原寬高比,不能對圖片進行剪切。


這個算法要求大概是這樣的:


1. 把一組自然數分成 M 組,每組 N 個 ;
2. 每組自然數相加之和爲 K ;
問題: 怎樣分配,才能使得 K1,K2,K3....KM 之間的差值較小?
實際應用 M 在 4 到 8 之間,N 在 10 到 20 之間。現在求一個比較優化的算法,最後K1 K2 K3...KM之間的差值越小越好。


補充下問題:
1.考慮排版的美感,所有上傳的圖片都進行縮放,使之寬度相等。且圖片的寬高比相差很大,換句話說,寬度相等後,圖片之間的高度差值很大。
2.每列存放的圖片數量基本相當,視覺上給人感覺是均勻分佈的,比較和諧。不能爲了高度相同,第一列出現10張小圖片,第二列只放三張大圖片。


*** 找到一個類似網站,該網站對每張圖片高度進行小範圍剪切(其實是在瀏覽器中隱藏部分高度),最後每組高度之和都一樣。但不知道他們根據什麼規則分組,我上傳了幾張新圖片測試,每次有新圖片之後,分組情況都不一樣。


比較簡單近似算法:


這些自然數按從大到小排序,然後依次分配到 M 組中,每次往當前和最小的組最後添加。


然後,如評論所說需要定義目標函數,也就是量化的評價某一個放法(configuration)的好壞程度,比如越好這個值就越大。然後就可以一定程度的優化上面的算法:


還是從大到小排序,一次往上放
定義一個概率函數,使得某個組當前的和越小其被選中的概率越大。根據這個概率密度函數,隨機選一個組添加。
添加完所有的數


上面的添加完之後可以得到一個 configuration,計算一下目標函數的值。重複幾次,因爲有隨機數,所以每次的結果不盡相同,根據工程需要確定重複次數。最後採用找到的裏面目標函數最大的一組值。可以用最開始的貪心算法的結果也作爲最初的候選。


有點像二維揹包。但是鑑於只要保持原寬高比即可,也就是說可以在保持原寬高比的前提下對圖片進行放大或縮小(即伸縮)。


一個很簡單的近似算法(複雜度爲O(M*N))是:按照圖片的寬高比將所有圖片(即M*N)分成M組(注意,這裏每組的圖片數目可不一定是相同的),由於每組的寬高比很相近,故每組圖片可以看成是一張圖片(即寬不變,高是所有圖片高之和,如果想在圖片上下間加適量空白,則高是所有圖片高之和再加上T*L的空白,T是該組圖片數量減去一或者加上一[該加該減取決於要不要考慮最上和最下的空白],L是空白距離)然後該問題就轉化爲將M張圖片並排放在一起使得高度最接近,如果沒有總寬度限制,則可設定一個高度H然後將每組圖片的整體高度伸縮到該高度即可;如果有總寬度限制,則把最後屏幕的寬高比設爲M組圖片的平均寬高比,這樣即可得到總高度,按照這個總高度將M組圖片伸縮即可。當然,這個算法的前提是圖片的寬高比是均勻分佈的,如果某組的圖片數目過多或過少可以考慮拆分成兩組或者合併成一組,但要保證最後是M組。


當然,還有效果更好的算法,這個還要根據需求(時間和空間複雜度,對最後排列質量的要求等)來考慮。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章