-1

我真的在努力解决一个问题,我需要将可用场景“修剪”到用户定义为有效的场景。下面是我试图在 .Net (C#) 中解决的问题的一个小例子。鉴于下面显示的级别/值,用户可以选择只有几个有效组合,但如果您想象下面的级别是 30-40 级数据而不是我显示的 5 级,您可能会看到我的困境。我可能需要经过数百万到数十亿个 NOT VALID 组合才能获得 Valid 组合。在某些情况下,级别中的所有值都适用,而在某些情况下,只有用户指定的那些组合才适用。

当前水平/数据值:

用户说有效的组合是:

*Notice all from level 4 are valid
Receiver -> Sony -> 500 -999 -> Retail
Receiver -> Sony -> 1000 - Up -> Retail  

给定 5 个信息级别的预期结果:

Receiver -> Sony -> 500-999 -> Open -Box -> Retail
Receiver -> Sony -> 500-999 -> New -> Retail
Receiver -> Sony -> 1000-Up -> Open -Box -> Retail
Receiver -> Sony -> 1000-Up -> New -> Retail

我尝试过的东西在小集合中表现出色,但是如果我要在组合中有很多关卡和很大的差距,这将不允许我在深入关卡之前修剪有效的组合,我会遇到主要性能问题。我显然没有错误地解决这个问题。

任何其他关于解决该问题的意见或建议将不胜感激。

4

1 回答 1

3

假设您能够将输入解析为 N 个不同的集合,每个集合都包含特定级别的有效值,那么问题只是找到这 N 个集合的笛卡尔积。

Eric Lippert 有一篇博客文章,他在其中介绍了如何创建一个解决方案,以在编译时获得许多未知序列的笛卡尔积。取自该帖子末尾的代码是:

static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
  IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
  return sequences.Aggregate( 
    emptyProduct, 
    (accumulator, sequence) => 
      from accseq in accumulator 
      from item in sequence 
      select accseq.Concat(new[] {item})); 
}

将此代码与您的示例输入一起使用:

var validValues = new string[][]{
    new string[] {"Receiver"},
    new string[]  {"Sony"},
    new string[]  {"500 -999","1000 - Up"},
    new string[]  {"Open -Box","New "},
    new string[]  {"Retail"},
};

foreach(var combination in  validValues.CartesianProduct())
    Console.WriteLine(string.Join(" ", combination));

提供输出:

接收器 Sony 500 -999 开箱零售
接收器 Sony 500 -999 新零售
接收器 Sony 1000 - Up Open-Box Retail
接收器 Sony 1000 - Up New Retail
于 2013-08-09T15:56:31.133 回答