昨天对活动选择的动态规划解做了分析和描述,今天就来简单的实现一下代码,并用实例来验证其运行的正确性。
//基础类用来保存动态的集合A[i][j]
class DynamicSet{ public static DynamicSet empty = new DynamicSet(null); List<Integer> resultSet = null; public DynamicSet(){ resultSet = new ArrayList<Integer>(); } public DynamicSet(List<Integer> rs){ this.resultSet = rs; } @Override public String toString() { return resultSet == null ? "empty" : resultSet.toString(); } }
//算法实现方法
public static void selectActivity(int[] s, int[] f, int n){
s[0] = f[0] = 0;
s[n+1] = f[n+1] = Integer.MAX_VALUE;
//Initialize the int[][]c and DynmicSet[][]A
int[][] c = new int[n+2][n+2];
DynamicSet[][] A = new DynamicSet[n+2][n+2];
for( int i = 0; i <= n + 1; i++){
for(int j = 0; j <= i; j++){
c[i][j] = 0;
A[i][j] = DynamicSet.empty;
}
}
//Start to calculation the values for the A and C
for( int t = 1; t <= n+1; ++t){
for( int i = 0; i <= n - t + 1; ++i){
int j = i + t;
if( f[i] >= s[j]){
c[i][j] = 0;
A[i][j] = DynamicSet.empty;
}else{
for(int k = i+1; k <= j - 1; k++){
if( f[i] <= s[k] && f[k] <= s[j]){
if( c[i][j] < c[i][k] + 1 + c[k][j]){
c[i][j] = c[i][k] + 1 + c[k][j];
resetDynmaicSetA_i_j(A,i,j,k);
}
}
}
//set DynamicSet.empty for the null set, this step could be omit
if(A[i][j] == null)
A[i][j] = DynamicSet.empty;
}
}
}
System.out.println(c[0][n+1]);
System.out.println(A[0][n+1].resultSet.toString());
}
//辅助方法,用来合并集合 A[i][j] = A[i][k] ∪ k ∪ A[k][j]
private static void resetDynmaicSetA_i_j(DynamicSet[][] A, int i, int j,int k) {
if( A[i][j] == null )
A[i][j] = new DynamicSet();
if( A[i][j].resultSet == null )
A[i][j].resultSet = new ArrayList<Integer>();
A[i][j].resultSet.clear();
if( A[i][k] != null && A[i][k] != DynamicSet.empty )
A[i][j].resultSet.addAll(A[i][k].resultSet);
A[i][j].resultSet.add(k);
if( A[k][j] != null && A[k][j] != DynamicSet.empty )
A[i][j].resultSet.addAll(A[k][j].resultSet);
}
测试代码,假设现在有11个活动已经按结束时间fi排好序:
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
s[i] | 1 | 3 | 0 | 5 | 3 | 5 | 6 | 8 | 8 | 2 | 12 |
f[i] | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
则测试代码如下:
public static void main(String[] args){
int n = 11;
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,8,9,10,11,12,13,14,0};
selectActivity(s,f,n);
}
运行结果:
4 // c[0][12]
[1, 4, 8, 11] //A[0][12]
内存中保存的值:
c[][]:
[0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 3, 4],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, 3],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, 3],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
A[][]:
[empty, empty, empty, empty, [1], empty, [1], [1], [1, 4], [1, 4], empty, [1, 4, 8], [1, 4, 8, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, [4], [4], empty, [4, 8], [4, 8, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, [4], [4], empty, [4, 8], [4, 8, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [7], [7, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [8], [8, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [8], [8, 11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, [11]]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty]
[empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty]