11#include < algorithm>
22#include < iostream>
33
4+ #include " Matrix.h"
45#include " Knapsack.h"
56
67Knapsack::Item::Item ():
@@ -40,20 +41,24 @@ Knapsack::Item& Knapsack::Item::operator=(Item&& i)
4041 return *this ;
4142}
4243
43- Knapsack::ItemScore::ItemScore ():
44+ Knapsack::ItemScore::ItemScore (const uint32_t idx) :
45+ m_idx(idx),
4446 m_set(false ),
4547 m_val(0 )
4648{}
4749
48- Knapsack::ItemScore::ItemScore (double val):
50+ Knapsack::ItemScore::ItemScore (const uint32_t idx, double val) :
51+ m_idx(idx),
4952 m_set(true ),
5053 m_val(val)
5154{}
5255
5356Knapsack::ItemScore::ItemScore (ItemScore&& itemScore):
57+ m_idx(itemScore.m_idx),
5458 m_set(itemScore.m_set),
5559 m_val(itemScore.m_val)
5660{
61+ itemScore.m_idx = 0 ;
5762 itemScore.m_set = false ;
5863 itemScore.m_val = 0 ;
5964}
@@ -64,13 +69,65 @@ Knapsack::ItemScore& Knapsack::ItemScore::operator=(ItemScore&& itemScore)
6469 {
6570 return *this ;
6671 }
72+ m_idx = itemScore.m_idx ;
6773 m_set = itemScore.m_set ;
6874 m_val = itemScore.m_val ;
75+ itemScore.m_idx = 0 ;
6976 itemScore.m_set = false ;
7077 itemScore.m_val = 0 ;
7178 return *this ;
7279}
7380
81+ bool Knapsack::ItemScore::operator <(const ItemScore& itemScore)
82+ {
83+ return m_val < itemScore.m_val ;
84+ }
85+
86+ Knapsack::Entity::Entity ():
87+ m_set(false ),
88+ m_val(0 )
89+ {}
90+
91+ Knapsack::Entity::Entity (const uint32_t val):
92+ m_set(true ),
93+ m_val(val)
94+ {}
95+
96+ Knapsack::Entity::Entity (Entity&& entity) :
97+ m_set(entity.m_set),
98+ m_val(entity.m_val)
99+ {
100+ entity.m_set = false ;
101+ entity.m_val = 0 ;
102+ }
103+
104+ Knapsack::Entity& Knapsack::Entity::operator =(Entity&& entity)
105+ {
106+ if (this == &entity)
107+ {
108+ return *this ;
109+ }
110+ m_set = entity.m_set ;
111+ m_val = entity.m_val ;
112+ entity.m_set = false ;
113+ entity.m_val = 0 ;
114+ return *this ;
115+ }
116+
117+ std::ostream& operator << (std::ostream& out, const Knapsack::Entity& entity)
118+ {
119+ if (entity.m_set )
120+ {
121+ out << entity.m_val ;
122+ }
123+ else
124+ {
125+ out << -1 ;
126+ }
127+ out << ' ;' ;
128+ return out;
129+ }
130+
74131Knapsack::Knapsack ()
75132{
76133}
@@ -126,7 +183,7 @@ bool Knapsack::run(
126183
127184 res = knapsack[numItems][m_maxWeight - 1 ];
128185
129- // TODO: backpropagation
186+ // backpropagation
130187 uint32_t currentWieght = m_maxWeight;
131188 for (uint32_t i = numItems; i > 0 ; --i)
132189 {
@@ -143,7 +200,70 @@ bool Knapsack::run(
143200 return true ;
144201}
145202
146- bool Knapsack::runGreedy (uint32_t &res)
203+ bool Knapsack::runByValue (uint32_t & res, ItemsList& resList)
204+ {
205+ auto it = std::max_element (m_items.begin (), m_items.end (), [](const Item& i1, const Item& i2) -> bool {
206+ return i1.m_value < i2.m_value ;
207+ });
208+ uint32_t maxValue = it->m_value ;
209+ uint32_t numOfItems = static_cast <uint32_t >(m_items.size ());
210+ Matrix<Entity> knapsackMatrix;
211+ knapsackMatrix.resize (numOfItems + 1 , numOfItems * maxValue + 1 );
212+
213+ Entity minEntity;
214+ Entity tmpVal;
215+ knapsackMatrix[0 ][0 ] = std::move (Entity (0 ));
216+ for (uint32_t i = 1 ; i <= numOfItems; ++i)
217+ {
218+ for (uint32_t x = 0 ; x <= numOfItems * maxValue; ++x)
219+ {
220+ tmpVal = ((m_items[i - 1 ].m_value < x) ? knapsackMatrix[i - 1 ][x - m_items[i - 1 ].m_value ] : Entity (0 ));
221+ minEntity = knapsackMatrix[i - 1 ][x];
222+
223+ if (tmpVal.m_set &&
224+ ((!minEntity.m_set ) ||
225+ (minEntity.m_val > m_items[i - 1 ].m_weight + tmpVal.m_val )))
226+ {
227+ minEntity.m_set = true ;
228+ minEntity.m_val = m_items[i - 1 ].m_weight + tmpVal.m_val ;
229+ }
230+ knapsackMatrix[i][x] = std::move (minEntity);
231+ }
232+ }
233+ // debug
234+ /* std::ofstream fout("knapsack.csv");
235+ fout << knapsackMatrix << std::endl;*/
236+
237+ res = 0 ;
238+ for (uint32_t x = 0 ; x <= numOfItems * maxValue; ++x)
239+ {
240+ if (knapsackMatrix[numOfItems][x].m_set &&
241+ knapsackMatrix[numOfItems][x].m_val <= m_maxWeight)
242+ {
243+ res = x;
244+ }
245+ }
246+
247+ // TODO: backpropagation
248+ uint32_t currVal = res;
249+ for (uint32_t i = numOfItems; i > 0 ; --i)
250+ {
251+ if ((m_items[i - 1 ].m_value <= currVal) &&
252+ knapsackMatrix[i - 1 ][currVal - m_items[i - 1 ].m_value ].m_set )
253+ {
254+ if (knapsackMatrix[i][currVal].m_val ==
255+ knapsackMatrix[i - 1 ][currVal - m_items[i - 1 ].m_value ].m_val + m_items[i - 1 ].m_weight )
256+ {
257+ currVal -= m_items[i - 1 ].m_value ;
258+ resList.push_front (m_items[i - 1 ]);
259+ }
260+ }
261+ }
262+
263+ return true ;
264+ }
265+
266+ bool Knapsack::runGreedy (uint32_t &res, ItemsList& resList)
147267{
148268
149269 std::vector<ItemScore> itemsScores;
@@ -155,19 +275,19 @@ bool Knapsack::runGreedy(uint32_t &res)
155275 {
156276 if (m_items[i].m_weight != 0 )
157277 {
158- itemsScores.push_back (std::move (ItemScore (m_items[i].m_value / m_items[i].m_weight )));
278+ itemsScores.push_back (std::move (ItemScore (i, static_cast < double >( m_items[i].m_value ) / m_items[i].m_weight )));
159279 }
160280 else
161281 {
162- itemsScores.push_back (std::move (ItemScore ()));
282+ itemsScores.push_back (std::move (ItemScore (i )));
163283 }
164284 }
165285 std::sort (itemsScores.begin (), itemsScores.end ());
166286 // debug
167- for (auto & itemScore : itemsScores)
287+ /* for (auto& itemScore : itemsScores)
168288 {
169289 std::cout << itemScore.m_val << std::endl;
170- }
290+ }*/
171291
172292 res = 0 ;
173293 uint32_t currentWeight = 0 ;
@@ -181,6 +301,7 @@ bool Knapsack::runGreedy(uint32_t &res)
181301 {
182302 currentWeight += m_items[itemScore.m_idx ].m_weight ;
183303 res += m_items[itemScore.m_idx ].m_value ;
304+ resList.push_back (m_items[itemScore.m_idx ]);
184305 }
185306 }
186307
@@ -190,6 +311,8 @@ bool Knapsack::runGreedy(uint32_t &res)
190311 (item.m_value > res))
191312 {
192313 res = item.m_value ;
314+ resList.clear ();
315+ resList.push_back (item);
193316 }
194317 }
195318
0 commit comments