Algorithm 对于整数A>;0,B>;0,N>;0,查找整数x>;0,y>;0,使得N-(Ax+;By)是最小的非负

Algorithm 对于整数A>;0,B>;0,N>;0,查找整数x>;0,y>;0,使得N-(Ax+;By)是最小的非负,algorithm,linear-algebra,Algorithm,Linear Algebra,例如: A=5,B=2,N=12 那么让x=2,y=1,那么12-(5(2)+2(1))=0 另一个例子: A=5,B=4,N=12 这里x=1,y=1是最好的。注x=2,y=0更好,但不允许x=0 我在找一些快的东西 注意通过查找Ax+的值就足够了。没有必要显式地给出x或y。如果gcd(A,B)| N,那么N是你的最大值。否则,它是gcd(A,B)的最大倍数,它小于N。以4x+2y=13为例,该值为gcd(4,2)*6=12,由4(2)+2(2)=12实现(在许多解决方案中) 作为一个公式,您

例如:

A=5,B=2,N=12

那么让x=2,y=1,那么12-(5(2)+2(1))=0

另一个例子:

A=5,B=4,N=12

这里x=1,y=1是最好的。注x=2,y=0更好,但不允许x=0

我在找一些快的东西

注意通过查找Ax+的值就足够了。没有必要显式地给出x或y。

如果gcd(A,B)| N,那么N是你的最大值。否则,它是gcd(A,B)的最大倍数,它小于N。以4x+2y=13为例,该值为gcd(4,2)*6=12,由4(2)+2(2)=12实现(在许多解决方案中)

作为一个公式,您的最大值是Floor(N/gcd(a,B))*gcd(a,B)

编辑:如果x和y都必须为正,这可能不起作用。然而,如果a+B>N,这甚至不是一个解决方案。这里有一个算法供您使用

来自数学导入层,ceil
def euclid_wallis(m,n):
col1=[1,0,m]
col2=[0,1,n]
而col2[-1]!=0:
f=-1*(col1[-1]//col2[-1])
col2,col1=[x2*f+x1表示x1,x2表示压缩(col1,col2)],col2
返回col1,col2
def阳性溶液(A、B、N):
(x,y,gcf),(cx,cy,uu)=欧几里德·沃利斯(A,B)
f=N//gcf
当f>0时:
fx,fy,n=f*x,f*y,f*gcf
k_min=(-fx+0.)/cx
k_max=(-fy+0.)/cy
如果cx<0:
k_min,k_max=k_max,k_min
如果floor(k_min)+1一个暴力
O(N^2/A/B)
算法,用普通Python3实现:

import math

def axby(A, B, N):
    return [A * x + B * y
            for x in range(1, 1 + math.ceil(N / A))
            for y in range(1, 1 + math.ceil(N / B))
            if (N - A * x - B * y) >= 0]

def bestAxBy(A, B, N):
    return min(axby(A, B, N), key=lambda x: N - x)
这与您的示例相符:

In [2]: bestAxBy(5, 2, 12)
Out[2]: 12                  # 5 * (2) + 2 * (1)

In [3]: bestAxBy(5, 4, 12)
Out[3]: 9                   # 5 * (1) + 4 * (1)

我不知道那可能是什么算法,但我认为你需要这样的算法(C#)

静态类程序
{
静态整数解算(整数a、整数b、整数N)
{

如果(a)你的问题没有任何意义。请重写它。现在看这个@bikeman868为什么9?5*2+4*0=10。和5*4+4*(-2)=12。仍然没有足够的意义。尽管如此,这可能会有所帮助:我设置了约束条件@sountswhat如果a=5,B=3,N=12@LalitVerma 5*3+3*(-1)=12.最初的问题陈述没有说x和y必须是正的。对不起,我没有提到,但是x,y应该是正整数,上面的公式对此约束失败@RaymondChen@LalitVerma我在Python中添加了一个算法来解释这个约束,它应该是非常优化的,因为没有太多的“强制力”一旦LCM(A,B)
,你可以停止搜索,因为你只会一遍又一遍地看到相同的答案。
static class Program
{
    static int solve( int a, int b, int N )
    {
        if( a <= 0 || b <= 0 || N <= 0 )
            throw new ArgumentOutOfRangeException();
        if( a + b > N )
            return -1;  // Even x=1, y=1 still more then N

        int x = 1;
        int y = ( N - ( x * a ) ) / b;

        int zInitial = a * x + b * y;
        int zMax = zInitial;

        while( true )
        {
            x++;
            y = ( N - ( x * a ) ) / b;
            if( y <= 0 )
                return zMax;    // With that x, no positive y possible
            int z = a * x + b * y;
            if( z > zMax )
                zMax = z;   // Nice, found better
            if( z == zInitial )
                return zMax;    // x/y/z are periodical, returned where started, meaning no new values are expected
        }
    }

    static void Main( string[] args )
    {
        int r = solve( 5, 4, 12 );
        Console.WriteLine( "{0}", r );
    }
}