在给定的时间间隔内查找 a,b,c,x,y,z 的所有可能值,使得 a^x+b^y=c^z

本文关键字:x+b 使得 有可能 时间 查找 | 更新日期: 2023-09-27 18:27:53

我想制作 C# 程序,用于在给定间隔内查找正整数 a,b,c,x,y,z 的组合,以便 a^x+b^y=c^z。 变量 a,b,c 必须在区间 [abc_min,abc_max] 中,x,y,z 必须在区间 [xyz_min,xyz_max] 中。我尝试使用六个 for 循环,但它非常慢。有没有更好的代码可以在非常大的时间间隔(例如 [0,100](内短时间内查找所有组合?这是我的代码,但它很慢:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
namespace ConsoleApplication8
{
class Program
{
    static void Main(string[] args)
    {
        try
        {
            int abc_min = 3, abc_max = 10, xyz_min = 3, xyz_max = 20, num = 0;
            int a, b, c, x, y, z;
            BigInteger p1, p2, p3;
            for (a = abc_min; a <= abc_max; a++)
            {
                for (b = abc_min; b <= abc_max; b++)
                {
                    for (c = abc_min; c <= abc_max; c++)
                    {
                        for (x = xyz_min; x <= xyz_max; x++)
                        {
                            for (y = xyz_min; y <= xyz_max; y++)
                            {
                                for (z = xyz_min; z <= xyz_max; z++)
                                {
                                    p1 = BigInteger.Pow(a, x);
                                    p2 = BigInteger.Pow(b, y);
                                    p3 = BigInteger.Pow(c, z);
                                    if (p1 + p2 == p3)
                                    {
                                        Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", a, x, b, y, c, z);
                                        num += 1;                                            
                                        Console.ReadKey();
                                        Console.WriteLine("----------------------------'n");
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Console.WriteLine("{0} instances found.", num);
        }
        catch
        {
            Console.WriteLine("'nError occured.");
        }
        Console.ReadKey();
    }
}

}

在给定的时间间隔内查找 a,b,c,x,y,z 的所有可能值,使得 a^x+b^y=c^z

您可以最初计算给定间隔内所有a值的 x 次幂数组:

BigInteger[,] abcPow = new BigInteger[abc_max - abc_min + 1, xyz_max - xyz_min + 1];
for (a = abc_min; a <= abc_max; a++)
    for (x = xyz_min; x <= xyz_max; x++)
        abcPow[a - abc_min, x - xyz_min] = BigInteger.Pow(a, x);

然后,您无需在每次迭代时计算BigInteger.Pow

for (a = abc_min; a <= abc_max; a++)
{
    for (b = a; b <= abc_max; b++)
    {
        for (c = abc_min; c <= abc_max; c++)
        {
            for (x = xyz_min; x <= xyz_max; x++)
            {
                p1 = abcPow[a - abc_min, x - xyz_min];
                for (y = xyz_min; y <= xyz_max; y++)
                {
                    p2 = abcPow[b - abc_min, y - xyz_min];
                    for (z = xyz_min; z <= xyz_max; z++)
                    {
                        p3 = abcPow[c - abc_min, z - xyz_min];
                        if (p1 + p2 == p3)
                        {
                            Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", a, x, b, y, c, z);
                            num++;
                            Console.ReadKey();
                            Console.WriteLine("----------------------------'n");
                            if (a != b)
                            {
                                Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", b, y, a, x, c, z);
                                num++;
                                Console.ReadKey();
                                Console.WriteLine("----------------------------'n");
                            }
                        }
                        else if (p1 + p2 < p3)
                        {
                            // No more solutions could be found for the given z
                            break;
                        }
                    }
                }
            }
        }
    }
}

请注意,p1 = ...p2 = ...移出了内部循环,因为它们不依赖于内部循环的变量。

编辑
由于a^x + b^y = b^y + a^x,从a开始循环是有意义的b当找到解决方案时,如果a != b,则输出两个解决方案。

在我的机器上,它以 ~20 倍的速度加快了计算速度。

这里有

一个想法。

首先,定义看起来像这样的类(这都是转述的 C#,可能需要重构(:

class Exponential
{
    public int base;
    public int power;
}
class ExponentialResult : List<Exponential>
{
    private BigInteger result;
    public ExponentialResult(BigInteger value)
    {
        result = value;
    }
    public BigInteger Result
    {
        get { return result; }
    }
}
public BigIntegerComparer : IComparer
{
    public int Compare(BigIntegerComparer x, BigIntegerComparer y)
    {
        return (int) BigInteger.Subtract(x, y);
    }
}

然后,您需要使用如下所示的内容将表单(base^power(的所有值累积到Exponential对象中

public Dictionary<BigInteger, ExponentialResult> AccumulateRange(int base_min, int base_max, int power_min, int power_max)
{
    Dictionary<BigInteger, ExponentialResult> dictionary = new Dictionary<BigInteger, ExponentialResult>();
    for (int base = base_min; base <= base_max; ++base)
    {
        for(int power = power_min; power <= power_max; ++power)
        {
            Exponential exp = new Exponential();
            exp.base = base;
            exp.power = power;
            BigInteger result = BigInteger.Pow(base, power);
            ExponentialResult set;
            if (!dictionary.TryGetValue(result, out set))
            {
               set = new ExponentialResult(result);
               dictionary.Add(result, set);
            }
            set.Add(exp);
        }
    }
}

从指定的范围内获得整组值后,您将需要对它们进行排序并正确迭代它们,并检查添加和不添加的内容:

public void Calculate(IDictionary<BigInteger, ExponentialResult> dictionary)
{
    SortedList<BigInteger, ExponentialResult> list = new SortedList<BigInteger, ExponentialResult>(dictionary, new BigIntegerComparer());
    foreach (KeyValuePair<BigInteger, ExponentialResult> kv1 in list)
    {
        foreach (KeyValuePair<BigInteger, ExponentialResult> kv2 in list)
        {
            ExponentialResult sum;
            if (list.TryGetValue(BigInteger.Add(kv1.Key, kv2.Key), out sum))
            {
               //we have found one such that a^x + b^y = c^z
            }
            if (kv1 == kv2)
            {
                break;
            } 
        }
    }
}

然后,在注释所在的if的内部,累积一组结果,使得存储在ExponentialResult kv1.Value中的所有对,加上存储在ExponentialResult kv2.Value中的所有对,导致存储在ExponentialResult sum中的所有对。