Algorithm 求极小函数
好吧,就这么定了。我有一堆线性函数,a*x+b 我的目标是回答以下问题:x=q的最小函数是什么 例如:如果我有函数f(x)=3*x+2,g(x)=5*x-6和h(x)=2*x+1,我将回答例如: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
- 对于x=4,函数h
- 对于x=2,函数g
- 对于x=1,函数g
提前谢谢。您能不能先解决它们的交点,然后在域中存储每个区间的最大函数 编辑- 更详细地说,如果要为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
。函数与查询的比率是多少?这将给出一个什么样的预计算是合理的想法。