Algorithm 求极小函数

Algorithm 求极小函数,algorithm,optimization,geometry,Algorithm,Optimization,Geometry,好吧,就这么定了。我有一堆线性函数,a*x+b 我的目标是回答以下问题:x=q的最小函数是什么 例如:如果我有函数f(x)=3*x+2,g(x)=5*x-6和h(x)=2*x+1,我将回答例如: 对于x=4,函数h 对于x=2,函数g 对于x=1,函数g 我的想法是这样的: 按x的系数按降序对函数进行排序 按递增顺序对查询进行排序 去掉并行函数,保留常数项最小的函数(例如:如果我有f(x)=2*x+4和g(x)=2*x+2,f(x)永远不会小于g(x),所以我不需要f(x)) 现在我在从-i

好吧,就这么定了。我有一堆线性函数,a*x+b

我的目标是回答以下问题:x=q的最小函数是什么

例如:如果我有函数f(x)=3*x+2,g(x)=5*x-6和h(x)=2*x+1,我将回答例如:

  • 对于x=4,函数h

  • 对于x=2,函数g

  • 对于x=1,函数g

我的想法是这样的:

  • 按x的系数按降序对函数进行排序

  • 按递增顺序对查询进行排序

  • 去掉并行函数,保留常数项最小的函数(例如:如果我有f(x)=2*x+4和g(x)=2*x+2,f(x)永远不会小于g(x),所以我不需要f(x))

  • 现在我在从-inf到某个实数的区间上,称之为w1,我知道在这个区间上,线性系数最高的函数是最小的

  • 通过查找最小的x1 s.t.f(x1)=g(x1)来查找w1,其中f是我的当前函数,g使用较小的线性系数,对所有其他函数进行迭代,w1=x1

  • 只要我的查询在间隔(-inf,w1)内,就重复此操作:输出当前函数,然后继续下一个查询

  • 如果我仍然有需要回答的查询,那么让当前函数在x=w1处与我的实际当前函数相交,而不是-inf put w1,重复相同的步骤

  • 然而,我的实现或想法不够快。有没有什么我没有注意到的东西可以加速我的程序


    提前谢谢。

    您能不能先解决它们的交点,然后在域中存储每个区间的最大函数

    编辑- 更详细地说,如果要为x解任意一对函数,那么x表示这两个函数中的一个大于另一个的值。有可定义的区间,其中最小函数对于区间中的所有值都是相同的

    下面是3个示例函数的曲线图。

    该图的区间(带有相应的最小函数)为

    (-∞, 7/3]     => 5x - 6
    (7/3, ∞]      => 2x + 1
    
    现在,在运行时,您只需执行“q属于哪个区间”,而不是“x=q的最小函数是什么”


    如果我没弄错的话,如果你有N个线性函数,你最多可以存储N-1个区间。而且,如果你真的有很多函数要分析,你可以使用专门的数据结构来存储和搜索区间。

    如果我理解正确,你的解决方案是对所有函数进行一些预处理,以便将
    x
    的域分为多个范围,在每一个这样的范围内,你知道什么是最小函数

    实际上有两个阶段:“准备”和“查询”(给定一个特定的
    x
    你给出结果)

    你的瓶颈是什么

    自然地,“查询”阶段要快,你应该将你的范围组织成一种排序数组,这样你就可以在对数时间内通过中值搜索(或类似搜索)找到包含给定
    x
    的范围。如果这是你所做的,而且这还不够快-考虑代码级优化,因为从算法的角度来看,这似乎是最理想的解决方案。 如果您的瓶颈是“准备”阶段-这里有优化的机会。据我所知,您可以找到所有函数对的交点(在去掉并行函数后)。这并不是真的必要

    考虑以下几点。首先,按系数对所有函数进行排序(较高的系数在开头)。去掉并行函数。接下来,在遍历函数的同时构建范围数组

    由于当前函数的系数最低(在已经分析过的函数中),因此当
    x
    趋于无穷大时,当前函数将是最小的函数。所以它的范围应该是从一些
    x0
    到无穷大。找到
    x0
    。从数组中选取最后一个范围(属于先前处理的函数),并找到该函数与当前函数的交点。前一个范围缩小到
    x0
    。如果该范围变得无效(范围开始大于
    x0
    )-表示该功能完全模糊。在这种情况下-删除该范围,然后重复该步骤

    为了让事情更清楚,我将编写一个伪代码:

    rangeArr
    是成对的数组
    F,X
    ,而
    F
    是功能描述,
    X
    是功能范围的开始。功能范围的结束被视为下一个范围的开始,最后一个功能范围的结束被视为+无穷大

    for each F sorted by coefficient
    {
        double x0;
    
        while (true)
        {
            if (rangeArr is empty)
            {
                x0 = -inf;
                break;
            }
    
            FPrev = rangeArr.back().F;
            xPrev = rangeArr.back().X;
    
            x0 = IntersectionOf(F, FPrev);
    
            if (x0 > xPrev)
                break;
    
            rangeArr.DeleteLastRange();
        }
    
        rangeArr.InsertRange(F, x0);
    }
    

    你能解释一下“每个间隔”是什么意思吗?我相信如果你检查每个交叉口,建立这些间隔将花费
    N^2
    。函数与查询的比率是多少?这将给出一个什么样的预计算是合理的想法。