如何更有效地从一个数中找到最小的Vector3组合?

我正在尝试从一个单独的数字中找到最小的Vector3组合,到目前为止,我有工作代码,但效率不高。

为了演示,假设用户输入数字_n_,函数应输出由3个数字( _x,y,z_)组成的组合,这个组合的和最小,同时仍然能够乘以原始数字_n_。

因此,如果用户输入100作为n,则x,y和z应该分别为4、5和5。 (或者(5,5,4) ; (5,4,5))。

我正在做3个for循环来计算x,y和z的独立值。 它在小数字下运行得很好,但随着_n_的增加,它变得非常重量级。 我正在寻找任何可以改变计算方法使其更快的方法。 我愿意使用近似算法,因为这不需要100%的准确性。

我最初用Lua编写了它,但问题与一种语言没有直接关系。

function CalculateVector(Size)
    local Vectors = {}
    local Lowest = math.huge
    local Index = nil
    for x = 0, Size, 1 do
        for y = 0, Size, 1 do
            for z = 0, Size, 1 do
                if Size - (x * y * z) == 0 then
                    table.insert(Vectors, Vector3.new(x, y, z))
                end
            end
        end
    end
    table.foreachi(Vectors, function(i, v)
        local Combined = v.X + v.Y + v.Z
        if Combined < Lowest then
            Lowest = Combined
            Index = i
        end
    end)
    return Vectors[Index]
end

同样的代码在Python中,以防有人不知道Lua语法。

class Vector3:
    def __init__(self, x, y, z):
        self.X = x
        self.Y = y
        self.Z = z

def CalculateVector(Size):
    Vectors = []
    Lowest = Size + 3
    Index = None
    for x in range(Size):
        for y in range(Size):
            for z in range(Size):
                if Size - (x * y * z) == 0:
                    Vectors.append(Vector3(x, y, z))
    for i,v in enumerate(Vectors):
        Combined = v.X + v.Y + v.Z
        if Combined < Lowest:
            Lowest = Combined
            Index = i
    return Vectors[Index]
点赞
用户1847592
用户1847592

n 分解质因数并测试将所有质因数分裂成 3 个集合的情况

function split_number_into_factors_having_min_sum(n, factors)
   assert(n > 0 and factors > 0)
   local primes = {}
   local degrees = {}
   local terms = {}
   local p = 2
   local step = {4, 1, 2, 0, 2}
   local m = 0
   while n > 1 do
      if p * p > n then
         p = n
      end
      if n % p == 0 then
         local d = 0
         repeat
            d = d + 1
            n = n / p
         until n % p ~= 0
         m = m + 1
         primes[m] = p
         degrees[m] = d
         terms[m] = {}
      end
      p = p + step[p % 6]
   end
   local parts = {}
   for j = 1, factors do
      parts[j] = 1
   end
   local best_sum = math.huge
   local best_parts = {}
   local process_next_prime

   local function split_in_terms(sum, qty, k)
      if qty < factors then
         local max_val = parts[qty] == parts[qty + 1] and sum > terms[k][qty] and terms[k][qty] or sum
         qty = qty + 1
         local min_val = qty == factors and sum or 0
         for val = min_val, max_val do
            terms[k][qty] = val
            split_in_terms(sum - val, qty, k)
         end
      else
         local p = primes[k]
         for j = 1, factors do
            parts[j] = parts[j] * p^terms[k][j]
         end
         process_next_prime(k)
         for j = 1, factors do
            parts[j] = parts[j] / p^terms[k][j]
         end
      end
   end

   function process_next_prime(k)
      if k < m then
         split_in_terms(degrees[k + 1], 0, k + 1)
      else
         local sum = 0
         for j = 1, factors do
            sum = sum + parts[j]
         end
         if sum < best_sum then
            best_sum = sum
            for j = 1, factors do
               best_parts[j] = parts[j]
            end
         end
      end
   end

   process_next_prime(0)
   table.sort(best_parts)
   return best_parts
end

用法:

local t = split_number_into_factors_having_min_sum(100, 3)
print(unpack(t))  --> 4 5 5
2020-08-25 22:42:05