十分鐘了解演算法(2) 初始貪心演算法和動態規劃

2021-09-13 12:50:42 字數 3890 閱讀 7634

為了達到目的,每一步都採取最優的方法,也就是區域性最優解,從而得到全域性最優解。

往往不能得到最優解,只有近似解。

簡單粗暴,速度快。

從條件中找出使得利益最大化的最值

不斷擴大規模,繼續找最值

np完全問題:

定義:問題涉及序列 / 集合,需要計算所有的解並從中選出最小/最短的那個。

特點:

例子:1. 活動安排問題:

設有n個活動,其中每個活動都要求使用同一資源,而在同一時間內只有乙個活動能使用這一資源。每個活動i都有乙個要求使用該資源的起始時間si和乙個結束時間fi,且si解決:每次都貪心的選擇結束時間最早的活動,就可以辦最多的活動。先選擇結束時間最早的那乙個活動,然後往後依次查詢結束時間最早的並且與上乙個活動不衝突的活動加入。

//先對活動開始時間進行排序

public static void sort(int start, int end)

start[j + 1] = temp1;

end[j + 1] = temp2;}}

}public static void getactivity(int start, int end, arraylistselected)

}selected.add(index);

for (int i = start[selected.get(0)]; i < start.length; i++)

}selected.add(index); //記錄活動}}

}

2. 最優裝載問題:

有一批貨櫃要裝上一艘載重量為c的輪船。其中貨櫃i的重量為wi。求確定在裝載體積不受限制的情況下,將盡可能多的貨櫃裝上輪船。

解決:每次都貪心的選擇裝最輕的貨櫃,就可以裝最多。

// 最優裝載問題

public static int load(float weight, float maxweight)

sum -= weight[index-1];

return sum;

}

3. 揹包問題:

有n件物品和乙個容量為height的揹包。第i件物品的重量是height[i],價值是value[i]。可以選擇裝入物品i的一部分,求解怎麼把物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。

解決:求每個物品的價值重量比,即價值/重量。然後每次都貪心的新增價值重量比最大的物品。

4. 多機排程問題:

給出一種作業排程方案,使所給的n個作業在盡可能短的時間內由m臺機器加工處理完成。

解決:每次都貪心的選擇最長處理時間作業。將n個作業依其所需的處理時間從大到小排序。然後依此順序將作業分配給空閒的處理機。

先解決子問題,再根據子問題解決大問題

確定約束條件和優化值,將需要優化的值當做單元格,根據優化值確定座標軸。

劃分問題:把問題由上到下劃分,每個單元格都是子問題。

分別解決子問題。

解決大問題。

01揹包問題:

有n件物品和乙個容量為height的揹包。第i件物品的重量是height[i],價值是value[i]。求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。

約束條件是揹包的容量,需要優化的是揹包的總價值。所以單元格是揹包的價值,如果需要確定價值,那麼首先需要每個物品的價值,然後還需要知道揹包的容量,做約束條件。

劃分子問題:分別裝入物品,計算此時揹包的價值。

解決子問題:根據新增加的目標和之前的資料,確定取該物品和不取該物品哪個價值更大,也就是取上乙個單元格的價值(cell[i-1][j])當前商品和剩餘空間的總價值(v[i]+cell[i-1][j-w[i]])之間的最大值。選擇滿足每一列約束條件的最大的目標及其權值新增進**。

最後乙個**就是整個問題的最優解

//01揹包問題

public static int getbag(int maxweight,int weight,int value)

else

maxvalue = bag[i][j]; //找到當前最大價值了}}

for (int i = 0; i < bag.length; i++)

system.out.printf("%n");

}return maxvalue;

}public static void main(string args) ;

// int value = ;

int weight = ;

int value = ;

// string goods = ;

system.out.println(getbag(maxweight,weight,value));

}

最長公共子串:

找出兩個單詞之間的最長公共子串。

約束條件是每個單詞的每個字元,需要優化的是兩個單詞間含有的公共最多連續的字元。所以單元格是兩個單詞此時的最長公共子串數量,如果需要確定最長公共子串,那麼就需要比較兩個單詞,因此兩個單詞分別是行和列。

劃分子問題:分別計算每個字元加入後,此時兩個字串的最長公共子串。

解決子問題:根據新增加的字元和之前的子串,如果新增加的字元相同,就在之前子串的基礎上再新增字元,如果新增加的字元不同,就需要清零。也就是0當前字元+之前字元的字元數(v[i]+cell[i-1][j-1])之間的最大值。選擇滿足約束條件的最大的目標及其字元數新增進**。

解決大問題:**中的最大值就是問題的解。

//公共最長子串

public static int substring(char a, char b) else

if (strs[i][j] > max) //結果為表中最大長度

max = strs[i][j];}}

for (int i = 0; i < strs.length; i++)

system.out.printf("%n");

}return max;

}

最長公共子串行:

找出兩個單詞之間的最長公共子串行,只需要在序列中即可。

約束條件是每個單詞的每個字元,需要優化的是兩個單詞間含有的公共最多字元。所以單元格是兩個單詞此時的最長公共子串行的數量,如果需要確定最長公共子串行,那麼就需要比較兩個單詞,因此兩個單詞分別是行和列。

劃分子問題:分別計算每個字元加入後,此時兩個字串的最長公共子串行。

解決子問題:根據新增加的字元和之前的子串行,如果新增加的字元相同,就在之前子串行的基礎上再新增字元,如果新增加的字元不同,就取上一次的最長子序列,沒必要清零。也就是上一次的子串行最大值(max(cell[i-1][j],cell[i][j-1]))當前字元+之前字元的字元數(v[i]+cell[i-1][j-1])之間的最大值。選擇滿足約束條件的最大的目標及其字元數新增進**。

解決大問題:**中的最大值就是問題的解。

//公共最長子序列

public static int sublist(chara,charb) else

if (strs[i][j] > max) //結果為表中最大長度

max = strs[i][j];}}

for (int i = 0; i < strs.length; i++)

system.out.printf("%n");

}return max;

}

十分鐘了解演算法(0) 初始演算法

演算法是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,並且毎條指令表示乙個或多個操作。輸入 可以沒有 輸出 至少乙個 有窮性確定性 可行性正確性 演算法至少應該具有輸入 輸出和加工處理無歧義性 能正確反映問題的需求 能夠得到問題的正確答案。時間效率髙和儲存量低 乙個程式的執行時間,依賴...

十分鐘了解演算法(3) 有趣的演算法

k最近鄰,就是k個最近的鄰居的意思,每個樣本都可以用它最接近的k個鄰居來代表。如果乙個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別,並具有這個類別上樣本的特性。1.特徵抽取 挑選合適的特徵 確定樣本的特徵值,建立n維座標軸 標出每個樣本的點,並使用畢達哥拉斯公式...

十分鐘零基礎了解Async

async function testasync const result testasync console.log result 輸出的是乙個 promise 物件。c var test node harmony async await promiseawait 可以理解為是 async wai...