用于找到最大n的最快算法,使得x ^ n <= y

时间:2017-07-24 13:26:54

标签: c algorithm math gmp

我正在开发一个项目,要求我找到最大的n,使得x ^ n&lt; = y,其中提供x和y。我正在使用gmp库并在c中使用大量数字。

约束:

x&gt; = 1&amp; Y'GT; = 1

使用我想到的第一种方法,当x = 12且y = 411 ^ 20000时,花了大约5秒来找到n,即

int n=0;
int x=12;
int y=100;
int temp;
int answer;
while(1)
{
    temp = pow(x,n);
    if(temp>y)
        {
            answer = n-1;
            return(0);
        }
   n++;
}

注意:不是实际代码。不想用gmp语法使事情复杂化

是否有更快的算法? 整个代码: https://pastebin.com/J1vbmEbK

3 个答案:

答案 0 :(得分:11)

如果gmp library包含对数函数,请使用

result = Floor(log(y)/log(x))

否则您可以尽可能利用binary search - square x (x, x^2, x^4, x^8),然后减少权力步骤

使用常用号码进行检查的快速而脏的实施

returns 24 for x = 2; y = 31415926.0;
(same as Floor(ln(y)/ln(x))

int FindXPower(double x, double y) 
{
  int Powers[64];
  double t, s, next;
  int ix;

  //exponential search phase
  ix = 0;
  t = x;
  while (t <= y)
  {
    Powers[ix++] = t;  //remember them to use later
    t = t * t;
  };
  //now powers contain [x,x^2,x^4,x^8,x^16...]

  ix--;
  int Result = 1 << ix;  // 2^lastindex: 1,2,4,8,16,32...

  //binary search phase
  s = Powers[ix--];     //max value after squaring
  while ((s < y) && (ix >= 0))
  {
     t = Powers[ix];
     next = s * t;
     while (next < y)
     {
      s = next;
      next = next * t;
      Result = Result + (1<<ix);
     }
     ix--;
  };
  return Result;
}

答案 1 :(得分:0)

您可以通过二分法搜索正确的值,而不是线性减少n

定义两个变量:n_lown_high,其不变量在任何时刻x^n_high严格大于yx^n_low小于y或等于m

在每次迭代时,计算n_high的值,该值将n_lowx^m之间的距离减半。

然后将yn_high = m进行比较。如果严格限制,请分配:n_low = m否则指定n_low+1==n_high。当n_low import numpy as np import cv2 # face file face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # eye file eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') # head shoulders file hs_cascade = cv2.CascadeClassifier('HS.xml') cap = cv2.VideoCapture(1) while 1: ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) headshoulders = hs_cascade.detectMultiScale(gray, 1.3, 3) # find the head and shoulders for (x,y,w,h) in headshoulders: # variable change to make portrait orientation x = int(x*1.5) w = int(w/1.5) cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # crop the image crop_img = img[y: y + h, x: x + w] # show original and crop cv2.imshow('crop', crop_img) cv2.imshow('img', img) k = cv2.waitKey(30) & 0xff if k == 27: break elif k == ord('s'): # save out the portrait image cv2.imwrite('cropimage.png',crop_img) # release the camera cap.release() cv2.destroyAllWindows() 的值是您正在寻找的值时。

答案 2 :(得分:0)

我假设你正在使用任意精度整数(GMP也支持任意精度浮点)。

  • 将bigints转换为浮点数。这将导致舍入错误。
  • 估算结果await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async () => { ... } );
  • 实际的n_est = floor(log(y_float) / log(x_float))可以是nn_est - 1n_est,可以轻松查看。