00001 #include<knapsack.h>
00002
00003 double
00004 KNAPSACK (array < int >&W, int w, array < double >&C, set < int >&S)
00005 {
00006
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 {
00045
00046
00047
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
00143
00144
00145
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 }