#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 выдает следующий пример вывода:
Редактировать: вот модифицированный алгоритм 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.