Algorithm 如何用数学证明编程函数
这里有一个编程问题: 给出了四个整数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)的值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=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) 我的想法是:我如何证明我的想法是正确的?如何用数学方法证明它?这是一个有趣的问题,所以我提出了一种方法,也可以用于一般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)]))))