1 সেল / পিক্সেলের বীজ থেকে একটি রাস্টারগুলিতে এলোমেলোভাবে আকারের কক্ষগুলির ক্লাম্প তৈরি করছেন?


11

আমার শিরোনাম অনুসারে, আমি একজন রাস্টারের মধ্যে বীজ থেকে কোষগুলির ঝাঁক "বৃদ্ধি" করতে চাই। আমার বেস রাস্টারটি 1 এবং 0 এর পূর্ণ, 1 এর জমি এবং 0 এর সমুদ্র / এনএ অঞ্চলগুলিতে পূর্ণ। 1 এর দশক থেকে আমি 60 টি র্যান্ডম পিক্সেল / কোষগুলিকে আমার বীজ হিসাবে নির্বাচন করতে চাই এবং তারপরে এলোমেলোভাবে পূর্বনির্ধারিত নংয়ের একটি সংযুক্ত ক্লাম্প বাড়িয়ে তুলতে চাই। পিক্সেল / কোষের বীজ থেকে সীমাবদ্ধ। আমি শুনেছি যে কৌশলটি 'স্প্রেড ডাই' হিসাবে উল্লেখ করা যেতে পারে তবে এটির জন্য খুব ভাগ্য অর্জন করতে পারেনি। বীজ ঘরটি 2 টির মানে পরিণত হবে এবং তারপরে 1 এর কাছাকাছি থেকে নির্বাচিত পরবর্তী ঘরটিও 2 তে রূপান্তরিত হবে। 2 এর পরে ভবিষ্যতে রূপান্তর করার জন্য অনুপলব্ধ।

এই থ্রেডটি কিছুটা সহায়তা করে, কারণ আমি আর এও করতে ইচ্ছুক কারণ আমি আর জি-র জিআইএস তথ্য পড়ার এবং এগুলি পরিচালনা করার সাথে পরিচিত However তবে, আমার যা প্রয়োজন তা এলোমেলোভাবে একটি বিদ্যমান ক্লাম্পের আশেপাশের পিক্সেল নির্বাচন করার নিয়মের একটি সেট is ।

যদি কোনও জিআইএস সেটিং-এ সেলুলার অটোমেটার এই আরও বেসিক ফর্মটি করে থাকে তবে আমি কোনও পরামর্শ / দিকনির্দেশনাটির প্রশংসা করব।

উদাহরণ:

আমার 250 টি সেল রয়েছে। আমি এলোমেলোভাবে একটি কক্ষ নির্বাচন করি যার মান 1 রয়েছে। এটি 2 টির মানতে পরিণত হয় Then তারপরে, বীজ ঘরের প্রতিবেশীদের একজনকে = 1 টি 2 তে পরিণত করা হয় Then তারপরে, কোষগুলির মধ্যে প্রতিবেশীদের মধ্যে একটি ২ টি মান সহ নির্বাচন করা হয় এবং এটি ২ এ পরিণত হয় 250 এটি 250 অবধি অবধি অবিচ্ছিন্ন আকার ধারণ করে অবধি চলতে থাকবে।

সম্পাদনা করুন: আরও প্রশ্ন

Whuber এর দুর্দান্ত উত্তরের উপর ভিত্তি করে, কোড সম্পর্কে আমার কয়েকটি প্রশ্ন রয়েছে:

  1. বর্ধিত কক্ষগুলির মানগুলি কীভাবে পরিবর্তিত মানগুলির পরিবর্তে সেগুলি তৈরি করা হয়েছিল তার প্রতিনিধিত্ব না করে কেবল একটি '2' এ কীভাবে বরাদ্দ করব?
  2. আমার নিজের অঞ্চলের 1'র মধ্যে 60 টি ক্লাম্প সেল তৈরি করতে হবে। আমি এলোমেলোভাবে শুরু করার অবস্থান বাছাই করার উপায়গুলি তৈরি করেছি তবে expandআপনি যে ফাংশনটি দয়া করে লিখেছেন তা ব্যবহার করে এটি লুপের মধ্যে সমস্ত কাজ করার জন্য সংগ্রাম করে যাচ্ছি । একে অপরের সাথে সংঘর্ষ না হয় এবং একই ফাইনাল ম্যাট্রিক্সের মধ্যে অন্তর্ভুক্ত 60 টি ক্লাম্প তৈরির জন্য কি আপনি কোনও উপায়ের পরামর্শ দিতে পারেন?

সম্পাদনা করুন: সমস্যার আরও ব্যাখ্যা

প্রতিটি ক্লাম্প কোষগুলি একটি সংজ্ঞায়িত আকারের 250 টি কোষের সুরক্ষিত অঞ্চলকে উপস্থাপন করে। প্রতিটি অঞ্চল 1 টির মান সহ কোষে শুরু এবং বর্ধমান হওয়া উচিত কারণ এটি ভূমির প্রতিনিধিত্ব করে এবং 0 এর মান সহ কোষগুলি এড়ায়, কারণ এটি সমুদ্রকে প্রতিনিধিত্ব করে। শূন্য মডেল তৈরি করতে প্রতিটি পুনরাবৃত্তির 60 টি সুরক্ষিত অঞ্চল সহ আমাকে 1000 বার এটি পুনরাবৃত্তি করা দরকার, দেখানো হচ্ছে যে এই জায়গাগুলির ভাগ কীভাবে ঘটবে তা যথাযথভাবে হবে। এই কারণে, সমস্ত 60 টি অঞ্চল জুড়ে সমস্ত কক্ষের মোট গণনা 1000 পুনরাবৃত্তির প্রত্যেকটিতে অভিন্ন হওয়া দরকার যাতে তারা তুলনীয় হয়। সুতরাং, যদি অঞ্চলগুলি স্পর্শ করে তবে এটি ঠিক আছে, তবে যদি কোনও সংঘর্ষ হয়, তবে 250 বা লক্ষ্যমাত্রা না পৌঁছা পর্যন্ত আদর্শভাবে এই ঝাঁকুনি অন্য উপলব্ধ দিকে বাড়বে।

এই 1000 টি সুরক্ষিত অঞ্চল নেটওয়ার্কগুলির প্রত্যেকটি তৈরি হয়ে গেলে, তারা অন্যান্য রাস্টার ডেটা যেমন জৈববৈচিত্রের ব্যবস্থাগুলির বিরুদ্ধে মাস্ক হিসাবে ব্যবহৃত হবে তা দেখার জন্য (ক) তারা নির্দিষ্ট প্রজাতির রেঞ্জকে ছেদ করে কিনা এবং (খ) নির্দিষ্ট প্রজাতির কোনটি% এই এলোমেলো নেটওয়ার্ককে রেঞ্জ করে? সুরক্ষিত অঞ্চল কভার।

আপনার সাহায্যের জন্য এখনও অবধি @ হুবুহরকে ধন্যবাদ, আপনি আমাকে সাহায্য করার জন্য আরও বেশি সময় ব্যয় করবেন বলে আমি আশা করি না, তবে ভেবেছিলাম আপনার অনুরোধ অনুসারে আমি চেষ্টা করব এবং আমার পরিস্থিতি পরিষ্কার করব।


আর ছাড়াও এই বিশ্লেষণের জন্য আপনি কোন অন্যান্য প্রোগ্রামিং ভাষা / সফ্টওয়্যার ব্যবহার করতে আগ্রহী?
হারুন

আমি আরকিজিআইএস বা কিউজিআইএস ব্যবহার করতে পেরে খুশি হব। দুর্ভাগ্যক্রমে আমি পাইথনের সাথে তেমন পরিচিত নই। ব্যাশ টার্মিনালের মাধ্যমে জিডিএলও একটি সম্ভাবনা।
জেপিডি

উত্তর:


12

অন্যান্য প্ল্যাটফর্মগুলিতে কীভাবে এটি যোগাযোগ করা যেতে পারে তা চিত্রিত করার জন্য আমি Rকিছুটা উপায়হীনভাবে কোডেড এমন একটি প্রস্তাব দেব R

R(পাশাপাশি কিছু অন্যান্য প্ল্যাটফর্ম, বিশেষত যারা কার্যকরী প্রোগ্রামিং শৈলীর পক্ষে রয়েছে) উদ্বেগটি হ'ল ক্রমাগত একটি বড় অ্যারে আপডেট করা খুব ব্যয়বহুল হতে পারে। পরিবর্তে, তারপরে, এই অ্যালগরিদম তার নিজস্ব ব্যক্তিগত ডেটা কাঠামো বজায় রাখে যার মধ্যে (ক) এ পর্যন্ত পূরণ করা সমস্ত কক্ষ তালিকাভুক্ত করা হয়েছে এবং (খ) সমস্ত নির্বাচিত ঘর নির্বাচন করা হবে (ভরাট কোষের ঘেরের চারপাশে) তালিকাভুক্ত. যদিও এই ডেটা কাঠামোটি হেরফের করা সরাসরি অ্যারেতে ইনডেক্সিংয়ের চেয়ে কম দক্ষ, পরিবর্তিত ডেটাটিকে একটি ছোট আকারে রেখে, সম্ভবত এটি কম গণনার সময় নেয়। (এটির জন্যও অনুকূলিতকরণের জন্য কোনও প্রচেষ্টা করা হয়নি R। রাজ্যের ভেক্টরদের প্রাক-বরাদ্দের কিছু সময় কার্যকর করার সময় সাশ্রয় করা উচিত, যদি আপনি কাজ চালিয়ে যেতে চান তবে R।)

কোডটি মন্তব্য করা হয়েছে এবং পড়ার জন্য সোজা হওয়া উচিত। যতটা সম্ভব অ্যালগরিদমকে সম্পূর্ণ করতে, ফলাফলের প্লট করা ছাড়া এটি কোনও অ্যাড-অন ব্যবহার করে না। একমাত্র জটিল অংশটি দক্ষতা এবং সরলতার জন্য এটি 1 ডি সূচকগুলি ব্যবহার করে 2D গ্রিডে সূচক পছন্দ করে। neighborsকোনও কক্ষের অ্যাক্সেসযোগ্য প্রতিবেশী কী হতে পারে তা নির্ধারণ করার জন্য ফাংশনে একটি রূপান্তর ঘটে যা 2D সূচক প্রয়োজন এবং তারপরে তাদের 1D সূচীতে রূপান্তর করে। এই রূপান্তরটি আদর্শ, সুতরাং অন্যান্য জিআইএস প্ল্যাটফর্মে আপনি কলাম এবং সারি সূচকগুলির ভূমিকাগুলি বিপরীত করতে চাইতে পারেন তা উল্লেখ করা ছাড়া আমি এ বিষয়ে আরও মন্তব্য করব না। ( Rকলাম সূচকগুলি করার আগে সারি সূচী পরিবর্তন হয়))

উদাহরণস্বরূপ, এই কোডটি গ্রিডের xপ্রতিনিধিত্বকারী একটি গ্রিড এবং অ্যাক্সেসযোগ্য পয়েন্টগুলির নদীর মতো বৈশিষ্ট্য গ্রহণ করে, সেই গ্রিডের একটি নির্দিষ্ট স্থানে (5, 21) শুরু হয় (নদীর নীচের বাঁকের নিকটে) এবং এটিকে এলোমেলোভাবে প্রসারিত করে 250 পয়েন্টগুলি coverেকে রাখে । মোট সময়সীমা 0.03 সেকেন্ড। (যখন অ্যারের আকারটি 10,000 থেকে 3000 সারিগুলির ফ্যাক্টর দ্বারা 5000 কলাম দ্বারা বাড়ানো হয়, সময়টি কেবল 0.09 সেকেন্ডে চলে যায় - কেবল 3 বা এর একটি উপাদান - এই অ্যালগরিদমের স্কেলিবিলিটি প্রদর্শন করে) কেবল 0, 1 এবং 2 এর গ্রিড আউটপুট করে, এটি নতুন কক্ষগুলি বরাদ্দ করা হয়েছিল এমন ক্রমটি আউটপুট করে। চিত্রটিতে প্রাথমিকতম কোষগুলি সবুজ, সোনার মাধ্যমে স্যামন রঙগুলিতে স্নাতক।

মানচিত্র

এটা স্পষ্ট হওয়া উচিত যে প্রতিটি কক্ষের একটি আট-পয়েন্ট পাড়া ব্যবহার করা হচ্ছে। অন্যান্য পাড়াগুলির জন্য কেবল nbrhoodশুরুর কাছাকাছি মানটি সংশোধন করুন expand: এটি কোনও প্রদত্ত ঘরের তুলনায় সূচক অফসেটের তালিকা of উদাহরণস্বরূপ, "D4" পাড়া হিসাবে নির্দিষ্ট করা যেতে পারে matrix(c(-1,0, 1,0, 0,-1, 0,1), nrow=2)

এটি স্পষ্টও যে স্প্রেডের এই পদ্ধতির সমস্যা রয়েছে: এটি পিছনে গর্ত ফেলে। যদি তা না হয় তবে এই সমস্যাটি সমাধানের বিভিন্ন উপায় রয়েছে। উদাহরণস্বরূপ, উপলভ্য কক্ষগুলিকে একটি সারিতে রাখুন যাতে পাওয়া প্রাচীনতম কক্ষগুলিও পূর্ণতম পূরণ করা হয়। কিছু র্যান্ডমাইজেশন এখনও প্রয়োগ করা যেতে পারে, তবে উপলব্ধ কক্ষগুলি আর অভিন্ন (সমান) সম্ভাবনার সাথে বেছে নেওয়া হবে না। আর একটি, আরও জটিল উপায় হ'ল সম্ভাব্যতার সাথে উপলব্ধ কক্ষগুলি নির্বাচন করা যা তাদের কতটা ভরা প্রতিবেশীর উপর নির্ভর করে। একবার কোনও ঘরের চারপাশে পরিণত হওয়ার পরে, আপনি এর নির্বাচনের সুযোগটি এত বেশি করে তুলতে পারেন যে কয়েকটি ছিদ্র পূরণ না করে।

আমি মন্তব্য করে শেষ করব যে এটি কোনও সেলুলার অটোমেটন (সিএ) নয়, যা সেল দ্বারা কোষটি এগিয়ে যায় না, পরিবর্তে প্রতিটি প্রজন্মের কোষগুলির পুরো সোয়েট আপডেট করবে। পার্থক্যটি সূক্ষ্ম: সিএ সহ, কোষগুলির জন্য নির্বাচনের সম্ভাবনাগুলি অভিন্ন হবে না।

#
# Expand a patch randomly within indicator array `x` (1=unoccupied) by
# `n.size` cells beginning at index `start`.
#
expand <- function(x, n.size, start) {
  if (x[start] != 1) stop("Attempting to begin on an unoccupied cell")
  n.rows <- dim(x)[1]
  n.cols <- dim(x)[2]
  nbrhood <- matrix(c(-1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1), nrow=2)
  #
  # Adjoin one more random cell and update `state`, which records
  # (1) the immediately available cells and (2) already occupied cells.
  #
  grow <- function(state) {
    #
    # Find all available neighbors that lie within the extent of `x` and
    # are unoccupied.
    #
    neighbors <- function(i) {
      n <- c((i-1)%%n.rows+1, floor((i-1)/n.rows+1)) + nbrhood
      n <- n[, n[1,] >= 1 & n[2,] >= 1 & n[1,] <= n.rows & n[2,] <= n.cols, 
             drop=FALSE]             # Remain inside the extent of `x`.
      n <- n[1,] + (n[2,]-1)*n.rows  # Convert to *vector* indexes into `x`.
      n <- n[x[n]==1]                # Stick to valid cells in `x`.
      n <- setdiff(n, state$occupied)# Remove any occupied cells.
      return (n)
    }
    #
    # Select one available cell uniformly at random.
    # Return an updated state.
    #
    j <- ceiling(runif(1) * length(state$available))
    i <- state$available[j]
    return(list(index=i,
                available = union(state$available[-j], neighbors(i)),
                occupied = c(state$occupied, i)))
  }
  #
  # Initialize the state.
  # (If `start` is missing, choose a value at random.)
  #
  if(missing(start)) {
    indexes <- 1:(n.rows * n.cols)
    indexes <- indexes[x[indexes]==1]
    start <- sample(indexes, 1)
  }
  if(length(start)==2) start <- start[1] + (start[2]-1)*n.rows
  state <- list(available=start, occupied=c())
  #
  # Grow for as long as possible and as long as needed.
  #
  i <- 1
  indices <- c(NA, n.size)
  while(length(state$available) > 0 && i <= n.size) {
    state <- grow(state)
    indices[i] <- state$index
    i <- i+1
  }
  #
  # Return a grid of generation numbers from 1, 2, ... through n.size.
  #
  indices <- indices[!is.na(indices)]
  y <- matrix(NA, n.rows, n.cols)
  y[indices] <- 1:length(indices)
  return(y)
}
#
# Create an interesting grid `x`.
#
n.rows <- 3000
n.cols <- 5000
x <- matrix(1, n.rows, n.cols)
ij <- sapply(1:n.cols, function(i) 
      c(ceiling(n.rows * 0.5 * (1 + exp(-0.5*i/n.cols) * sin(8*i/n.cols))), i))
x[t(ij)] <- 0; x[t(ij - c(1,0))] <- 0; x[t(ij + c(1,0))] <- 0
#
# Expand around a specified location in a random but reproducible way.
#
set.seed(17)
system.time(y <- expand(x, 250, matrix(c(5, 21), 1)))
#
# Plot `y` over `x`.
#
library(raster)
plot(raster(x[n.rows:1,], xmx=n.cols, ymx=n.rows), col=c("#2020a0", "#f0f0f0"))
plot(raster(y[n.rows:1,] , xmx=n.cols, ymx=n.rows), 
     col=terrain.colors(255), alpha=.8, add=TRUE)

সামান্য পরিবর্তন সহ আমরা expandএকাধিক ক্লাস্টার তৈরি করতে লুপ করতে পারি । এটি সনাক্তকারী দ্বারা ক্লাস্টারগুলিকে আলাদা করার পরামর্শ দেওয়া হচ্ছে, যা এখানে 2, 3, ... ইত্যাদি চলবে

প্রথমে, ত্রুটি থাকলে প্রথম লাইনে expand(ক) ফিরে আসার পরিবর্তন করুন NAএবং (খ) indicesম্যাট্রিক্সের পরিবর্তে মানগুলি y। ( yপ্রতিটি কলের সাথে একটি নতুন ম্যাট্রিক্স তৈরি করতে সময় নষ্ট করবেন না )) এই পরিবর্তনটি করা, লুপ করা সহজ: একটি এলোমেলো শুরু চয়ন করুন, এর চারপাশে প্রসারিত করার চেষ্টা করুন, indicesসফল হলে ক্লাস্টার সূচকগুলি সংগ্রহ করুন এবং শেষ না হওয়া পর্যন্ত পুনরাবৃত্তি করুন। লুপের মূল অংশটি হ'ল বহুসংখ্যক ক্লাস্টার সন্ধান না করা হলে পুনরাবৃত্তির সংখ্যা সীমাবদ্ধ করা: এটি দিয়ে সম্পন্ন করা হয়েছে count.max

এখানে একটি উদাহরণ যেখানে 60 ক্লাস্টার কেন্দ্রগুলি এলোমেলোভাবে একত্রে নির্বাচিত হয়।

size.clusters <- 250
n.clusters <- 60
count.max <- 200
set.seed(17)
system.time({
  n <- n.rows * n.cols
  cells.left <- 1:n
  cells.left[x!=1] <- -1 # Indicates occupancy of cells
  i <- 0
  indices <- c()
  ids <- c()
  while(i < n.clusters && length(cells.left) >= size.clusters && count.max > 0) {
    count.max <- count.max-1
    xy <- sample(cells.left[cells.left > 0], 1)
    cluster <- expand(x, size.clusters, xy)
    if (!is.na(cluster[1]) && length(cluster)==size.clusters) {
      i <- i+1
      ids <- c(ids, rep(i, size.clusters))
      indices <- c(indices, cluster)
      cells.left[indices] <- -1
    }                
  }
  y <- matrix(NA, n.rows, n.cols)
  y[indices] <- ids
})
cat(paste(i, "cluster(s) created.", sep=" "))

310 বাই 500 গ্রিডে প্রয়োগ করার সময় এখানে ফলাফল রয়েছে (ক্লাস্টারগুলি সুস্পষ্ট হওয়ার জন্য যথেষ্ট ছোট এবং মোটা করা)। এটি কার্যকর করতে দুই সেকেন্ড সময় লাগে; 3100 বাই 5000 গ্রিডে (100 গুণ বড়) এটি বেশি সময় নেয় (24 সেকেন্ড) তবে সময়টি যথাযথভাবে স্কেলিং করছে। (অন্যান্য প্ল্যাটফর্মগুলিতে, যেমন সি ++ তে সময় নির্ধারণ করা গ্রিড আকারের উপর নির্ভর করে না))

60 টি ক্লাস্টার


হাই হুইবার এই জন্য আপনাকে অনেক ধন্যবাদ, আমি সত্যিই এটি তারিফ। আমি কেবল কিছুটা জন্য পরীক্ষা নিরীক্ষা করছি এবং খুব শীঘ্রই কয়েকটি ফলোআপ প্রশ্ন নিয়ে ফিরে আসতে পারি।
জেপিডি

+1 জিআইএস এসই-তে আরও কিছু জটিল প্রশ্নের উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ।
রাডার

@whuber। আপনার উত্তরের ভিত্তিতে প্রশ্নটি কিছুটা প্রসারিত করেছে। আবার ধন্যবাদ!
জেপিডি

1
# 1 উত্তর তুচ্ছ হল: লাইন প্রতিস্থাপন y[indices] <- 1:length(indices)দ্বারা y[indices] <- 2। # 2 এর উত্তর প্রায় সরল: কেবল লুপ।
whuber

@whuber। আপডেটের জন্য আবার ধন্যবাদ। এখানে এখন ক্লাম্প সংঘর্ষের সমস্যা রয়েছে এবং এর ফলে সংঘবদ্ধ সংখ্যার চেয়ে ক্লাম্পগুলির আকার কম হয় size.clusters। আমি কীভাবে এটি নিশ্চিত করতে পারি যে একটি ঝাঁক সঠিক আকারে বেড়েছে, যেমন, এই মুহুর্তে, আমি ধরে নিয়েছি এটি একটি বিদ্যমান ঝাঁকুনিতে পরিণত হওয়ার চেষ্টা করে, ব্যর্থ হয়, তবে এখনও এটি একটি সফল সম্প্রসারণ হিসাবে নিবন্ধিত হয়। আমি তারপরেও গড় নাল মডেল স্টাইলের ডেটাসেট তৈরি করে 1000 বারের 60 টি ক্লাম্পের উত্পাদন পুনরাবৃত্তি করতে চাই। এলোমেলো অবস্থান প্রতিটি সময় একটি forলুপের মধ্যে পরিবর্তিত হতে পারে ?
জেপিডি

3

কখনও আপনার ক্রিয়াকলাপ না করে, এবং খেলার জন্য অবকাশ রাখার ছাড়াই, আমি কেবলমাত্র আপনার তালিকায় এই দুটি লিঙ্ক যুক্ত করতে পারি:

ভেক্টর পয়েন্টের ভিত্তিতে নিকটতম রাস্টার সেল মানটি সন্ধান করুন (প্রথম উত্তরটি (4 টি ভোট সহ) এটি আমাকে উত্সাহিত করেছিল)।

এছাড়াও: হাথের গ্রিডস্প্রেড সাহায্য করবে?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.