简体   繁体   English

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

[英]Finding optimal rows & columns for grid of N cells

I'm trying to create a grid that has to have enough rows and columns to fit length number of cells.我正在尝试创建一个网格,该网格必须具有足够的行和列以适应单元格的length数量。 Here are some examples:这里有些例子:

- 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)

I've come up with a solution, using square root, that gives me a pretty close solution:我想出了一个使用平方根的解决方案,这给了我一个非常接近的解决方案:

var cols = Math.ceil(Math.sqrt(length));
var rows = Math.ceil(length / cols);

It's okay to have extra cells (like with prime numbers), but I prefer to minimize them whenever possible.可以有额外的单元格(如质数),但我更喜欢尽可能减少它们。 The problem with this approach is that I get empty cells when there could be a more optimal solution:这种方法的问题在于,当可能有更优化的解决方案时,我会得到空单元格:

- 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

Is there an alternative way to optimize my grid to get the least number of extra cells possible?有没有其他方法可以优化我的网格以获得尽可能少的额外单元格? I feel like my attempt isn't optimal.我觉得我的尝试不是最佳的。

For even length m , we can easily say:对于偶数m ,我们可以很容易地说:

cols = m / 2
rows = 2

For odd length m , we need to factorize m .对于奇数长度m ,我们需要分解m Fortunately, just a non-trivial (1 or m ) factor is enough.幸运的是,一个不平凡的(1 或m )因子就足够了。 by the following algorihtm:通过以下算法:

for(var i = 3; i * i < m; i += 2){
    if(m % i == 0)
        return i;
}
return -1;

If the result was -1 , it will be prime number, hence, the final reuslt will be:如果结果是-1 ,它将是素数,因此,最终的结果将是:

cols = (m+1)/2
rows = 2

Else, if we call the factor k , the result will be:否则,如果我们调用因子k ,结果将是:

cols = m / k
row = k

You can find the final result in the following:您可以在以下内容中找到最终结果:

 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));

This result of this function is optimized (in terms of your definition).此函数的此结果已优化(根据您的定义)。 Because the remainder is zero for not prime numbers and is 1 for primes.因为对于非素数,余数为零,对于素数,余数为1

Assuming these numbers never get astronomically large you could just check how good of a fit each number is starting from the square root and keep track of the best one given an evaluation function that accounts for both the remainder and lack of squareness.假设这些数字永远不会像天文数字一样大,您可以从平方根开始检查每个数字的拟合程度,并在给定评估函数的情况下跟踪最佳数字,该评估函数考虑了余数和缺乏平方。 So something like:所以像:

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;
}

Note that I didn't actually run this code, so treat it as pseudo code if it doesn't.请注意,我实际上并没有运行此代码,因此如果没有运行,请将其视为伪代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM