Project Euler 101 :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 最优多项式的更多相关文章
- Python练习题 048:Project Euler 021:10000以内所有亲和数之和
本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...
- Python练习题 034:Project Euler 006:和平方与平方和之差
本题来自 Project Euler 第6题:https://projecteuler.net/problem=6 # Project Euler: Problem 6: Sum square dif ...
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- Python练习题 029:Project Euler 001:3和5的倍数
开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...
- Project Euler 9
题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...
- 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 ...
- project euler 169
project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...
- 【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 × ...
- Project Euler 第一题效率分析
Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...
随机推荐
- AngularJs学习笔记-AngularJS权威教程学习笔记
AngularJS是什么? AngularJS是一种构建动态Web应用的结构化框架.主要用于构建单页面Web应用, 增加抽象级别,使构建交互式的现代Web应用变得更加简单. AngularJS使开发W ...
- MYSQL与 R
1. 配置MySQL ODBC必须先安装MySQL ODBC driver下载地址可以为:http://www.mysql.com/downloads/connector/odbc/ 2. 控制面板\ ...
- 48.Warning: (vsim-3534) [FOFIR] - Failed to open file "sp_rom_8x256_sr.mif" for reading.
当在仿真ROM IP核文件时,会出现这种警告,而这种警告的结果是ROM不能输出数据,原因是mif文件要放在modelsim工程文件目录下.类似的,有时候会报错,Failed to open file& ...
- vimium
安装在chrome上的一个插件,可以实现chrome无鼠标无键盘操作. 事实上vimium就是提供了一系列的快捷键列表,所以只要熟悉了这些快捷键就可以方便使用了. 要查看快捷键列表,打开chrome, ...
- 在使用SQLite插入数据时出现乱码的解决办法
在VC++中通过sqlite3.dll接口对sqlite数据库进行操作,包括打开数据库,插入,查询数据库等,如果操作接口输入参数包含中文字符,会导致操作异常.例如调用sqlite3_open打开数 ...
- ##常用效果css##
1 绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块.元素被设置成,absolute,原有的位置会被占用,设为 relative原位置 ...
- hope is a good thing!
好久没有写博客了,在这么特殊的日子里,似乎不写点东西感觉总是少了点什么.其实从昨天开始就在努力的回忆,回忆自己这个2014年都做了些什么?自己收获了些什么?突然就觉得去年的那个暑假是那么的熟悉,怎么又 ...
- 我存在,你深深的循环里--从反射看JSON死循环
JSON有一个非常经典的问题:JSONException: There is a cycle in the hierarchy!俗称死循环.解决这个问题至少有三种以上的办法,总之一句话就是过滤.今 ...
- Gulp的安装
Gulp 是前端自动化开发工具,我们可以用它提高开发效率. 它有以下用途: 压缩js.压缩css.压缩less.压缩图片等功能 首先我们开始安装Gulp Gulp是基于node来实现的,所以应该先安装 ...
- ip地址转化代码实例
/*@author: lgh@ * * */ #include <stdio.h> #include <string.h> #include <unistd.h> ...