动态规划之活动选择--代码实现



   昨天对活动选择的动态规划解做了分析和描述,今天就来简单的实现一下代码,并用实例来验证其运行的正确性。

   //基础类用来保存动态的集合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排好序:

      

i1234567891011
s[i]130535688212
f[i]4567891011121314

 

 

 

 

 

 

 

 

 

 

则测试代码如下:

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]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值