Algorithm 如何用数学证明编程函数

Algorithm 如何用数学证明编程函数,algorithm,math,Algorithm,Math,这里有一个编程问题: 给出了四个整数A、B、C和D。它们的组合是由这四个整数按一定顺序组成的任何零索引数组M。如果所有给定的整数都是唯一的,那么它们有24种不同的混合 给定整数的最佳混合是任意M个整数的混合,其值为: F(M)=abs(M[0]-M[1])+abs(M[1]-M[2])+abs(M[2]-M[3])是最大的 编写一个函数: 类解{intsolution(inta,intb,intc,intd);} 给定四个整数A、B、C和D,找到它们的最佳混合M并返回F(M)的值 例如,考虑下列

这里有一个编程问题:

给出了四个整数A、B、C和D。它们的组合是由这四个整数按一定顺序组成的任何零索引数组M。如果所有给定的整数都是唯一的,那么它们有24种不同的混合

给定整数的最佳混合是任意M个整数的混合,其值为: F(M)=abs(M[0]-M[1])+abs(M[1]-M[2])+abs(M[2]-M[3])是最大的

编写一个函数:

类解{intsolution(inta,intb,intc,intd);}

给定四个整数A、B、C和D,找到它们的最佳混合M并返回F(M)的值

例如,考虑下列整数: A=5B=3C=-1D=5

它们的最佳组合如下:

M[0]=5

M[1]=-1

M[2]=5

M[3]=3

结果是F(M)=14

假设:

A、 B、C和D是范围内的整数[−1000000..1000000]

复杂性:

期望最坏情况时间复杂度为O(1); 预期最坏情况下的空间复杂度为O(1)

我的想法是:

  • 创建一个数组并按子代顺序对数字进行排序
  • 分配M0[0]=N[3],M[1]=N[0],M[2]=N[2],M[3]=V[1]
  • 澳大利亚统计局星期四【最大数字-最小数字】+【最小数字-第二大数字】+【第二大数字-第二小数字】

  • 我如何证明我的想法是正确的?如何用数学方法证明它?

    这是一个有趣的问题,所以我提出了一种方法,也可以用于一般N

    首先让我解释一下我对4个整数的方法,然后我将解释如何将我们的方法扩展到4个以上的整数

    因此,我正在考虑给定的示例

    Array arr = [A=5, B=-1, C=5, D=3].
    
    应采取的步骤:-

    1. Sort all the numbers, now you the list as follows - -1,3,5,5.
    2. Keep two pointers one start=0 and other end=3.
    3. Take a new list say new_arr and Append arr[3] to new_arr i.e 5. Now without much thinking append arr[0] and arr[1] to both sides of 5.
    4. So our new_arr looks like = -1,5,3.
    5. Increment start += 2 and Decrement end -= 1.
    6. Now we take arr[end] i.e arr[2] = 5 and we check whether abs(new_arr[0]-arr[2]) > abs(new_arr[length]-arr[2]) or not, if yes then append arr[2] to start else append it to the end.
    7. Now our final list looks like - 5,-1,5,3.
    8. Now if you calculate the abs(new_arr[i]-new_arr[i+1]) you will get 14.
    
    您也可以对输入
    100,1,50,51
    测试上述方法,它将为您
    199

    现在,让我们讨论一下如何将其扩展到常规
    N

    因此,一旦我们完成了步骤4。因此,从那时起,对于每个
    start+1
    end+1
    交替,直到
    start
    ,我们检查以下条件:

    abs(new_arr[start]-arr[cur_index]) > abs(new_arr[end]-arr[cur_index]) or not.
    
    基于对每个迭代的检查,我们将附加到前面或后面

    基本上是一种贪婪的方法,它应该起作用,因为我们在中间创造了一个最大元素的山脉和两边的其他小斜坡。


    希望这能有所帮助。

    由于似乎没有向您询问一般解决方案,而且问题规模很小,最简单的方法是对函数调用中的24种排列进行硬编码,以评估成本并保持最佳:

    F(A, B, C, D); 
    F(A, B, D, C); 
    F(A, C, B, D);
    ...
    
    作为一个次要的优化,您可以删除一半对称的情况(函数的计算方法与从左到右或从右到左的计算方法相同),因此只需要12个调用


    高级注意事项:

    我在Wikipedia上找到了这句话:“在具有非负边权重的加权完整图中,加权最长路径问题与旅行商路径问题相同,因为最长路径总是包含所有顶点。”


    如果我是对的,我们正是在这种情况下,所以这个问题是NP难的。这意味着没有希望找到比穷举搜索更好的方法,如上所述。(无论如何,这个问题的例子享受三角不等式,这可能会使它更容易…

    迭代所有可能的组合是不必要的-一个简单的排序,再加上以适当的顺序从结果集合中提取值就是所需要的。您希望将最小的输入值设置为“介于”最大值和第二大值之间,以及最大值旁边的第二小值,所有操作都是为了最大化各种元素的差异。使用以下函数(在Clojure中,是一种Lisp变体):

    在这里,我们获取输入集合
    n
    ,并按降序对其排序以生成“m”,然后根据需要提取值以获得所需结果。然后执行计算(m0-m1)、(m1-m2)、(m2-m3),取每个子结果的绝对值,并求和


    我希望看到一个数据集,该函数不能为其生成所需的结果。

    我认为您的任务要求您编写代码来实现这一点,这是错误的。您只需迭代24个配置并返回最佳配置。@TimBiegeleisen True,尽管一般问题(有N个整数)仍然很有趣。顺便说一句,您的解决方案不正确。考虑这个例子:<代码> [ 1, 50, 51,100 ] < /代码>。您的订单将是
    [100,1,51,50]
    ,总计为
    149
    ,但是
    [50,100,1,51]
    是一个更好的订单,分数为
    199
    。也许最好把N分成两半,从大到小,每一半取一个元素?(也不确定这是否是最优的)。如果你不能证明它是有效的,我就不会依赖这种启发式方法。@YvesDaoust你想让我写一个程序并在一堆案例上测试它吗?不,一些测试永远不会说服我,因为你不确定覆盖范围是否足够。我需要一个数学论证。
    (defn maximal-func [n]
      (let [m  (sort > n)
            m0 (second m)         ; second-largest value
            m1 (last m)           ; smallest input value
            m2 (first m)          ; largest input value
            m3 (second(rest m))]  ; second-smallest value
      (reduce + (map #(Math/abs %) [(- m0 m1) (- m1 m2) (- m2 m3)]))))