我想针对特定问题开发自我训练算法.为了简单起见,我将其简化为简单的例子.
更新:我添加了一个有效的解决方案作为下面这个问题的答案.
假设我有一个来自数据库的大量实体列表.每个实体属于同一类型,并具有4个byte类型的属性.
public class Entity { public byte Prop1 { get; set; } public byte Prop2 { get; set; } public byte Prop3 { get; set; } public byte Prop4 { get; set; } }
现在,我想根据一个简单的条件动态测试每个实体的一个或多个属性.这基本上意味着我想针对这种情况测试所有属性的所有可能组合.
为了完成这项工作,我为属性创建了一个位掩码.
[Flags] public enum EEntityValues { Undefined = 0, Prop1 = 1, Prop2 = 2, Prop3 = 4, Prop4 = 8, }
并添加了一种获取位掩码最大值的方法.对于此示例,返回15(1 + 2 + 4 + 8).
public static int GetMaxValue() where T : struct { return Enum.GetValues( typeof(T) ).Cast ().Sum(); }
在这个阶段,我能够通过简单的循环迭代所有属性组合.在第一次迭代中的示例中,测试属性Prop1,在第二次迭代上测试Prop2,在第三次迭代上测试Prop1和Prop2,依此类推.
for(int i = 1; i <= GetMaxValue(); i++) { EEntityValues flags = (EEntityValues)i; if(flags.HasSet(EEntityValues.Prop1)) { .... } }
现在让我们让实体进入游戏.
Listentities = GetEntitiesFromDb(); for(int i = 1; i <= GetMaxValue (); i++) { EEntityValues flags = (EEntityValues)i; byte minProp1Value = 10, minProp2Value = 20, minProp3Value = 30, minProp4Value = 40; foreach(Entitiy entity in entities) { if(flags.HasSet(EEntityValues.Prop1) && entitiy.Prop1 >= minProp1Value) { .... } else { continue; } if(flags.HasSet(EEntityValues.Prop2) && entitiy.Prop2 >= minProp2Value) { .... } else { continue; } } }
好吧,如果我的最小值是静态的,这很有用.
现在让我们变得更复杂.我们记得,在第一次迭代中,我们仅测试属性Prop1,因为位掩码是1.Prot1的值范围是0..255.我还为此属性定义了一个最小值,其有效范围为1..255.此最小值只是跳过foreach循环中实体的过滤器.
现在我想测试属性Prop1,而我正在提升最低水平.这些测试不是问题的一部分,因此我不将它们包含在我的样本中.
byte minProp1Value = 1; while(minProp1Value <= 255) { foreach(Entitiy entity in entities) { if(flags.HasSet(EEntityValues.Prop1) && entitiy.Prop1 >= minProp1Value) { .... // Testing the matching entity and storing the result } else { continue; } } minProp1Value++; }
这对于单个属性来说很简单.在第三次迭代中,我必须处理2个属性Prop1和Prop2,因为位掩码是3.
byte minProp1Value = 1, minProp2Value = 1; while(minProp1Value <= 255) { while(minProp2Value <= 255) { foreach(Entitiy entity in entities) { .... } minProp2Value++; } minProp1Value++; minProp2Value = 1; }
正如您所看到的,在这个阶段,我正在测试每个实体的Prop1和Prop2,以达到不断上升的最低水平.
由于我正在处理动态生成的多个属性集,我无法将while循环硬编码到我的代码中.这就是为什么我正在寻找一种更智能的解决方案来测试给定属性集(位掩码)的所有可能的最小值组合.