`
ShadowDai
  • 浏览: 15110 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
ss8
社区版块
存档分类
最新评论

暴力法求解01背包问题

 
阅读更多

这段代码只是使用暴力法解决了01背包问题,但是没有经过优化,效率不高。

使用暴力法的原因只是因为作业需求,请勿评价。

主要的难点在于使用C语言列出一个数组的所有子集。使用了递归的方法,将每次的计算都归并为二个元素,这样就能够简化问题。

 

//
//  main.c
//  BackPack
//
//  Created by shadowdai on 11-10-25.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#include <stdio.h>

//k是开始字符的位置,n是数组的长度,l是子集的位数
void subArray(int W[], int V[], int k,int l, int n);

//初始化整个子集数组
void initArray(int n);

//用于输出子集的数组
int priArray[4];
void printArray(int W[], int n);

//计算子集的个数
int counter;
int subArrayWeight[16];
int subArrayValue[16];

//计算子集的重量和价值
void sumOfWeightAndValue(int W[], int V[], int m, int n);

//寻找重量不超过背包重量,并且价值最大的子集
int searchMax();

//重量和价值数组


int main()
{
	int i;
    int max;
	
	int array[4] = {7, 3 , 4, 5};
    int value[4] = {42, 12, 40, 25};
    
    //0是所有数组的子集
    printf("The No.1 is: 0\n");
    subArrayWeight[0] = 0;
    subArrayValue[0] = 0;
    counter = 1;
	
	for (i = 0; i < 4; i++)
	{
        initArray(4);
		//递归算法需要保证从第一个元素开始的所有的元素都被遍历到
		priArray[0] = i;
        counter ++;
        sumOfWeightAndValue(array, value, counter, 1);
		printArray(array, 1);
		subArray(array, value, i+1, 2, 4);	
	}
    
    printf("\nThere are %d SubArray.\n", counter);
    
    for (i = 0; i < 16; i++)
    {
        printf("The Weight of %d is %d and the value is %d\n", i+1 , subArrayWeight[i], subArrayValue[i]);
    }
    
    max = searchMax();
    printf("\nThe most valuable package is No.%d, the max value is %d.\n", max+1, subArrayValue[max]);
    
	return 0;
}

/*
 * 该递归算法每次只向后寻找一位数字。
 * 例如k=1时,只会寻找2,3,4;k=2时,只会寻找3,4
 */

void subArray(int W[], int V[], int k, int l, int n)
{
	int i;
	
	if (k == n-1)
	{
        //n是整个数组的长度,k是整个子集的上一位字符,当k == n-1时,意味着已经是最后一个了。
        priArray[l-1] = k;
        counter += 1;
        sumOfWeightAndValue(W, V, counter, l);
		printArray(W, l);
	}
	else
	{
		for ( i= k; i <= n-1; ++i)
		{
			priArray[l-1] = i;
            counter += 1;
            sumOfWeightAndValue(W, V, counter, l);
			printArray(W, l);
			subArray(W, V, i+1, l+1,n);
		}
	}
	
}

/*
 * 打印子集数组的函数
 */

void printArray(int W[], int n)
{
	int i;
    
    printf("The No.%d is: " , counter);
    
	for (i = 0; i < n; i++)
	{
		printf("%d	", W[priArray[i]]);
	}
	printf("\n");
}

/*
 * 初始化子集数组
 */
void initArray(int n)
{
    for (int i = 0; i<= n-1 ; i++) {
        priArray[i] = 0;
    }
}

/*
 * 计算子集的重量和价值综合
 * m是该子集的序号,与counter相同。n是数组长度
 */
void sumOfWeightAndValue(int W[], int V[], int m, int n)
{
    int i;
    int sumWeight = 0, sumValue = 0;//重量和价值总和变量
    for ( i = 0; i < n; i++) {
        sumWeight += W[priArray[i]];
        sumValue += V[priArray[i]];
    }
    subArrayWeight[m-1] = sumWeight;
    subArrayValue[m-1] = sumValue;
}

/*
 * 排序并查找所有子集中最大子集
 */
int searchMax()
{
    int i,max,MAX;
    max = 0;
    MAX = subArrayValue[max];
    
    for (i = 0; i < 16; i++) {
        if (subArrayWeight[i] <= 10) 
        {
            if (subArrayValue[i] >= MAX)
            {
                max = i;
                MAX = subArrayValue[max];
            }
        }
    }
    
    return max;
}
1
2
分享到:
评论

相关推荐

    01背包问题典型算法(C++源码)

    01背包问题是一种经典的组合优化问题,常在计算机科学,特别是算法设计与分析领域中被研究。它模拟了这样一个场景:我们有一组物品,每件物品都有一定的重量和价值,我们需要将这些物品装入一个容量有限的背包中,以...

    MATLAB求解背包问题.zip

    文档详细阐述了使用动态规划法求解背包问题的步骤。动态规划是一种常用的解决背包问题的方法,其核心思想是将大问题划分为较小的子问题,并利用子问题的解来构建最终解。具体来说,我们可以定义二维数组`dp(i,j)`表示在...

    01背包源代码动态规划法

    ### 01背包问题与动态规划法解析 在计算机科学领域,背包问题是一类经典的组合优化问题,其中01背包问题是最基础也是最典型的一种。01背包问题的基本设定是:给定一组物品,每种物品都有自己的重量和价值,在限定的...

    0-1背包问题

    01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2……Wn,与之相对应的价值为P1,P2……Pn。

    第7章-背包问题.pdf

    分支定界法是一种求解背包问题的有效算法。它通过构建一棵搜索树,将问题分解为多个子问题,然后采用剪枝策略消除无望成为最优解的分支。这种方法可以确保找到全局最优解,但计算量较大,适用于规模较小的问题。 ...

    穷举法求解0-1整数规划的matlab程序

    然而,随着问题规模的增加,穷举法的计算复杂度呈指数增长,因此在实际应用中往往需要考虑其他更为高效的求解方法。对于初学者而言,掌握穷举法的基础原理和实现是理解更高级优化技术的重要基石。

    01背包问题的LC分支限界算法2

    01背包问题是一种经典的组合优化问题,常在计算机科学、运筹学以及人工智能等领域出现。它的目标是在容量有限的背包中选择物品,使得装入背包的物品总价值最大,但每个物品都有自己的重量和价值,并且背包只能容纳...

    背包九讲——背包问题的详细分析

    【背包问题】是一种经典的计算机科学优化问题,常用于求解有限资源的最大利用。它通过模拟放入背包中的物品,以达到最大价值或满足特定条件。在动态规划领域,背包问题是一个非常重要的模型,因为它能直观地展示动态...

    0/1背包问题相关算法

    在0/1背包问题中,回溯法会递归地尝试包含或不包含当前物品的两种情况,直到找到最优解。虽然这种方法直观易懂,但效率通常低于动态规划。 3. 剪枝策略(Pruning): 在回溯法的基础上,可以加入剪枝策略来提高...

    算法分析与设计0-1背包问题

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它模拟了许多实际场景,如资源分配、项目选择、装载问题等。在这个问题中,我们有一组物品,每件物品都有一个重量和一个价值,以及一...

    0-1背包问题多种解法

    0-1背包问题的多种解法,包括暴力求解、动态规划求解、回溯法、贪心法求解求解、模拟退火算法,C++源代码,有详细的注释

    动态规划之背包

    除了动态规划之外,文档还提到了背包问题的搜索解法,这通常指的是回溯法等暴力搜索的解决方案,是背包问题的另一种解法,但在面对大规模数据时效率往往不高。 在文档的前言部分,作者强调了动态规划学习中思考的...

    背包问题的相关解法探讨

    虽然看起来仍然较高,但对比于暴力求解的O(2^n)已经有了显著提升。 此外,还有一些优化技巧可以提高算法效率,例如剪枝操作,通过提前判断某些状态不可能得到最优解而减少不必要的计算。还有记忆化搜索,利用已计算...

    C#使用动态规划解决0-1背包问题实例分析

    通过动态规划求解0-1背包问题,时间复杂度是O(nW),其中n是物品数量,W是背包容量。这种方法避免了暴力枚举所有可能的组合,大大提高了效率。在实际应用中,动态规划可以解决各种类似的优化问题,如旅行商问题、最长...

    暴力、递归与分治、动态规划、贪心算法、回溯经典习题

    这类习题有助于培养总结经验、状态转移的思维能力,如背包问题、最长公共子序列等。 4. 贪心算法习题 贪心算法通过局部最优选择来近似获得全局最优解,在某些场景下可以极高效地解决问题。这类习题有助于启发我们从...

    算法设计与分析-穷举法、贪心法、分枝限界法讲稿

    分枝限界法适用于求解组合优化问题,如背包问题、旅行商问题等。特别是在解空间较大但存在有效的限界函数时,分枝限界法能够高效地找到最优解。 #### 优点与局限性 - **优点**:相比于单纯的穷举法,分枝限界法能够...

    算法分析与设计教程课件

    蛮力法,又称暴力求解,是通过穷举所有可能的解决方案来寻找最优解。虽然这种方法在小规模问题中可行,但随着问题规模的增长,其效率会急剧下降。例如,在解决旅行商问题(TSP)时,若城市数量增加,计算量将以指数...

    详解动态规划

    动态规划是一种优化技术,主要用来解决复杂的问题,通过将大问题分解为小的、相互关联的子...理解和掌握动态规划是成为优秀程序员的关键技能之一,因为它能够解决许多复杂问题,而且通常比朴素的暴力求解方法更有效。

    0-1packets.zip_packets 算法

    通过阅读和理解这段代码,我们可以深入理解分支界限法如何应用于0-1背包问题,学习如何设计高效的数据结构和算法来求解此类问题。 分支界限法相比简单的暴力枚举,其优势在于可以显著减少搜索空间,提高求解效率。...

Global site tag (gtag.js) - Google Analytics