动态规划法解决装载问题

8 篇文章 0 订阅



#include <stdio.h>
#include <stdlib.h>

/*  思路:首先将第一艘船尽可能装满,剩余货物装入第二艘船。
 *	如果能装入第二艘船,则解决装载问题。
 *	使用动态规划将第一艘船尽可能装满,x[i]记录第i个货物是否装入
 *	第一艘船。m[i][j]表示第一艘船剩余容量j下,从第i个货物到第n个货物
 *	最大装载重量。w[i]表示第i个货物重量。C1表示第一艘船最大载重量。
 *	C2表示第二艘船最大载重量。
 *	w[1:n]	m[1:n][1:C1]	x[1:n]
 */

void Loading(int C1,int* w,int num,bool* x,int** m){
	for (int i = 1; i < C1+1 ; i++ ) {
		if ( w[num] > i ) {
			m[num][i] = 0;
			x[num] = false;
		} else {
			m[num][i] = w[num];
			x[num] = true;
		}
	}

	for (int i1 = num - 1; i1 >= 2 ; i1--) {
		for (int j = 1; j <= C1 ; j++ ) {
			if ( w[i1] > j ) {
				m[i1][j] = m[i1+1][j];
				x[i1] = false;
			} else {
				int temW = w[i1] + m[i1+1][ j - w[i1] ];
				if ( temW > m[i1+1][j]  ) {
					m[i1][j] =   temW ;
					x[i1] = true;			
				}else{
					m[i1][j] = m[i1+1][j];
					x[i1] = false;
				}			
			}
		}
	}

	if ( w[1] > C1 ) {
		m[1][C1] = m[2][C1];
		x[1] = false;
	} else {
		int temW = m[2][ C1 - w[1] ] + w[1];
		if ( temW > m[1][C1]  ) {
			m[1][C1] = temW;
			x[1] = true;			
		}else{
			m[1][C1] = m[2][ C1 ];
			x[1] = false;
		}	
	}

}

void SolveLoading(int C2,bool* x,int* w,int num){
	int totalW = 0;
	int c1W = 0;/* 第一艘船总载重 */
	for (int i = 1; i <= num ; i++ ) {
		if ( x[i] == true ) {
			c1W += w[i];
		} 
		totalW += w[i];
	}
	if ( totalW-c1W > C2 ) {
		printf("没有合理的装载方案! :( ");
		return;
	}

	printf(" 装载方案如下:\n ");
	printf(" 第一艘船装 ");
	for (int i = 1; i <= num ; i++ ) {
		if ( x[i] == true ) {
			printf("%d ",i);
		} 
	}
	printf("\n总载重 %d \n",c1W);


	printf(" 第二艘船装 ");
	for (int i = 1; i <= num ; i++ ) {
		if ( ! x[i] ) {
			printf("%d ",i);
		} 
	}
	printf("\n总载重 %d \n",totalW-c1W);
}

int main(int argc,char* argv[]){
	
	int C1 = 0;
	int C2 = 0;
	int num = 0;
	bool* x = NULL;
	int** m = NULL;
	int* w = NULL;

	printf("输入第一艘船最大载重量:");
	scanf("%d",&C1);

	printf("输入第二艘船最大载重量:");
	scanf("%d",&C2);


	printf("输入货物个数");
	scanf("%d",&num);

	x = (bool*)malloc((num+1)*sizeof(bool));
	w = (int*)malloc((num+1)*sizeof(int));

	m = (int**)malloc((num+1)*sizeof(int*));
	for (int i = 0; i <= num ; i++ ) {
		m[i] = (int*)malloc( (C1+1) * sizeof(int) );
	}
	printf("分别输入货物重量(回车结束):\n");

	for (int i = 1; i <= num ; i++ ) {
		scanf("%d",w+i);
	}

	Loading(C1, w, num, x, m);

	SolveLoading(C2, x, w, num);

	
	return 0;
}


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
装载问题是一道经典的回溯算问题。假设有一个货车,它的载重量为C,同时有n个货物,每个货物的重量为w1, w2, ..., wn,现在需要将这些货物装载到货车上,问最多可以装载多少重量的货物? 这个问题可以使用回溯算解决。回溯算的基本思路是搜索所有可能的解,直到找到符合条件的最优解。在装载问题中,我们可以将每个货物看作一个节点,每个节点有两种状态,即选中和不选中。我们可以遍历所有的节点,对于每个节点,都尝试选中和不选中两种状态,然后依次递归下去,直到所有节点都被遍历过。如果当前货物被选中了,我们就将当前货物的重量加到当前的载重量中,如果当前的载重量大于货车的载重量,就表示当前方案不可行,需要回溯到上一个状态继续搜索。最终,我们可以得到符合条件的最优解。 下面是装载问题的回溯算实现的伪代码: ```python def load(w, c): n = len(w) best = 0 def backtrack(i, cw): if i == n: nonlocal best if cw > best: best = cw return backtrack(i + 1, cw) if cw + w[i] <= c: backtrack(i + 1, cw + w[i]) backtrack(0, 0) return best ``` 其中,w是一个列表,表示每个货物的重量;c是货车的载重量;best表示符合条件的最大载重量。回溯函数backtrack(i, cw)表示从第i个货物开始搜索,当前载重量为cw。在回溯函数中,首先判断是否到达了最后一个货物,如果是,则更新最优解;否则,依次尝试选中和不选中当前货物,然后递归下去。 使用回溯算解决装载问题的时间复杂度为O(2^n),因为每个节点有两种状态,总共有n个节点。因此,当n比较大时,回溯算不是很适合。可以考虑使用其他更高效的算,如动态规划等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值