演算法導論16.1 活動選擇問題
這篇文章主要講述一個經典問題:活動選擇問題。並給出該問題的貪心演算法實現和動態規劃實現。
對於該問題的描述,在演算法導論第16章給出了詳細的講解,這裡就不做解釋說明了,下面給出貪心演算法的Java語言實現:
package chapter1.homework1;
import java.util.*;
public class ActivitySelector {
private int activitiesNum=0;//活動總數
private Activity[] activities=null;//記錄所有活動,包括虛擬活動
public static void main(String[] args) {
// TODO Auto-generated method stub
ActivitySelector sample=new ActivitySelector();
sample.getInputInfo();
System.out.println("活動選擇結果:");
sample.greedyActivitySelector();
}
public void greedyActivitySelector(){
int i=0;
for(int m=1;m<=this.activitiesNum;m++){
if(this.activities[m].start>=this.activities[i].end){
System.out.println("id="+this.activities[m].id+" start="+this.activities[m].start+" end="+this.activities[m].end);
i=m;
}
}
}
public void getInputInfo(){
System.out.println("請輸入活動的總數");
Scanner in=new Scanner(System.in);
this.activitiesNum=in.nextInt();
System.out.println("請依次輸入活動的序號,活動的起始時間和活動的截止時間");
activities=new Activity[this.activitiesNum+1];
int id,start,end;
activities[0]=new Activity(0,0,0);
for(int i=1;i<this.activitiesNum+1;i++){
id=in.nextInt();
start=in.nextInt();
end=in.nextInt();
activities[i]=new Activity(id,start,end);
}
}
public class Activity{
private int id;
private int start;
private int end;
public int getId() {
return id;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public Activity(int id,int start,int end){
this.id=id;
this.start=start;
this.end=end;
}
}
}
上述程式碼是按照演算法導論書中GREEDY-ACTIVITY-SELECTOR(s,f)虛擬碼實現的,大家可以參考下,執行結果如下所示:
請輸入活動的總數
11
請依次輸入活動的序號,活動的起始時間和活動的截止時間
1 1 4
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6 10
8 8 11
9 8 12
10 2 13
11 12 14
活動選擇情況如下:
id=1 start=1 end=4
id=4 start=5 end=7
id=8 start=8 end=11
id=11 start=12 end=14
在課後練習題16.1-1中,要求給出活動選擇問題的動態規劃演算法,下面就給出動態規劃的演算法。
在動態規劃演算法中,我們要利用到書中公式16.3,並且要定義陣列c[i][j]來儲存在活動ai之後,活動aj之前的最大活動子集的數目。
演算法實現如下所示:
package chapter1.homework1;
import java.util.Scanner;
public class ActivitySelectorDP {
private int activitiesNum=0;//活動總數
private Activity[] activities=null;//記錄所有活動,包括虛擬活動
private int c[][]=null;//定義陣列儲存
public static void main(String[] args) {
// TODO Auto-generated method stub
ActivitySelectorDP sample=new ActivitySelectorDP();
sample.getInputInfo();
sample.dynamicProgramming();
System.out.println("活動選擇情況如下:");
sample.printSelectedActivity(0, sample.activitiesNum+1);
}
public void getInputInfo(){
System.out.println("請輸入活動的總數");
Scanner in=new Scanner(System.in);
this.activitiesNum=in.nextInt();
System.out.println("請依次輸入活動的序號,活動的起始時間和活動的截止時間");
activities=new Activity[this.activitiesNum+2];
int id,start,end;
activities[0]=new Activity(0,0,0);
for(int i=1;i<this.activitiesNum+1;i++){
id=in.nextInt();
start=in.nextInt();
end=in.nextInt();
activities[i]=new Activity(id,start,end);
}
activities[this.activitiesNum+1]=new Activity(this.activitiesNum+1,Integer.MAX_VALUE,Integer.MAX_VALUE);
}
public void dynamicProgramming(){
this.c=new int[this.activitiesNum+2][this.activitiesNum+2];
for(int i=0;i<=this.activitiesNum;i++){
c[i][i+1]=0;
}
for(int step=2;step<=this.activitiesNum+1;step++){
for(int i=0;i<=this.activitiesNum;i++){
int j=i+step;
if(j<this.activitiesNum+2){
if(this.activities[i].end<=this.activities[j].start){
int max=0;
for(int k=i+1;k<j;k++){
if(this.activities[k].start>=this.activities[i].end
&&this.activities[k].end<=this.activities[j].start){
int temp=c[i][k]+c[k][j]+1;
if(temp>max)
max=temp;
}
}
if(max>c[i][j]){
c[i][j]=max;
}
}
}
}
}
}
public void printSelectedActivity(int start,int end){
if(end-start==1){
return;
}
for(int k=start+1;k<end;k++){
if(this.activities[k].start>=this.activities[start].end
&&this.activities[k].end<=this.activities[end].start){
if(c[start][k]+c[k][end]+1==c[start][end]){
printSelectedActivity(start,k);
System.out.println("id="+k+" start="+this.activities[k].start+" end="+this.activities[k].end);
printSelectedActivity(k,end);
break;
}
}
}
}
public class Activity{
private int id;
private int start;
private int end;
public int getId() {
return id;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public Activity(int id,int start,int end){
this.id=id;
this.start=start;
this.end=end;
}
}
}
程式執行結果如下所示:
請輸入活動的總數
11
請依次輸入活動的序號,活動的起始時間和活動的截止時間
1 1 4
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6 10
8 8 11
9 8 12
10 2 13
11 12 14
活動選擇情況如下:
id=1 start=1 end=4
id=4 start=5 end=7
id=8 start=8 end=11
id=11 start=12 end=14
相關文章
- 演算法導論-16.1-4 活動教室選擇問題演算法
- 活動選擇問題理解貪心演算法演算法
- 物聯網工程導論第二版答案選擇題
- 為你的迴歸問題選擇最佳機器學習演算法機器學習演算法
- 演算法學習之路|選擇題演算法
- 選擇問題——選取第K小元素
- 這就是選擇排序的問題排序
- CSS選擇器常見問題CSS
- [課程複習] 軟體工程導論之經典題目回顧 (一)選擇題、填空題1軟體工程
- 前端面試題:演算法-選擇排序前端面試題演算法排序
- 機器學習處理問題如何選擇一個合適的演算法?機器學習演算法
- 《演算法導論》演算法
- 【爬坑日記】.class.class選擇器的選擇問題
- 演算法導論第二章思考題演算法
- ListView Item 選擇問題解決之道View
- jQuery 選擇器彙總-思維導圖-選擇器jQuery
- 選擇問題(求第k個最小元素)
- MySQL 你可能忽視的選擇問題MySql
- EditText選擇模式的一些問題模式
- 特徵選擇和特徵生成問題初探特徵
- 演算法導論-堆排序演算法排序
- 演算法導論-快速排序演算法排序
- 演算法導論學習之三:排序之C語言實現:選擇排序,插入排序,歸併排序演算法排序C語言
- 選擇物聯網路卡需注意哪些問題
- 選擇伺服器需要關注哪些問題伺服器
- 排序演算法__選擇排序排序演算法
- 常用演算法-選擇排序演算法排序
- 排序演算法:選擇排序排序演算法
- java選擇排序演算法Java排序演算法
- Oracle建立索引選擇合適的可選項及效率問題Oracle索引
- 修改題庫(選擇題) (轉)
- 演算法導論-第6章演算法
- 演算法導論FFT程式碼演算法FFT
- 2 Elment Ui 日期選擇器 格式化問題UI
- 選擇直播美顏工具時應注意哪些問題?
- 選擇資料分析工具時要注意哪些問題
- 卷積核大小選擇、網路層數問題卷積
- 淺談5G頻段的選擇問題