Optimum polynomial

If we are presented with the first k terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.

As an example, let us consider the sequence of cube numbers. This is defined by the generating function,
un = n3: 1, 8, 27, 64, 125, 216, …

Suppose we were only given the first two terms of this sequence. Working on the principle that “simple is best” we should assume a linear relationship and predict the next term to be 15 (common difference 7). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.

We shall define OP(k, n) to be the nth term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that OP(k, n) will accurately generate the terms of the sequence for n ≤ k, and potentially the first incorrect term (FIT) will be OP(k, k+1); in which case we shall call it a bad OP(BOP).

As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for n ≥ 2, OP(1, n) = u1.

Hence we obtain the following OPs for the cubic sequence:

   
OP(1, n) = 1 1, 1, 1, 1, …
OP(2, n) = 7n−6 1, 8, 15, …
OP(3, n) = 6n2−11n+6 1, 8, 27, 58, …
OP(4, n) = n3 1, 8, 27, 64, 125, …

Clearly no BOPs exist for k ≥ 4.

By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain 1 + 15 + 58 = 74.

Consider the following tenth degree polynomial generating function:

un = 1 − n + n2 − n3 + n4 − n5 + n6 − n7 + n8 − n9 + n10

Find the sum of FITs for the BOPs.


最优多项式

如果我们知道了一个数列的前k项,我们仍无法确定地给出下一项的值,因为有无穷个多项式生成函数都有可能是这个数列的模型。

例如,让我们考虑立方数的序列,它可以用如下函数生成,
un = n3: 1, 8, 27, 64, 125, 216, …

如果我们只知道数列的前两项,秉承“简单至上”的原则,我们应当假定这个数列遵循线性关系,并且预测下一项为15(公差为7)。即使我们知道了数列的前三项,根据同样的原则,我们也应当首先假定数列遵循二次函数关系。

给定数列的前k项,定义OP(k, n)是由最优多项式生成函数给出的第n项的值。显然OP(k, n)可以精确地给出n ≤ k的那些项,而可能的第一个不正确项(First Incorrect Term,简记为FIT)将会是OP(k, k+1);如果事实的确如此,我们称这个多项式为坏最优多项式(Bad OP,简记为BOP)。

在最基本的情况下,如果我们只得到了数列的第一项,我们应当假定数列为常数,也就是说,对于n ≥ 2,OP(1, n) = u1。

由此,我们得到了立方数列的最优多项式如下:

   
OP(1, n) = 1 1, 1, 1, 1, …
OP(2, n) = 7n−6 1, 8, 15, …
OP(3, n) = 6n2−11n+6 1, 8, 27, 58, …
OP(4, n) = n3 1, 8, 27, 64, 125, …

显然,当k ≥ 4时不存在坏最优多项式。

所有坏最优多项式的第一个不正确项(用红色标示的数)之和为1 + 15 + 58 = 74。

考虑下面这个十阶多项式生成函数:

un = 1 − n + n2 − n3 + n4 − n5 + n6 − n7 + n8 − n9 + n10

求其所有坏最优多项式的第一个不正确项之和。

解题

mathblog 提到拉格朗日多项式,突然明白了。

wiki中拉格朗日多项式的定义,在数值计算方法中叫拉格朗日差值函数

上面第k+1项就是所求的答案,至于为什么?已知的点很显然能够准确的预测出来,对于未知的点,为什么第k+1个点不能够预测对?

根据上面博客中写的程序,我记忆中本科时候好像写过这个程序的。

Java

package Level4;

public class PE0101{
public static void run(){
Lagrange(); }
public static void Lagrange(){
long[] coef = {1,-1,1,-1,1,-1,1,-1,1,-1,1};
Polynomial poly = new Polynomial(coef); long[] y = new long[coef.length];
for(int i=0;i<y.length;i++)
y[i] = poly.evaluate(i+1); long fits = 0;
for(int n=1;n<=coef.length -1;n++){
long result = 0;
for(int i =1;i<=n;i++){
long tmp1 = 1;
long tmp2 = 1;
for(int j=1;j<=n;j++){
if(i==j)
continue;
else{
tmp1 *= n + 1-j;
tmp2 *= i-j;
}
}
result +=tmp1*y[i-1]/tmp2;
}
fits +=result;
}
System.out.println(fits);
} public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms");
// 37076114526
// running time=0s1ms
}
}
class Polynomial{
private long[] coef;
public int Degree;
public Polynomial(int deg){
Degree = deg;
coef = new long[deg+1];
}
public Polynomial(long[] coef){
Degree = coef.length - 1;
this.coef = coef;
}
public long get(int i){
return coef[i];
}
public void set(int i,long value){
coef[i] = value;
}
public long evaluate(long x){
long result =0;
for(int i= this.Degree;i>=0;i--){
result = result *x +get(i);
}
return result;
} }

Python

# coding=gbk

import time as time
import re
import math def run():
y = ploy()
fits = 0
for n in range(1,11):
res = 0
for i in range(1,n+1):
tmp1 = 1
tmp2 = 1
for j in range(1,n+1):
if i==j:
continue
else:
tmp1 *= (n+1-j)
tmp2 *= (i-j)
res += tmp1*y[i-1]/tmp2
fits += res
print res
def ploy():
coef = [1,-1,1,-1,1,-1,1,-1,1,-1,1]
y = list() for n in range(1,11):
res = 1
m = n
for i in range(1,11):
res = res + coef[i] * m
m *=n
y.append(res)
print y
return y t0 = time.time()
run()
t1 = time.time()
print "running time=",(t1-t0),"s"

Project Euler 101 :Optimum polynomial 最优多项式的更多相关文章

  1. Python练习题 048:Project Euler 021:10000以内所有亲和数之和

    本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...

  2. Python练习题 034:Project Euler 006:和平方与平方和之差

    本题来自 Project Euler 第6题:https://projecteuler.net/problem=6 # Project Euler: Problem 6: Sum square dif ...

  3. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  4. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  5. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  6. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  7. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  8. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

  9. Project Euler 第一题效率分析

    Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...

随机推荐

  1. 2.2孙鑫C++

    1.继承 动物有 吃 睡 呼吸的方法 当然 鱼也有    不用重复再定义 1)public 那里都可以访问 #include <iostream.h> class Animal //类 基 ...

  2. PB中获取datawindow提交的sql语句

    PB的群里边,有人问的到这个问题,查了一下,综合了两条回答,得到了答案 1.DW 控件的SQLpreview 事件里的sqlsyntax 参数即是 2.pb一般使用占位符优化SQL语句,也就是你看到的 ...

  3. C++函数的参数传递机制以及参数的类型选择

    C++primer之函数的参数传递以及参数的类型 一:函数的基本知识 (1)      函数要素:返回类型,函数名字,形参(参数之间用逗号隔开) (2)      函数调用机制:我们通过调用运算符来执 ...

  4. Delphi 路径相关函数

    IncludeTrailingPathDelimiter(const S: string): string; 功能 返回包括最后路径分隔符 说明 最后一个字符是路径分隔符则不变;否则加上一个路径分隔符 ...

  5. 委托、匿名委托和lambda表达式

    1.委托 在.NET中,委托有点类似于C/C++中的函数指针,但与指针不同的是,委托是一种安全的类型,那么我们就以实现两个数的差为例,先声明一个成员方法: public int CompareTwoV ...

  6. C#外挂QQ找茬辅助源码,早期开发

    这是一款几年前开发的工具,当年作为一民IT纯屌,为了当年自己心目中的一位女神熬夜开发完成.女神使用后找茬等级瞬间从眼明手快升级为三只眼...每次看到这个就会想起那段屌丝与女神的回忆.今天特地把代码更新 ...

  7. Codeforces Round #109 (Div. 2) E. Double Profiles hash

    题目链接: http://codeforces.com/problemset/problem/155/E E. Double Profiles time limit per test 3 second ...

  8. Ext中获取button的思考

    今天在获取window中的button时,发现通过component无法获取,具体表现为: Ext.getCmp('loginForm').ownerCt.getComponent('btn_logi ...

  9. bzoj 3170 manhattan距离

    首先将坐标系顺时针旋转45度,得到一个新的坐标系,这个坐标系 对应的坐标的manhattan距离就是原图中的距离,然后快排,利用前缀和 数组O(N)求所有的答案,然后找最小值就行了,总时间O(Nlog ...

  10. 【BZOJ】【2756】【SCOI2012】奇怪的游戏

    网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...