Main Page   Class Hierarchy   Compound List   File List   Contact   Download   Symbolic Constraints   Examples  

knapsack.cc

00001 #include<knapsack.h>
00002 
00003 double
00004 KNAPSACK (array < int >&W, int w, array < double >&C, set < int >&S)
00005 {
00006   /*{\Mfunc Solves the knapsack problem. {\bf describe}} */
00007   array2 < double >G (-1, W.high (), 0, w);
00008 
00009   for (int i = 0; i <= w; i++)
00010     G (-1, i) = -1;
00011   G (-1, 0) = 0;
00012 
00013   for (int i = 0; i <= W.high (); i++)
00014     {
00015       for (int j = 0; j <= w; j++)
00016         if (j < W[i])
00017           G (i, j) = G (i - 1, j);
00018         else
00019           G (i, j) = leda_max (G (i - 1, j), G (i - 1, j - W[i]) + C[i]);
00020     }
00021 
00022   int j = 0;
00023   for (int i = 0; i <= w; i++)
00024     if (G (W.high (), i) > G (W.high (), j))
00025       j = i;
00026 
00027   int i = j;
00028   for (int k = W.high (); k >= 0; k--)
00029     {
00030       if (G (k - 1, i) != G (k, i))
00031         {
00032           i -= W[k];
00033           S.insert (k);
00034         }
00035     }
00036 
00037   return G (W.high (), j);
00038 }
00039 
00040 
00041 
00042 double
00043 KNAPSACK (map < int, int >&W, map < int, double >&C, int w, set < int >&S)
00044 {                               //, set< map<int,int> >& GP) {
00045   /*{\Mfunc Solves the knapsack problem, where $C$ maps the items to their costs,
00046      $W$ maps the items to their wheight, and $w$ is the wheigt limit.
00047      The solution is stored in $S$. } */
00048   map < int, list < KE > >G;
00049   int i, last = -1;
00050   list_item l1, l2;
00051   S.clear ();
00052 
00053   forall_defined (i, W)
00054   {
00055     if (last == -1)
00056       {
00057         G[i].append (KE (W[i], C[i], nil, 0));
00058         G[i].append (KE (0, 0, nil, 0));
00059       }
00060     else
00061       {
00062         l2 = G[last].first_item ();
00063         forall_items (l1, G[last])
00064         {
00065           while ((l2 != nil)
00066                  && (G[last][l2].first () < G[last][l1].first () + W[i]))
00067             {
00068               G[i].append (KE (G[last][l2].first (),
00069                                G[last][l2].second (), l2, last));
00070               l2 = G[last].next_item (l2);
00071             }
00072           if ((l2 != nil)
00073               && (G[last][l2].first () == G[last][l1].first () + W[i]))
00074             {
00075               if (G[last][l2].second () > G[last][l1].second () + C[i])
00076                 G[i].append (KE (G[last][l2].first (),
00077                                  G[last][l2].second (), l2, last));
00078               else
00079                 G[i].append (KE (G[last][l1].first () + W[i],
00080                                  G[last][l1].second () + C[i], l1, last));
00081             }
00082           else
00083             {
00084               if (G[last][l1].first () + W[i] <= w)
00085                 G[i].append (KE (G[last][l1].first () + W[i],
00086                                  G[last][l1].second () + C[i], l1, last));
00087             }
00088         }
00089       }
00090     last = i;
00091   }
00092   l2 = G[last].first_item ();
00093   forall_items (l1,
00094                 G[last]) if (G[last][l1].second () >
00095                              G[last][l2].second ())l2 = l1;
00096 
00097   i = last;
00098   l1 = l2;
00099   int j;
00100 
00101   int w1 = G[last][l2].first ();
00102 
00103   while (G[i][l1].third () != nil)
00104     {
00105       j = G[i][l1].fourth ();
00106       l1 = G[i][l1].third ();
00107       if (G[j][l1].first () != w1)
00108         {
00109           S.insert (i);
00110         }
00111       i = j;
00112       w1 = G[i][l1].first ();
00113     };
00114   if (G[i][l1].first () != nil)
00115     {
00116       S.insert (i);
00117     }
00118 
00119   j = 0;
00120   forall_defined (i, W) j++;
00121   array < int >W2 (j);
00122   array < double >C2 (j);
00123   j = 0;
00124   forall_defined (i, W)
00125   {
00126     W2[j] = W[i];
00127     C2[j] = C[i];
00128     j++;
00129   }
00130   set < int >S2;
00131   if (KNAPSACK (W2, w, C2, S2) != G[last][l2].second ())
00132     cout << "knapsack error\n";
00133 
00134   return G[last][l2].second ();
00135 };
00136 
00137 
00138 double
00139 KNAPSACK (map < int, int >&W, map < int, double >&C, int w,
00140           map < int, int >&S, map < int, int >&LB, map < int, int >&UB)
00141 {
00142   /*{\Mfunc Solves the knapsack problem, where $C$ maps the items to their costs,
00143      $W$ maps the items to their wheight, $w$ is the wheigt limit, and $LB$ and 
00144      $UB$ are lower and upper bounds on the number of times a item can be used. 
00145      The solution is stored in $S$. } */
00146   S.clear ();
00147 
00148   int w1 = w;
00149 
00150   int i, j, k, l = 0;
00151 
00152   forall_defined (i, W)
00153   {
00154     j = UB[i] - LB[i];
00155     k = 1;
00156     while (2 * k - 1 < j)
00157       {
00158         l++;
00159         k = k * 2;
00160       };
00161     l++;
00162   }
00163 
00164   array < int >W1 (l + 1);
00165   array < double >C1 (l + 1);
00166   array < int >ON (l + 1);
00167   array < int >Nk (l + 1);
00168 
00169   l = 0;
00170   forall_defined (i, W)
00171   {
00172     j = UB[i] - LB[i];
00173     w1 -= LB[i] * W[i];
00174     k = 1;
00175     while (2 * k - 1 < j)
00176       {
00177         W1[l] = W[i] * k;
00178         C1[l] = C[i] * k;
00179         ON[l] = i;
00180         Nk[l] = k;
00181         l++;
00182         k = k * 2;
00183       };
00184     W1[l] = W[i] * (j - k + 1);
00185     C1[l] = C[i] * (j - k + 1);
00186     ON[l] = i;
00187     Nk[l] = j - k + 1;
00188     l++;
00189   }
00190 
00191   if (w1 < 0)
00192     {
00193       cout << w1 << " w1\n";
00194       return -10000;
00195     }
00196 
00197   set < int >S1;
00198   double d = KNAPSACK (W1, w1, C1, S1);
00199 
00200   forall (i, S1)
00201   {
00202     S[ON[i]] += Nk[i];
00203   }
00204 
00205   forall_defined (i, W)
00206   {
00207     S[i] += LB[i];
00208     d += LB[i] * C[i];
00209   }
00210 
00211   return d;
00212 }

Generated on Tue Nov 16 15:18:17 2004 for SCIL by doxygen1.2.16