Error Curves UVA - 1476(三分求最值)

Josephina is a clever girl and addicted to Machine Learning recently. She pays much attention to a
method called Linear Discriminant Analysis, which has many interesting properties.
In order to test the algorithm’s efficiency, she collects many datasets. What’s more, each data is
divided into two parts: training data and test data. She gets the parameters of the model on training
data and test the model on test data.
To her surprise, she finds each dataset’s test error curve is just a parabolic curve. A parabolic curve
corresponds to a quadratic function. In mathematics, a quadratic function is a polynomial function of
the form f(x) = ax2 + bx + c. The quadratic will degrade to linear function if a = 0.
It’s very easy to calculate the minimal error if there is only one test error curve. However, there
are several datasets, which means Josephina will obtain many parabolic curves. Josephina wants to
get the tuned parameters that make the best performance on all datasets. So she should take all error
curves into account, i.e., she has to deal with many quadric functions and make a new error definition
to represent the total error. Now, she focuses on the following new function’s minimal which related to
multiple quadric functions.
The new function F(x) is defined as follow:
F(x) = max(Si(x)), i = 1 . . . n. The domain of x is [0, 1000]. Si(x) is a quadric function.
Josephina wonders the minimum of F(x). Unfortunately, it’s too hard for her to solve this problem.
As a super programmer, can you help her?
Input
The input contains multiple test cases. The first line is the number of cases T (T < 100). Each case
begins with a number n (n ≤ 10000). Following n lines, each line contains three integers a (0 ≤ a ≤ 100),
b (|b| ≤ 5000), c (|c| ≤ 5000), which mean the corresponding coefficients of a quadratic function.
Output
For each test case, output the answer in a line. Round to 4 digits after the decimal point.
Sample Input
2
1
2 0 0
2
2 0 0
2 -4 2
Sample Output
0.0000
0.5000

题意:
给出n条s[i] = axx + b*x + c
令f[i] = max{s[k}
求出f[i]的最小值
思路:
三分算法求最值。针对于凸函数(百科上是如a为正数的二次函数曲线)。
本题图图像就是一个凸函数。
因为a ≥ 0,本身就是许多凸函数的和(a=0时为直线,那么斜率是什么都可以看做凸函数)
那么这就是许多凸函数相交。
两个这样的二次函数相交,有三种情况。
无交点或全交:那么一个函数可以直接替换掉另外一个函数。
有一个交点:那么交点两侧较高的区间代替两个函数,交点本身成为最小值,仍然是凸函数。
有两个交点:两个交点中间的中间曲线和左右较高曲线取代两个函数,最小值在两个交点之一,仍然是凸函数。
所以很多凸函数相交,结果仍然是凸函数。

对于此类函数只有一个最值点。以本题求最小值为例。
那么设置m1 = l + (r - l), m2 = l + 2 * (r - l)。

那么当m1 和 m2同时再最小值右侧或同时在最小值左侧的时候,
当f(m1) < f(m2),区间左移 r = m2,属于同时再左侧的情况
否则区间右移 l = m1,属于同时在右侧的情况。

但是当m1和m2分别再两侧的情况时候,f(m1) 和 f(m2)的大小关系无论如何,区间都得移动,所以同理适用于原来的移动关系。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const double INF = 0x3f3f3f3f;
const int maxn = 1e4 + 7;
const double eps = 1e-9;
double a[maxn],b[maxn],c[maxn];
int n;

double f(double x)
{
    double ans = -INF;
    for(int i = 1;i <= n;i++)
    {
        ans = max(ans,a[i] * x * x + b[i] * x + c[i]);
    }
    return ans;
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
        
        double l = 0.0,r = 1000.0;
        while(r - l > eps)
        {
            double m1 = l + (r - l) / 3,m2 = l + (r - l) / 3 * 2;
            if(f(m1) < f(m2))
            {
                r = m2;
            }
            else
            {
                l = m1;
            }
        }
        printf("%.4f\n",f(l));
    }
    return 0;
}

发布了676 篇原创文章 · 获赞 18 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104242571