Как говорится в моем названии, я хочу «вырастить» скопления клеток из семян в растре. Мой базовый растр полон 1 и 0, 1 указывает на сушу, а 0 - на море / NA. Из числа 1 я хочу выбрать 60 случайных пикселей / ячеек в качестве своих семян, а затем случайным образом вырастить связную группу заранее определенного числа нет. пикселей / ячеек предел от этого семени. Я слышал, что эту технику можно назвать «спред-красителем», но мне не очень-то повезло. Начальная ячейка будет установлена в значение 2, а затем следующая ячейка, выбранная из окружающих 1, будет также преобразована в 2. 2 тогда недоступны для преобразования в будущем.
Этот поток немного помогает, поскольку я также хотел бы сделать это в R, так как я знаком с чтением и манипулированием данными ГИС в R. Однако мне требуется набор правил для случайного выбора пикселей, окружающих существующий скопление ,
Если кто-то сделал эту более базовую форму клеточных автоматов в условиях ГИС, я был бы признателен за любые советы / рекомендации.
Пример:
У меня цель 250 клеток. Я случайным образом выбираю одну ячейку, которая имеет значение 1. Это превращается в значение 2. Затем один из соседей исходной ячейки = 1 превращается в 2. Затем один из соседей любой из ячеек со значением 2 выбирается и превращается в 2. Это будет продолжаться до тех пор, пока не будет достигнута непрерывная форма, насчитывающая 250 ячеек.
Изменить: дополнительные вопросы
Основываясь на отличном ответе Уубер, у меня есть несколько вопросов о коде:
- Как я могу распределить значения выращенных клеток только на «2», а не на значения переменных, которые представляют порядок, в котором они были созданы?
- Мне нужно создать 60 скоплений клеток в моей области 1. Я разработал способы выбора случайных стартовых позиций, но изо всех сил стараюсь заставить все это работать в цикле, используя
expand
функцию, которую вы любезно написали. Можете ли вы предложить способ создания 60 скоплений, которые не конфликтуют друг с другом и содержатся в одной и той же конечной матрице?
Изменить: дальнейшее объяснение проблемы
Каждый скопление клеток будет представлять собой защищенную область определенного размера, например, 250 клеток. Каждая область должна начинаться и расти в ячейки со значением 1, поскольку это представляет землю и избегать ячеек со значением 0, поскольку это представляет море. Мне нужно повторить эту 1000 раз с 60 защищенными областями в каждой итерации, чтобы создать нулевую модель, показывающую, какие распределения этих областей будут случайными. По этой причине общее количество ячеек во всех 60 областях должно быть одинаковым в каждой из 1000 итераций, чтобы они были сопоставимы. Следовательно, это нормально, если области касаются, но если есть столкновение, то в идеале сгусток будет расти в другом доступном направлении, пока не будет достигнута цель 250.
Как только каждая из этих 1000 сетей охраняемых районов будет создана, они будут использоваться в качестве маски против других растровых данных, таких как меры по биоразнообразию, чтобы увидеть (а) пересекают ли они ареалы определенных видов и (б) какой процент конкретных видов охватывает эти случайные сети покрытия охраняемых территорий.
Спасибо @whuber за вашу помощь, я не ожидаю, что вы потратите больше времени, помогая мне, но подумал, что постараюсь прояснить ситуацию, как вы просили.
Ответы:
Я предложу
R
решение, которое написано немного неR
так, чтобы проиллюстрировать, как оно может подходить на других платформах.Проблема
R
(как и некоторых других платформ, особенно тех, которые предпочитают стиль функционального программирования) заключается в том, что постоянное обновление большого массива может быть очень дорогим. Вместо этого этот алгоритм поддерживает свою собственную структуру частных данных, в которой (а) перечислены все ячейки, которые были заполнены до сих пор, и (б) все ячейки, которые доступны для выбора (по периметру заполненных ячеек) перечислены. Хотя манипулирование этой структурой данных менее эффективно, чем прямое индексирование в массив, при сохранении измененных данных небольшого размера это, вероятно, займет гораздо меньше времени вычислений. (Также не было предпринято никаких усилий для его оптимизацииR
. Предварительное распределение векторов состояния должно сэкономить некоторое время выполнения, если вы предпочитаете продолжать работать внутриR
.)Код комментируется и должен быть простым для чтения. Чтобы сделать алгоритм максимально полным, он не использует никаких дополнений, кроме как в конце, чтобы отобразить результат. Единственная сложность заключается в том, что для эффективности и простоты он предпочитает индексировать в двумерные сетки, используя одномерные индексы. Преобразование происходит в
neighbors
функции, которая нуждается в двумерном индексировании, чтобы выяснить, какими могут быть доступные соседи ячейки, а затем преобразует их в одномерный индекс. Это преобразование является стандартным, поэтому я не буду комментировать его далее, за исключением того, что хочу указать, что на других платформах ГИС вы можете изменить роли индексов столбцов и строк. (InR
, индексы строк изменяются раньше, чем индексы столбцов.)Чтобы проиллюстрировать, этот код берет сетку,
x
представляющую сушу и речную особенность недоступных точек, начинается в определенном месте (5, 21) в этой сетке (около нижнего изгиба реки) и расширяет ее случайным образом, чтобы покрыть 250 точек , Общее время составляет 0,03 секунды. (Когда размер массива увеличивается в 10 000–3 000 строк на 5000 столбцов, время увеличивается только до 0,09 секунды - в 3 раза или более - демонстрируя масштабируемость этого алгоритма.) Вместо просто выводя сетку из 0, 1 и 2, она выводит последовательность, с которой были выделены новые ячейки. На рисунке самые ранние ячейки зеленого цвета, переходящие из золота в цвета лосося.Должно быть очевидно, что используется восьмиточечная окрестность каждой ячейки. Для других окрестностей просто измените
nbrhood
значение в началеexpand
: это список смещений индекса относительно любой данной ячейки. Например, район "D4" может быть указан какmatrix(c(-1,0, 1,0, 0,-1, 0,1), nrow=2)
.Также очевидно, что у этого метода распространения есть свои проблемы: он оставляет дыры позади. Если это не то, что было задумано, существуют различные способы решения этой проблемы. Например, сохраняйте доступные ячейки в очереди, чтобы самые ранние найденные ячейки были также заполнены самыми ранними. Некоторая рандомизация все еще может быть применена, но доступные ячейки больше не будут выбираться с одинаковыми (равными) вероятностями. Другим, более сложным способом будет выбор доступных ячеек с вероятностями, которые зависят от того, сколько у них заполненных соседей. Как только клетка окажется в окружении, вы можете сделать так, чтобы ее выбор был настолько велик, что несколько отверстий останутся незаполненными.
В заключение я прокомментирую, что это не совсем клеточный автомат (CA), который не будет обрабатывать ячейку за ячейкой, а вместо этого будет обновлять целые полосы ячеек в каждом поколении. Разница тонкая: с CA вероятности выбора для ячеек не будут одинаковыми.
С небольшими изменениями мы можем зацикливаться,
expand
чтобы создать несколько кластеров. Желательно дифференцировать кластеры по идентификатору, который здесь будет работать 2, 3, ... и т. Д.Во-первых, измените
expand
на return (a)NA
в первой строке, если есть ошибка, и (b) значения вindices
матрицеy
. (Не тратьте время на создание новой матрицыy
при каждом вызове.) После внесения этого изменения цикл становится легким: выберите случайный старт, попробуйте расширить его, накапливайте кластерные индексы,indices
если все прошло успешно, и повторяйте до тех пор, пока не закончите. Ключевой частью цикла является ограничение количества итераций в случае, если невозможно найти много смежных кластеров: это делается с помощьюcount.max
.Вот пример, где 60 кластерных центров выбираются случайным образом равномерно.
Вот результат при применении к сетке 310 на 500 (сделан достаточно малым и грубым, чтобы кластеры были заметны). Выполнение занимает две секунды; на сетке 3100 на 5000 (в 100 раз больше) это занимает больше времени (24 секунды), но время масштабируется достаточно хорошо. (На других платформах, таких как C ++, время вряд ли должно зависеть от размера сетки.)
источник
y[indices] <- 1:length(indices)
наy[indices] <- 2
. Ответ на # 2 почти так же прост: просто цикл.size.clusters
. Как я могу убедиться, что сгусток вырастет до нужного размера, поскольку в настоящий момент я предполагаю, что он пытается превратиться в существующий сгусток, терпит неудачу, но все же регистрируется как успешное расширение. Затем я также собираюсь повторить производство 60 сгустков 1000 раз, создавая набор данных со средним нулевым стилем модели. Будет ли случайное расположение изменяться каждый раз вfor
цикле?Даже не выполнив свою операцию и не пожалев времени на игру, я могу добавить только две ссылки в ваш список:
Найти значение ближайшей растровой ячейки на основе векторной точки (первый ответ (с 4 голосами) меня заинтриговал).
Кроме того: поможет ли Gridspread от Hawth ?
источник