标题:学习日记8:动态规划解背包问题
只看楼主
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
结帖率:58.18%
 问题点数:0 回复次数:0 
学习日记8:动态规划解背包问题
程序代码:
#include <stdio.h>
#include <stdlib.h>

#define  MaxNumber 100
#define  MaxWeight1 100
int M[100][100],T[100][100] ;
int book[100] ;

struct Goods
{
    int    weight[ MaxNumber ] ;
    int value[ MaxNumber]   ;
    int numbers            ;//物品数量
} ;


struct Knapsack
{
    int MaxWeight ;  //背包承重量

} ;

int Max( int a, int b )
{
    if(a>b) return a ;
    else return b ;
}


//自底向上动态规划
int MaxValue( struct Knapsack *knapsack ,  struct Goods *goods )
{
    int i , j ;

    for(j=0 ; j<=knapsack->MaxWeight ; j++ ) //第0行每列都为0
        M[0][j] = 0 ;   

    for(i=1 ; i<=goods->numbers ; i++)
    {
        M[i][0] = 0  ;    //逐行,从左向右依次填充表格
        for(j=1 ; j<= knapsack->MaxWeight ; j++)
        {
            if( j< goods->weight[i] )
                M[i][j] = M[i-1][j] ;
            else  
                M[i][j] = Max( M[i-1][j] , goods->value[i]+M[i-1][ j-goods->weight[i] ] ) ;            
        }    
    }
    
    return M[goods->numbers][knapsack->MaxWeight] ;
}

//动态规划:备忘录法
//改动变化原因
int  MFKnapsack( int i , int j , struct Knapsack *knapsack ,  struct Goods *goods ) 
{
    int value ;

    if(i==0) return 0 ; 
    else 
    {
        if(T[i][j]<0)
        {
            if( j<goods->weight[i] )
                value = MFKnapsack(i-1,j, knapsack ,  goods ) ;
            else
                value =  Max(   MFKnapsack(i-1,j, knapsack , goods ) ,
                           goods->value[i]+MFKnapsack( i-1 , j-goods->weight[i] , knapsack , goods )  );
            T[i][j] = value ;
        }
        
        return T[i][j] ;
    }
    
}


void recall(struct Knapsack *knapsack ,  struct Goods *goods )
{
    int i , j ;//回溯表格,标记最优子集中的物品,属于最优子集中的标记为1,否则标记为0
    j=knapsack->MaxWeight ;
    for(i=goods->numbers ; i>=0 ; i--)    
            if(M[i][j] == M[i-1][j] )
            {
                book[i]=0 ;//第i个物品放与不放不影响价值,则不需要放入
            }
            else
            {    
                book[i]=1 ;//第i个物品取出
                j = j-goods->weight[i] ;
            }
        
}

int main( )
{
    int i,j ;
    int MV ;
    struct Knapsack *knapsack ;
    struct Goods *goods ;

    knapsack=(struct Knapsack *)malloc(sizeof(struct Knapsack) ) ;
    goods = (struct Goods *)malloc( sizeof(struct Goods) ) ;

    printf("输入背包最大承重量\n");
    scanf( "%d" , &knapsack->MaxWeight ) ;//输入背包最大承重量

    printf("输入物品数量\n");
    scanf( "%d" , &goods->numbers ) ; //输入物品数量

    printf("输入物品重量\n");
    for( i=1 ; i<=goods->numbers ; i++ )//输入物品重量
    {
        scanf("%d",&goods->weight[i]) ;
    }

    printf("输入物品价值\n");
    for( i=1 ; i<=goods->numbers ; i++ )//输入物品价值
    {
        scanf("%d",&goods->value[i]) ;
    }

    MV=MaxValue( knapsack , goods ) ;

    printf("背包能容纳的最大价值%d\n" , MV ) ;    
    
    printf("输出表格\n");
    for(i=0 ; i<=goods->numbers ; i++)//输出表格
    {    
        for(j=0 ; j<=knapsack->MaxWeight ; j++)
            printf("%d ", M[i][j]) ;
        printf("\n");
    }
    
    //最优子集不止一种如何输出
    recall( knapsack , goods ) ;
    printf("输出最优子集物品编号\n") ;

    for(i=1;i<=goods->numbers;i++)
        if(book[i]==1) printf("%d ",i) ;
    printf("\n") ;

    //动态规划备忘录法
    //初始化表格
    for(i=0 ; i<=goods->numbers ; i++)
        for(j=0 ; j<=knapsack->MaxWeight ; j++)
            T[i][j] = -1 ; 
    MFKnapsack(goods->numbers ,  knapsack->MaxWeight , knapsack ,  goods ) ;

    printf("备忘录法建立的表格\n") ;
    for(i=0 ; i<=goods->numbers ; i++)//输出表格
    {    
        for(j=0 ; j<=knapsack->MaxWeight ; j++)
            printf("%d ", T[i][j]) ;
        printf("\n");
    }

}

搜索更多相关主题的帖子: color 背包 动态 日记 
2015-12-16 16:30



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-460281-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.316654 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved