为了账号安全,请及时绑定邮箱和手机立即绑定

为 N 个单元格的网格找到最佳行和列

为 N 个单元格的网格找到最佳行和列

holdtom 2023-03-10 13:48:29
我正在尝试创建一个网格,该网格必须具有足够的行和列以适应length单元格的数量。这里有些例子:- Length: 8: 2 rows x 4 cols - Length: 9: 3 rows x 3 cols - Length: 10: 5 rows x 2 cols - Length: 11: 4 rows x 3 cols (with one extra)我想出了一个解决方案,使用平方根,它给了我一个非常接近的解决方案:var cols = Math.ceil(Math.sqrt(length)); var rows = Math.ceil(length / cols);可以有额外的单元格(比如素数),但我更喜欢尽可能地减少它们。这种方法的问题是,当可能有更优化的解决方案时,我得到的是空单元格:- Length: 8: returns 3 x 3, but 2 x 4 has 0 remainders - Length: 10: returns 4 x 3, but 5 x 2 has 0 remainders - Length: 15: returns 4 x 4, but 5 x 3 has 0 remainders有没有其他方法可以优化我的网格以获得尽可能少的额外单元格?我觉得我的尝试不是最佳的。
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

对于偶数 length m,我们可以很容易地说:


cols = m / 2

rows = 2

对于奇数长度m,我们需要分解m。幸运的是,只需要一个非平凡的(1 或m)因子就足够了。通过以下算法:


for(var i = 3; i * i < m; i += 2){

    if(m % i == 0)

        return i;

}

return -1;

如果结果是-1,它将是质数,因此,最终结果将是:


cols = (m+1)/2

rows = 2

否则,如果我们调用 factor k,结果将是:


cols = m / k

row = k

您可以在以下内容中找到最终结果:


function factor(m){

   // if m is even

   if(m % 2 == 0)

       return [2, m/2]   

   for(var i = 3; i * i < m; i += 2){

        // m is odd and not prim

        if(m % i == 0)

            return [i, m/i];

   }

   // m is odd prime

   return [2, (m+1)/2];


console.log(factor(8));

console.log(factor(10));

console.log(factor(11));

console.log(factor(15));

此功能的结果已优化(根据您的定义)。因为余数对于非素数为零,而1对于素数则为零。



查看完整回答
反对 回复 2023-03-10
?
繁华开满天机

TA贡献1816条经验 获得超4个赞

假设这些数字永远不会大到天文数字,您可以只检查每个数字从平方根开始的拟合程度,并在给定评估函数的情况下跟踪最佳数字,该评估函数既考虑了余数又考虑了方差。所以像:


function optimizeRectangle(N) {

  let bestRectangle = null;

  let best_evaluation = Infinity;


  let start_row = Math.floor(Math.sqrt(N));

  // Maximum aspect ratio of 3:1

  for (let offset = 0; offset < start_row / 2; offset++) {

    let row = start_row - offset;

    let col = Math.ceil(N/row);

    let remainder = row * col - N;

    let evaluation = remainder + offset; // or some other function of remainder and offset

    if (evaluation < best_evaluation) {

      best_evaluation = evaluation;

      best_rectangle = [row, col];

    }

  }

  return best_rectangle;

}

请注意,我实际上并没有运行这段代码,所以如果没有运行,请将其视为伪代码。


查看完整回答
反对 回复 2023-03-10
  • 2 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信