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

时间:2012-11-05 12:16:17

标签: c++ c algorithm integer

我正在寻找一种算法来找到两个整数值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的差异也很小?

5 个答案:

答案 0 :(得分:3)

您必须查看相关数字的平方根。对于21.5 sqrt(21.5)= 4.6368,实际上你找到的数字就在这个值附近。

答案 1 :(得分:2)

您想要最小化

  1. 因素 X Y
  2. 的差异
  3. 产品差异 X×Y P
  4. 您提供了一个示例,其中这些目标相互矛盾 3×7 4×5 更接近 21 ,但后者因素更为正方形。因此,不能有任何同时使两者最小化的算法。

    您可以对两个目标进行加权并将它们转换为一个,然后通过non-linear integer programming解决问题:

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

    其中 c,d 是非负数,用于定义您评估的目标值。

答案 2 :(得分:1)

取平方根,一个整数,然后另一个整数。

#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。如果你想在产品和实际价值之间取得更好的距离,你必须调整整数并增加它们的差异。

答案 3 :(得分:0)

  1. 让双给K。

  2. 取K的地板,让它成为F.

  3. 取两个大小为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 ;            
       }
    }
    
  5. 您现在可以获得所有可能数字的差异/产品对。现在为产品接近值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) ; 
        }
    

    遍历Ar3以找到最大值,即您正在寻找的对。

答案 4 :(得分:0)

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;
    }
}