貪心算法是什么意思?舉個例子就很清楚了:現在你有一個能裝4斤蘋果的袋子,蘋果有兩種,一種3斤一個,一種2斤一個,怎么裝才能得到最多蘋果?當然我們人考慮的話當然是拿兩個2斤的蘋果,就剛好裝滿了,但是如果按貪心算法拿的話,首先就要把最重的蘋果拿下(是不是很符合貪心兩個字?),但並沒有得到最多蘋果。
貪心算法保證了局部最優,但並不能保證得到最優解。
什么時候用貪心法?滿足下面兩個條件
1.
具有最優子結構
2.
貪心選擇性
第1點跟動態規划的條件一樣,其實貪心跟動態規划一樣,都是解決最優化的問題,而求解最優化問題通常又通過一系列的求解子問題的步驟。
第2點看個例子在說
現在有個活動選擇的問題如下:
學校只有一個教室,下面表格i代表活動的編號,s代表活動開始時間,f代表活動結束時間.
i
1
2
3
4
5
6
7
8
9
10
11
s
1
3
0
5
3
5
6
8
8
2
12
f
4
5
6
7
9
9
10
11
12
14
16
現在問題是怎么合理分配才能讓教室利用最大化(求活動序列A)?
如果用動態規划做的話思想可能是這樣的,假設我已經知道第k個活動是活動序列之一,
那么又把1到k和k到11看做兩個子問題繼續分下去……(是不是感覺很麻煩- -)
用貪心法的話思想很簡單:活動越早結束,剩余的時間是不是越多?那我就早最早結束的那個活動,找到后在剩下的活動中再找最早結束的不就得了?
雖然貪心算法的思想簡單,但是貪心法不保證能得到問題的最優解,如果得不到最優解,那就不是我們想要的東西了,所以我們現在要證明的是在這個問題中,用貪心法能得到最優解。
現在要證明的是:
S是所有活動的集合,令m為活動集中最早結束的活動,則m在A活動序列中(A就是我們要求出的那個活動序列)。
證明:設j為A中最早結束的活動,如果m=j,那么就證明了最早結束活動m在A中,如果m!=j,
那么我們把j從A中剔除掉,然后換上m,依然能得到一個最優活動序列(m是所有活動中最早結束的),所以貪心法在這個問題里能得到最優解。
現在回過來看什么是貪心選擇性質?就是能用貪心法得到得到全局最優解的性質,至於什么時候能獲得,那就得自己判斷了。
下面是實現的代碼
static void Main(string[] args)
{
int[] s = new int[] {0,1,3,0,5,3,5,6,8,8,2,12}; //活動開始時間,為了方便計算加入第0個活動,不影響
int[] f = new int[] {0,4,5,6,7,9,9,0,10,11,12,14,16}; //活動結束時間
Console.WriteLine(RAS(s,f,0,11));
}
public static string RAS(int[] s,int[] f,int k,int n)//k為從第k個活動到第n個活動選出最優活動
{
int m = k + 1;
while (m <= n && s[m] < f[k])
{
m = m + 1;
}
if (m <= n)
{
return m + "," + RAS(s, f, m, n);
}
else
{
return null;
}
}
To be continued。。。。。。
貪心算法是什么意思?舉個例子就很清楚了:現在你有一個能裝4斤蘋果的袋子,蘋果有兩種,一種3斤一個,一種2斤一個,怎么裝才能得到最多蘋果?當然我們人考慮的話當然是拿兩個2斤的蘋果,就剛好裝滿了,但是如果按貪心算法拿的話,首先就要把最重的蘋果拿下(是不是很符合貪心兩個字?),但並沒有得到最多蘋果。
貪心算法保證了局部最優,但並不能保證得到最優解。
什么時候用貪心法?滿足下面兩個條件
1.
具有最優子結構
2.
貪心選擇性
第1點跟動態規划的條件一樣,其實貪心跟動態規划一樣,都是解決最優化的問題,而求解最優化問題通常又通過一系列的求解子問題的步驟。
第2點看個例子在說
現在有個活動選擇的問題如下:
學校只有一個教室,下面表格i代表活動的編號,s代表活動開始時間,f代表活動結束時間.
i
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
s
|
1
|
3
|
0
|
5
|
3
|
5
|
6
|
8
|
8
|
2
|
12
|
f
|
4
|
5
|
6
|
7
|
9
|
9
|
10
|
11
|
12
|
14
|
16
|
現在問題是怎么合理分配才能讓教室利用最大化(求活動序列A)?
如果用動態規划做的話思想可能是這樣的,假設我已經知道第k個活動是活動序列之一,
那么又把1到k和k到11看做兩個子問題繼續分下去……(是不是感覺很麻煩- -)
用貪心法的話思想很簡單:活動越早結束,剩余的時間是不是越多?那我就早最早結束的那個活動,找到后在剩下的活動中再找最早結束的不就得了?
雖然貪心算法的思想簡單,但是貪心法不保證能得到問題的最優解,如果得不到最優解,那就不是我們想要的東西了,所以我們現在要證明的是在這個問題中,用貪心法能得到最優解。
現在要證明的是:
S是所有活動的集合,令m為活動集中最早結束的活動,則m在A活動序列中(A就是我們要求出的那個活動序列)。
證明:設j為A中最早結束的活動,如果m=j,那么就證明了最早結束活動m在A中,如果m!=j,
那么我們把j從A中剔除掉,然后換上m,依然能得到一個最優活動序列(m是所有活動中最早結束的),所以貪心法在這個問題里能得到最優解。
現在回過來看什么是貪心選擇性質?就是能用貪心法得到得到全局最優解的性質,至於什么時候能獲得,那就得自己判斷了。
下面是實現的代碼
static void Main(string[] args)
{
int[] s = new int[] {0,1,3,0,5,3,5,6,8,8,2,12}; //活動開始時間,為了方便計算加入第0個活動,不影響
int[] f = new int[] {0,4,5,6,7,9,9,0,10,11,12,14,16}; //活動結束時間
Console.WriteLine(RAS(s,f,0,11));
}
public static string RAS(int[] s,int[] f,int k,int n)//k為從第k個活動到第n個活動選出最優活動
{
int m = k + 1;
while (m <= n && s[m] < f[k])
{
m = m + 1;
}
if (m <= n)
{
return m + "," + RAS(s, f, m, n);
}
else
{
return null;
}
}
To be continued。。。。。。