| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3210 人关注过本帖
标题:备忘录法解背包问题,哪错了
只看楼主 加入收藏
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
结帖率:58.18%
收藏
已结贴  问题点数:30 回复次数:3 
备忘录法解背包问题,哪错了
程序代码:
#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&&j>=0)
    {
        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 ) ;

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

}

图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2015-12-16 08:22编辑过]

搜索更多相关主题的帖子: 备忘录 color 背包 
2015-12-15 16:53
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:30 
程序代码:
int MFKnapsack(int i, int j, struct Knapsack *knapsack, struct Goods *goods)
{
    int value;

    if (i > 0 && j > 0)
    {
        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];
    }
    return T[i][j] = 0;
}


[fly]存在即是合理[/fly]
2015-12-16 09:26
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 2楼 azzbcc
我少了递归出口
2015-12-16 16:28
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 2楼 azzbcc
这样改也可以呢,谢谢版主
2015-12-16 16:29
快速回复:备忘录法解背包问题,哪错了
数据加载中...
 
   



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

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