In the worst case scenario, you need to go through all subsets of 2^nyour dataset, but if all your objects are non-negative, you can start by filtering by item.Number <= 500.
Here is a possible method Subsets(actually the answer to How to get all subsets of an array?, But don't tell them):
public static IEnumerable<IEnumerable<T>> Subsets(this IEnumerable<T> source)
{
var first = source.FirstOrDefault();
if (first == null) return new[] { Enumerable.Empty<T>() };
var others = source.Skip(1).Subsets();
return others.Concat(others.Select(s => s.Concat(new { first })));
}
Once you have a method Subsets, you can filter the result as follows, although the performance is still about gazillion (or 2^nif you want to be picky).
var sets = items.Where(i => i.Number <= 500)
.Subsets().Where(s => s.Sum(i => i.Number) == 500);
However, if you have a restriction on the Numberfact that it is non-negative, you can combine the operation Subsetswith the search for the target amount. That would mean that you define
public static IEnumerable<IEnumerable<T>> SubsetsAddingUpTo(this IEnumerable<T> source, int target)
{
if (target < 0) return Enumerable.Empty<IEnumerable<T>>();
var first = source.FirstOrDefault();
if (first == null) return Enumerable.Empty<IEnumerable<T>>();
var tail = source.Skip(1).Where(i => i.Number <= target).ToList();
var othersIncludingFirst = tail.SubsetsAddingUpTo(target - first.Number);
var othersExcludingFirst = tail.SubsetsAddingUpTo(target);
return othersExcludingFirst.Concat(othersIncludingFirst.Select(s => s.Concat(new { first })));
}
<= target , . , , , .
var sets = items.OrderByDescending(i => i.Date).SubsetsAddingUpTo(500);
. ( 0 1) ( 2^n), Number , , .