【问题标题】:Generating a row within a cross product given an integer在给定整数的叉积中生成一行
【发布时间】:2013-10-22 07:19:27
【问题描述】:

我遇到了一个我正在努力解决的问题。给定任意数量的数组和一个称为“特异性”的整数,我需要在数组的叉积中生成表示该点的行。数组的长度始终至少为 2,并且每个数组的最后一个值始终为空。除了每个数组中的最后一个元素外,没有其他元素为空。例如,给定数组 {1, 2, null} 和 {A, B, null},叉积实际上是:

0:1A
1:1 B
2:1 无效
3:2A
4:2 B
5:2 空
6:空A
7:空B
8:空空

因此,给定“特异性”4,例如上面列出的两个数组,它应该返回数组 {2, B}。那是容易的部分。我已经在下面的代码部分完成了这个特殊案例。但是,请考虑没有空值的组合优先的情况。现在的顺序是:

0:1A
1:1 B
2:2A
3:2 B
4:1 无效
5:2 空
6:空A
7:空B
8:空空

这是我目前实施的算法。上面的第一种情况处理得很好,但我不知道如何处理第二种情况。关于“else”子句的内容有什么想法吗?

    public static String generateKeyForSource(int specificity, KeySource keySource) {
    if (specificity > keySource.getNumPossibleKeys()) {
        throw new IllegalArgumentException("The specificity " + specificity + " is larger than the max number of possible keys for this KeySource, which is " + keySource.getNumPossibleKeys());
    }
    Object[][] hierarchies = keySource.getHierarchies();
    boolean combinedPrecedence = keySource.isCombinedPrecedence();

    int[] indexes = new int[hierarchies.length];
    int multiplier = 1;

    if (!(combinedPrecedence && specificity >= keySource.getFirstSpecificityContainingNull())) {
        for (int i = hierarchies.length - 1; i >= 0; i--) {
            Object[] hierarchy = hierarchies[i];
            int range;
            if (combinedPrecedence)
                range = hierarchy.length - 1;
            else
                range = hierarchy.length;

            int currentArrayIndex = specificity / multiplier % range;
            indexes[i] = currentArrayIndex;
            multiplier *= hierarchies[i].length;
        }
    }
    else {
        //?????????
    }

    return generateKey(indexes, hierarchies);
}

【问题讨论】:

    标签: java math theory


    【解决方案1】:

    在寻找此类问题的解决方案时,归纳是您的朋友。

    对于简单的情况,它看起来像

    easy( a, i ) ≡ easyHelper( a, a.length, i )  
    easyHelper( a, n, i ) ≡ easyInduction( easyHelper, 0 )( a, n, i )
    
    easyInduction( f, b )( a, 0, 0 ) ≡ []  
    easyInduction( f, b )( a, 0, i + 1 ) ≡ undefined
    easyInduction( f, b )( a, n + 1, i ) ≡
       let t = a[n + 1].length - b
        in f( a, n, ⌊i / t⌋ ) ++ [ a[n + 1][i mod t] ]
    

    对于困难的情况,我认为你需要一个更强的归纳假设。也就是说,您的辅助递归方法需要将偏移量和函数映射特性返回到元组。该函数在应用于偏移量的索引时,返回所有数组的叉积成员,其中删除了空值;在偏移量之上,空案例开始。了解了 n 数组的情况,您可以通过以下三种情况为 n + 1 数组构造新的偏移量和新函数:

    1. 你小于新的偏移量,所以你把它当作最后一个数组的非空成员的简单情况
    2. 你在新偏移量和新旧偏移量之和之间,所以你应该返回递归结果,最后为空
    3. 您大于总和,因此您再次将其视为简单的情况,除非您确保其中的递归调用使用超出旧偏移量的索引

    这是我未经测试的伪代码。

    hard( a, i ) ≡ hardHelper( a, a.length ).second( i )
    hardHelper( a, 0 ) ≡ ( 1, { case 0 => [] } )
    hardHelper( a, n + 1 ) ≡
      let t = a[n + 1].length
      and ( k, f ) = hardHelper( a, n )
      and k' = k * ( t - 1 )
      and f'( i ) =
            if ( i < k' )
            then easyInduction( f, 1 )( a, n + 1, i )
            else if ( k' <= i < k' + k )
            then easyInduction( f, 1 )( a[ 0..n ] ++ [ [ null ] ], n + 1, i - k' )
            else easyInduction( ( b, m, j ) => f( b, m, j + k ), 0 )( a, n + 1, i - k' - k )
       in ( k', f' )
    

    【讨论】:

    • 感谢您的详细回复。我会在本周的某个时候做出回应,当我找到一些空闲时间来进一步分析并测试实施时。我应该考虑使用归纳法;我现在很清楚这是要采取的方法。我已经用了几年了:)
    • 抱歉,我一直没有时间回复这个问题。不幸的是,与此问题相关的要求发生了变化,并要求我更改排序的工作方式。由于排序的复杂性,使用归纳法非常具有挑战性,我转而使用基于评分系统排序的定义的有序列表,并定义用于给定“特异性”分数的索引。由于这是一个不可扩展的问题,我对层次结构的数量和每个层次结构中的值的数量进行了限制。
    • 好的,但我相信我正确回答了您发布的问题。
    猜你喜欢
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2022-07-13
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    相关资源
    最近更新 更多