我正在尝试创建一个修改后的背包功能,该功能可以采集对象集合并比较任何2个基于数字的值,并找到最优化的配置。
如果我已经知道对象的类型和属性,我已经得到了算法,但我喜欢制作一个可以在任何对象上工作的通用版本。
算法首先通过表示resourceCost(需要最小化的值)的属性对集合进行排序,然后迭代地将最大的成本资源添加到解决方案中,直到资源完全被resourceSize填满为止。 (在麻袋中占据“空间”的价值)
认识到,一些较大的成本资源可能具有最小尺寸,因此留下了当袋子被填充时仍然可以进一步优化的可能性,最后一步是递归地去除最小尺寸同时保持袋子仍然至少100%满。 (我故意允许1个物品溢出袋子以确保袋子尺寸100%使用)
代码使用的示例可能是:
listOfBuildings.KnapSack(300, building => building.NumRooms, building => building.Distance);
这是在回答这个问题:“返回距离家最近且建筑总数至少为300间的建筑物的数量最少”
所以这是我的问题:
注意在foreach循环下我注释掉currentSackSize += item.resourceSize;
这是因为显然这不是正确的语法。因为我使用T作为通用类型。如何从我指定为resourceSize的“item”返回相同的值?
所以无论如何这里是代码:
public static IEnumerable<T> KnapSack<T>(this IEnumerable<T> source, float sackSize, Expression<Func<T, object>> resourceCost, Expression<Func<T, object>> resourceSize) {
source = source.OrderBy(resourceCost);
int currentSackSize = 0;
bool useLastIteration = true;
List<T> sack = new List<T>();
foreach(T item in source) {
//currentSackSize += item.resourceSize;
if(currentSackSize <= sackSize) {
sack.Add(item);
} else {
if(useLastIteration) {
sack.Add(item);
useLastIteration = false;
if(currentSackSize > sackSize) {
sack = OptimizeSack(sack, resourceSize, sackSize);
}
}
}
}
return sack;
}
private static IEnumerable<T> OptimizeSack<T>(IEnumerable<T> sack, Expression<Func<T, object>> resourceSize, float sackSize) {
int currentSackSize = sack.Sum(resourceSize);
int minValue = sack.Min(resourceSize);
if((currentSackSize - minValue) > sackSize) {
source = sack.OrderBy(area).Skip(1); //drop the smallest value from the sack
return OptimizeSack(sack, sackSize);
} else {
return sack;
}
}