Как случайным образом заполнить пробел в одном измерении?

#random

#Случайный

Вопрос:

Я хотел бы знать, как я могу случайным образом заполнить пробел заданным количеством элементов и целевым размером, например, учитывая количество столбцов = 15 и ширину целевого размера = 320, как я могу случайным образом распределить ширину столбцов, чтобы заполнить пробел? как показано на рисунке ниже, если возможно, подойдет любой псевдокод или алгоритм

введите описание изображения здесь

Комментарии:

1. может быть любым, скажем, javascript

2. что означает width = 320? это значение изображения? если да, то что вы подразумеваете под заполнением?

3. Ширина области, в которой я хочу случайным образом распределить столбцы, я отредактирую вопрос, чтобы прояснить это

Ответ №1:

Один из способов разделить ваши 320 пикселей на 15 случайных «столбцов» — сделать это равномерно, т. Е. Ширина каждого столбца соответствует одинаковому распределению.

Для этого вам действительно нужно равномерное распределение по симплексу. Первый способ достижения — это тот, который описан yi_H, и, вероятно, это правильный путь:

  • Сгенерируйте 14 однородных целых чисел от 0 до 320.
  • Продолжайте восстанавливать любое уже выбранное число, чтобы в итоге получилось 14 разных чисел
  • Сортируйте их
  • Границы ваших столбцов задаются двумя последовательными случайными числами.

Если у вас есть требование к минимальной ширине (например, 1 для непустых столбцов), удалите его 15 раз из ваших 320 пикселей, сгенерируйте числа в новом диапазоне и внесите необходимые корректировки.

Второй способ достижения однородной точки на симплексе немного сложнее и не очень хорошо подходит для дискретных настроек, таких как пиксели, но в любом случае здесь он вкратце:

  • Сгенерируйте 15 экспоненциальных случайных величин с одинаковым параметром формы (например, 1)
  • Разделите каждое число на общее, чтобы каждое было в [0,1]
  • Измените масштаб этих чисел, умножив их на 320 и округлив. Это ваши ширины столбцов

Это не так хорошо, как первый способ, поскольку при округлении вы можете получить общее количество больше или меньше 320, и у вас могут быть столбцы с шириной 0… Единственное преимущество заключается в том, что вам не нужно выполнять какую-либо сортировку (но вам нужно вычислять логарифмы… итак, в целом, первый способ — это путь).

Я должен добавить, что если вы не обязательно хотите равномерного случайного заполнения, то в вашем распоряжении гораздо больше алгоритмов.

Редактировать: Вот быстрая реализация первого алгоритма в Mathematica. Обратите внимание, что для того, чтобы избежать генерации точек, пока все они не будут разными, вы можете просто считать, что пустой столбец имеет ширину 1, а затем минимальная ширина 2 даст вам столбцы с непустым внутренним пространством:

 min = 2;
total = 320;
height = 50;
n = 15;
x = Sort[RandomInteger[total - n*min - 1, n - 1]]   Range[n - 1]*min
Graphics[{Rectangle[{-2, 0}, {0, height}], (*left margin*)
  Rectangle[{#, 0}, {#   1, height}] amp; /@ x, (*columns borders*)
  Rectangle[{total, 0}, {total   2, height}]}, (*right margin*)
 PlotRange -> {{-2, total   2}, {0, height}}, 
 ImageSize -> {total   4, height}]
  

with выдает следующий пример вывода:

вывод с 15 столбцами, минимальная ширина 2

Редактировать: вот модифицированный алгоритм javascript (будьте осторожны, я никогда раньше не писал Javascript, поэтому могут быть некоторые ошибки плохой стиль):

 function sortNumber(a,b)
{
   return a - b;
}

function draw() {
   var canvas = document.getElementById( "myCanvas" );

   var numberOfStrips = 15;
   var initPosX = 10;
   var initPosY = 10;
   var width = 320;
   var height = 240;
   var minColWidth = 2;
   var reducedWidth = width - numberOfStrips * minColWidth;
   var separators = new Array();

   for ( var n = 0; n < numberOfStrips - 1; n   ) {
      separators[n] = Math.floor(Math.random() * reducedWidth);
   }
   separators.sort(sortNumber);
   for ( var n = 0; n < numberOfStrips - 1; n   ) {
      separators[n]  = (n 1) * minColWidth;
   }
   if ( canvas.getContext ) {
      var ctx = canvas.getContext( "2d" );

      // Draw lines
      ctx.lineWidth = 1;
      ctx.strokeStyle = "rgb( 120, 120, 120 )";
      for ( var n = 0; n < numberOfStrips - 1; n   ) {
         var newPosX = separators[n];
         ctx.moveTo( initPosX   newPosX, initPosY );
         ctx.lineTo( initPosX   newPosX, initPosY   height );
      }
      ctx.stroke();

      // Draw enclosing rectangle
      ctx.lineWidth = 4;
      ctx.strokeStyle = "rgb( 0, 0, 0 )";
      ctx.strokeRect( initPosX, initPosY, width, height );
   }
}
  

Кроме того, обратите внимание, что minColWidth это не должно быть больше определенного значения ( reducedWidth не должно быть отрицательным …), Но оно не проверяется в алгоритме. Как указывалось ранее, используйте значение 0, если вы не возражаете против двух строк друг над другом, значение 1, если вы не возражаете против двух строк рядом друг с другом, и значение 2 или более, если вам нужны только непустые столбцы.

Комментарии:

1. @ FelixCQ — сможете ли вы перевести этот код на что-то вроде Javascript? Спасибо

2. @Ricardo — если вы дадите что-то для начала, то есть код, который рисует прямоугольник и несколько строк, я должен быть в состоянии.

3. Круто, если вы посмотрите исходный код здесь, у меня есть очень простой код javascript dl.dropbox.com/u/26115638/UniformRandomDist/index.html

4. Потрясающе, что это доставляет удовольствие и мне легче понять, я понял это при первом чтении, большое, большое спасибо за вашу помощь

5. @Mr.Wizard Нет, не совсем, поскольку, если вы сделаете это, вы гарантируете, что ширина первого столбца будет не менее min пикселей. Вам действительно нужно удалить n ширину, умноженную на min total ширину, использовать обычный алгоритм, а затем добавить обратно min ко всем столбцам.

Ответ №2:

Создайте 14 уникальных чисел в диапазоне (0,320). Это будет позиция x столбцов.

Создайте случайное число, сравните с предыдущими, сохраните его.

Если последовательные строки не разрешены, также убедитесь, что они не равны ни одному предыдущему -1.