找到两个整数,使它们的产品接近给定的真实

Find two integers such that their product is close to a given real

本文关键字:接近 真实 整数 两个      更新时间:2023-10-16

我正在寻找一种算法来找到两个整数值 x,y,以便它们的产品与给定的双k尽可能接近,而它们的差异很低。

示例:矩形的区域是k=21.5,我想找到该矩形的边缘长度,并以它们必须是整数的约束,在这种情况下,某些可能的解决方案是排列)(x=4,y=5)(x=3,y=7)和愚蠢的解决方案(x=21,y=1)

实际上,对于(3,7)夫妇,我们的差异与(21,1)夫妇

相同

21.5-3*7=0.5 = 21.5-21*1

对于(4,5)夫妇 21.5-4*5=1.5

,但这对 (4,5)是可取的,因为它们的差异是1,因此矩形是"更平方的"。

是否有一种提取x,y值的方法,其差异是最小的,并且其产品与K的差异也很小?

您必须围绕所讨论的数字的平方根。对于21.5 SQRT(21.5)= 4.6368,实际上您发现的数字就在此值左右。

您要最小化

  1. 因素的差异 x y
  2. 产品的差异 x×y p

您提供了一个示例,其中这些目标彼此矛盾 3×7 21 更接近 4×5 ,但后一个因素更为正方形。因此,不能有任何同时最大程度地减少这两个算法。

您可以加权两个目标并将它们转换为一个目标,然后通过非线性整数编程解决问题:

       min c × |X × Y - P|  +  d × |X – Y|
subject to X, Y ∈ ℤ
           X, Y ≥ 0

其中 c,d 是定义您重视数量的目标的非负数。

取平方根,地板一个整数,另一个。

#include <iostream>
#include <cmath>
int main(){
    double real_value = 21.5;
    int sign = real_value > 0 ? 1 : -1; 
    int x = std::floor(std::sqrt(std::abs(real_value)));
    int y = std::ceil(std::sqrt(std::abs(real_value)));
    x *= sign;
    std::cout << x << "*" << y << "=" << (x*y) << " ~~ " << real_value << "n";
    return 0;
}

请注意,这种方法仅给您xy之间的距离,例如,如果real_value = 10则是x=3y=4,但是产品为12。如果您想在产品和实际价值之间达到更高的距离,则必须调整整数并增加它们的差异。

double best = DBL_MAX;
int a, b;
for (int i = 1; i <= sqrt(k); i++)
{
    int j = round(k/i);
    double d = abs(k - i*j);
    if (d < best)
    {
        best = d;
        a = i;
        b = j;
    }
}
  1. 让双double为k。

  2. 占用K的地板,让它为f。

  3. 取2个大小f*f的整数阵列。让它们为ar1,ar2。

  4. 像以下这样的循环

    int z = 0 ;
    for ( int i = 1 ; i <= F ; ++i )
    {
       for ( int j = 1 ; j <= F ; ++j )           
       {
           Ar1[z] = i * j ;
           Ar2[z] = i - j ; 
           ++ z ;            
       }
    }
    

现在,您可以为所有可能的数字提供差异/产品对。现在,分配一些"优先级值",以使产品接近值K,而另一些则与较小的差异分配。现在将这些阵列从0到f*f,并通过检查状况找到您需要的对。

例如。让靠近K具有优先级1,并且差异较小具有优先级.5。考虑另一个大小f*f的数组AR3。然后,

    for ( int i = 0 ; i <= F*F ; ++i )
    {
       Ar3[i] = (Ar1[i] - K)* 1 + (Ar2[i] * .5) ; 
    }

traverse ar3要找到最大的值,那将是您要寻找的对。