01揹包問題

//重量數組w[], 價值數組v[], 包的最大容量wCApacity, map[begin][wCapacity]記錄從begin到end容量不超過wCapacity的最大價值
//重量數組的開始位置 begin, 結束位置 end

// 當begin != end時
//map(begin,wCapacity) =
//(Max(map(begin+1,wCapacity),map(begin+1,wCapacity-w[i] )+v[i])    (wCapacity>=w[i])
// map(begin+1,wCapacity)                             (0 <= wCapacity <w[i]))
//當begin == end 時
//map(begin, wCapacity) =
//v[begin] wcapcity >= w[n]
//0                 0 <=wCapacity < w[n]
#include <iostream>
using namespace std;

#define    N 4 //數組大小
#define MaxC 12 //包容量的最大值
#define Max(a,b) ((a >= b)? a : b)
#define Min(a,b) ((a <= b)? a : b)


//01揹包問題的遞歸算法
int knapsack( int begin, int end, int wCapacity, int map[][MaxC], int* w, int* v)
{
   if (wCapacity < 0)
  {
    printf( "The value of wCapacity is invalid!\n");
     return -1;
  }
   if (begin == end)
  {
     if (wCapacity >= w[end])
    {
      map[begin][wCapacity] = v[end];
    }
     else
    {
      map[begin][wCapacity] = 0;
    }
     return map[begin][wCapacity];
  }
   else
  {
     if (wCapacity >= 0 && wCapacity < w[begin])
    {
      map[begin][wCapacity] = knapsack(begin+1, end, wCapacity, map, v, w);
       return map[begin][wCapacity];
    }
     else
    {
      map[begin][wCapacity] = Max(knapsack(begin+1,end,wCapacity, map, v, w), knapsack(begin+1,end, wCapacity-w[begin],map, v, w) + v[begin]);
       return map[begin][wCapacity];
    }
  }
    
}

void traceBack( int begin, int end, int wCapacity, int map[][MaxC], int * w, int * x)
{
   int wCap = wCapacity;
   for ( int k = begin; k <= end - 1; k++)
  {    
     if (map[k][wCap] == map[k+1][wCap])
    {
      x[k] = 0;    
    }
     else
    {
      x[k] = 1;
      wCap -= w[k];
    }
  }
  x[end] = (map[end][wCap] == 0)?0:1;

}
//01揹包問題的非遞歸算法

int noknapsack( int begin, int end, int wCapacity, int map[][MaxC], int * w, int * v)
{
   int i, j;

   for (i = 0; i <= wCapacity; i++)
  {
     if (i >= w[end])
    {
      map[end][i] = v[end];
    }
     else
    {
      map[end][i] = 0;
    }
  }
   for (i = end - 1; i >= 0; i--)
  {
     for (j = 0; j <= wCapacity; j++)
    {
       if (j >= w[i])
      {
        map[i][j] = Max(map[i+1][j], map[i+1][j - w[i]] + v[i]);
      }
       else
      {
        map[i][j] = map[i+1][j];
      }
    }
  }
   return map[begin][wCapacity];
}

int main()
{
   int w[N] = {2, 3, 4, 5};
   int v[N] = {10, 30, 40, 25};
   int map[N][MaxC];
   int x[N];
   int wCapacity = 7;
//  int maxValue = knapsack(0, N - 1, wCapacity, map, w, v);
   int maxValue = noknapsack(0, N - 1, wCapacity, map, w, v);
  traceBack(0, N - 1, wCapacity, map, w, x);
   for ( int i = 0; i < N; i++)
  {
    printf( "%d,", x[i]);    
  }
  printf( "\nMaxValue is: %d \n", maxValue);
   return 0;
}
相關文章
相關標籤/搜索