三分法求极值

该博客介绍了如何运用三分法解决凹凸函数的极值问题,提供了输入、输出的示例。

三分求解凹凸函数的极值问题。


Party All the Time

2000ms
32768KB

In the Dark forest, there is a Fairy kingdom where all the spirits will go together and Celebrate the harvest every year. But there is one thing you may not know that they hate walking so much that they would prefer to stay at home if they need to walk a long way.According to our observation,a spirit weighing W will increase its unhappyness for S3*W units if it walks a distance of S kilometers. 
Now give you every spirit's weight and location,find the best place to celebrate the harvest which make the sum of unhappyness of every spirit the least.

Input

The first line of the input is the number T(T<=20), which is the number of cases followed. The first line of each case consists of one integer N(1<=N<=50000), indicating the number of spirits. Then comes N lines in the order that x[i]<=x[i+1] for all i(1<=i<N). The i-th line contains two real number : Xi,Wi, representing the location and the weight of the i-th spirit. ( |xi|<=106, 0<wi<15 )

Output

For each test case, please output a line which is "Case #X: Y", X means the number of the test case and Y means the minimum sum of unhappyness which is rounded to the nearest integer.

Sample Input

1
4
0.6 5
3.9 10
5.1 7
8.4 10

Sample Output

Case #1: 832


#include<stdio.h>
#include<math.h>
const double eps=1e-4;
double x[50001],w[50001]; int N;
double tri(double x)
{
    return x*x*x;
}
double cal(double h)
{
    double res=0.00000;int i;
    for(i=1;i<=N;i++)
    {
        res+=tri(fabs(x[i]-h))*w[i];
    }
    return res;
}
int main()
{
    int T,i; double left,right,mid,midmid; int Ca=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(i=1;i<=N;i++)
            scanf("%lf%lf",x+i,w+i);
        left=-1e6; right=1e6;
        while(fabs(left-right)>eps)
        {
            mid=(left+right)/2;
            midmid=(mid+right)/2;
            if(cal(mid)<cal(midmid))
                right=midmid;
            else
                left=mid;
        }
        printf("Case #%d: %.0lf\n",Ca,cal(left));
        Ca++;
    }
    return 0;
}


三分极值是一种用于在单峰函数上寻找极值点的算,主要用于在一维空间中高效地定位函数的最大值或最小值。 ### 原理 三分极值的基本原理基于单峰函数的特性。单峰函数是指在定义域内只有一个峰值(最大值)或谷值(最小值)的函数。通过不断将搜索区间划分为三个部分,比较两个三分点的函数值大小,逐步缩小包含极值点的区间,直到达到所需的精度。 经典的三分点选取方式如下: ```python mid1 = l + (r - l)/3 mid2 = r - (r - l)/3 ``` 其中,`l` 和 `r` 分别是当前搜索区间的左右端点。通过比较 `mid1` 和 `mid2` 处的函数值大小,判断极值点位于哪一部分,然后更新搜索区间。这种方式保证每次迭代区间缩小比例恒定 [^4]。 ### 应用 三分极值在实际应用中有广泛的用途,特别是在优化问题中,当目标函数是单峰函数时,可以使用该算来寻找最优解。例如,在数学和物理学等领域,解泛函的极值问题中可能会用到类似的思想 [^3]。在编程竞赛中,如备战蓝桥杯的题目(洛谷P3382)中也会涉及三分法极值的应用 [^4]。 ### 实现方 以下是一个简单的Python代码示例,展示了如何使用三分法单峰函数的极值: ```python def func(x): # 这里定义具体的单峰函数 return -x**2 + 5*x + 10 def ternary_search(l, r, eps=1e-9): while r - l > eps: mid1 = l + (r - l) / 3 mid2 = r - (r - l) / 3 if func(mid1) < func(mid2): l = mid1 else: r = mid2 return (l + r) / 2 # 示例使用 left = -10 right = 10 extreme_point = ternary_search(left, right) print("极值点:", extreme_point) print("极值:", func(extreme_point)) ``` ### 注意事项 - **单峰性验证**:在实际应用中,需要先验证函数是否为单峰函数。如果函数不是单峰的,三分法可能无找到正确的极值点 [^4]。 - **端点处理**:当极值点恰好位于区间端点时,需要额外进行判断 [^4]。 - **系数输入顺序**:在处理多项式函数时,要注意题目要的系数输入顺序,例如有些题目要系数按降幂输入,与常规存储方式不同 [^4]。 ### 复杂度分析 - **时间复杂度**:$O(N\cdot\log(1/\varepsilon))$,其中 $\varepsilon$ 为精度要 [^4]。 - **空间复杂度**:$O(N)$,仅需存储多项式系数 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值