আমি দেখছি মির্সিভিকিং একটি চতুর্থাংশের প্রস্তাব দিয়েছে । আমি একই জিনিসটি বলতে যাচ্ছিলাম এবং এটি ব্যাখ্যা করার জন্য, এখানে কোড এবং একটি উদাহরণ রয়েছে। কোডটি লিখিত আছে R
তবে সহজেই বলা উচিত, পাইথন port
ধারণাটি লক্ষণীয়ভাবে সহজ: বিন্দুটিকে প্রায় অর্ধেকটি এক্স-দিক দিয়ে বিভক্ত করুন, তারপরে অবিচ্ছিন্নভাবে দুটি অংশকে Y- দিক বরাবর বিভক্ত করুন, প্রতিটি স্তরের দিক পরিবর্তন করে, যতক্ষণ না কোনও বিভাজন পছন্দ না হয়।
উদ্দেশ্য হ'ল প্রকৃত পয়েন্টের অবস্থানগুলি ছদ্মবেশ করা, এটি বিভাজনের মধ্যে কিছু এলোমেলোতা প্রবর্তন করা দরকারী । এটির একটি দ্রুত সহজ উপায় হ'ল 50% থেকে দূরে একটি ছোট এলোমেলো পরিমাণে কোয়ান্টাইল সেটে বিভক্ত হওয়া। এই ফ্যাশনে (ক) বিভাজক মানগুলি ডেটা স্থানাঙ্কের সাথে একত্রিত হওয়ার পক্ষে অত্যন্ত সম্ভাবনা নেই, যাতে পয়েন্টগুলি বিভাজন দ্বারা নির্মিত কোয়াড্রেন্টগুলিতে স্বতন্ত্রভাবে পতিত হয় এবং (খ) বিন্দু স্থানাঙ্কগুলি চতুষ্কোণ থেকে অবিকল পুনর্গঠন করা অসম্ভব হবে।
যেহেতু উদ্দেশ্যটি k
প্রতিটি চতুর্ভুজ পাতার মধ্যে ন্যূনতম পরিমাণ নোড বজায় রাখার জন্য, আমরা চতুর্দিকে একটি সীমাবদ্ধ ফর্মটি প্রয়োগ করি। এটি (1) গ্রুপগুলির মধ্যে ক্লাস্টারিং পয়েন্টগুলিকে সমর্থন করবে যা প্রতিটি এবং k
2 * k
-1 উপাদানগুলির মধ্যে রয়েছে এবং (2) চতুর্ভুজগুলিকে ম্যাপিং করবে।
এই R
কোডটি নোড এবং টার্মিনাল পাতার একটি গাছ তৈরি করে, শ্রেণি দ্বারা তাদের আলাদা করে। ক্লাস লেবেল পোস্ট-প্রসেসিং যেমন প্লট করা, নীচে দেখানো ত্বরান্বিত করে। কোডগুলি আইডির জন্য সংখ্যাসূচক মান ব্যবহার করে। এটি গাছে 52 টি গভীরতা পর্যন্ত কাজ করে (ডাবল ব্যবহার করে; স্বাক্ষরযুক্ত দীর্ঘ পূর্ণসংখ্যার ব্যবহার করা হলে সর্বাধিক গভীরতা 32)। গভীর গাছগুলির জন্য (যা কোনও প্রয়োগে খুব বেশি সম্ভাবনা নেই, কারণ কমপক্ষে k
* 2 ^ 52 পয়েন্ট জড়িত থাকতে পারে), আইডিগুলিতে স্ট্রিং থাকতে হবে।
quadtree <- function(xy, k=1) {
d = dim(xy)[2]
quad <- function(xy, i, id=1) {
if (length(xy) < 2*k*d) {
rv = list(id=id, value=xy)
class(rv) <- "quadtree.leaf"
}
else {
q0 <- (1 + runif(1,min=-1/2,max=1/2)/dim(xy)[1])/2 # Random quantile near the median
x0 <- quantile(xy[,i], q0)
j <- i %% d + 1 # (Works for octrees, too...)
rv <- list(index=i, threshold=x0,
lower=quad(xy[xy[,i] <= x0, ], j, id*2),
upper=quad(xy[xy[,i] > x0, ], j, id*2+1))
class(rv) <- "quadtree"
}
return(rv)
}
quad(xy, 1)
}
দ্রষ্টব্য যে এই অ্যালগরিদমের পুনরাবৃত্ত ডিভাইড এবং বিজয়ী নকশা (এবং ফলস্বরূপ, বেশিরভাগ পোস্ট-প্রসেসিং অ্যালগরিদমগুলির) অর্থ সময় প্রয়োজন হয় ও (এম) এবং র্যামের ব্যবহার হ'ল (এন) যেখানে m
সংখ্যাটি কোষ এবং n
পয়েন্ট সংখ্যা। প্রতি সেল প্রতি সর্বনিম্ন পয়েন্ট দ্বারা বিভক্ত m
সমানুপাতিক n
,k
। এটি গণনার সময়গুলি অনুমান করার জন্য দরকারী। উদাহরণস্বরূপ, যদি 50-99 পয়েন্টের (কে = 50) কোষগুলিতে n = 10 ^ 6 পয়েন্ট বিভাজনে 13 সেকেন্ড সময় লাগে, m = 10 ^ / 50 = 20000 you প্রতি সেল প্রতি পয়েন্ট (কে = 5), মি 10 গুণ বড় হয়, তাই সময় প্রায় 130 সেকেন্ডে যায়। (যেহেতু কোষগুলি ছোট হওয়ার সাথে সাথে তাদের মিডলগুলির চারপাশে স্থানাঙ্কের একটি সেট বিভক্ত করার প্রক্রিয়া দ্রুততর হয়, আসল সময়টি ছিল মাত্র 90 সেকেন্ড)) প্রতি সেলে কে = 1 পয়েন্টে যেতে, প্রায় ছয়গুণ বেশি সময় লাগবে এখনও, বা নয় মিনিট, এবং আমরা কোডটি আসলে এর চেয়ে কিছুটা দ্রুত গতিতে প্রত্যাশা করতে পারি।
আরও এগিয়ে যাওয়ার আগে আসুন কিছু আকর্ষণীয় অনিয়মিতভাবে ব্যবধানযুক্ত ডেটা তৈরি করি এবং তাদের সীমাবদ্ধ চতুষ্কোণ (0.29 সেকেন্ড অতিবাহিত সময়) তৈরি করি:
এই প্লট উত্পাদনের কোড এখানে। এটি R
এর পলিমারফিজমটি শোষণ করে: উদাহরণস্বরূপ, points.quadtree
যখনই points
কোনও quadtree
বস্তুতে ফাংশন প্রয়োগ করা হয় তখন তাকে ডাকা হবে । এর ক্লাস্টার সনাক্তকারী অনুসারে পয়েন্টগুলি রঙ করার জন্য ফাংশনের চরম সরলতার মধ্যে এর শক্তিটি স্পষ্ট:
points.quadtree <- function(q, ...) {
points(q$lower, ...); points(q$upper, ...)
}
points.quadtree.leaf <- function(q, ...) {
points(q$value, col=hsv(q$id), ...)
}
গ্রিডটি নিজেই প্লট করা একটু কৌশলযুক্ত কারণ এর জন্য চতুর্ভুজ বিভাজনের জন্য ব্যবহৃত চৌকাঠগুলির বারবার ক্লিপিংয়ের প্রয়োজন হয়, তবে একই পুনরাবৃত্তির পদ্ধতিটি সহজ এবং মার্জিত। যদি ইচ্ছা হয় তবে কোয়ার্ট্রেন্টগুলির বহুভুজ উপস্থাপনাগুলি তৈরি করতে কোনও রূপ ব্যবহার করুন।
lines.quadtree <- function(q, xylim, ...) {
i <- q$index
j <- 3 - q$index
clip <- function(xylim.clip, i, upper) {
if (upper) xylim.clip[1, i] <- max(q$threshold, xylim.clip[1,i]) else
xylim.clip[2,i] <- min(q$threshold, xylim.clip[2,i])
xylim.clip
}
if(q$threshold > xylim[1,i]) lines(q$lower, clip(xylim, i, FALSE), ...)
if(q$threshold < xylim[2,i]) lines(q$upper, clip(xylim, i, TRUE), ...)
xlim <- xylim[, j]
xy <- cbind(c(q$threshold, q$threshold), xlim)
lines(xy[, order(i:j)], ...)
}
lines.quadtree.leaf <- function(q, xylim, ...) {} # Nothing to do at leaves!
অন্য উদাহরণ হিসাবে, আমি 1,000,000 পয়েন্ট তৈরি করেছি এবং এগুলিকে প্রতিটি 5-9 এর গ্রুপে বিভক্ত করেছি। সময় ছিল 91.7 সেকেন্ড।
n <- 25000 # Points per cluster
n.centers <- 40 # Number of cluster centers
sd <- 1/2 # Standard deviation of each cluster
set.seed(17)
centers <- matrix(runif(n.centers*2, min=c(-90, 30), max=c(-75, 40)), ncol=2, byrow=TRUE)
xy <- matrix(apply(centers, 1, function(x) rnorm(n*2, mean=x, sd=sd)), ncol=2, byrow=TRUE)
k <- 5
system.time(qt <- quadtree(xy, k))
#
# Set up to map the full extent of the quadtree.
#
xylim <- cbind(x=c(min(xy[,1]), max(xy[,1])), y=c(min(xy[,2]), max(xy[,2])))
plot(xylim, type="n", xlab="x", ylab="y", main="Quadtree")
#
# This is all the code needed for the plot!
#
lines(qt, xylim, col="Gray")
points(qt, pch=".")
জিআইএসের সাথে কীভাবে ইন্টারঅ্যাক্ট করবেন তার উদাহরণ হিসাবে , আসুন shapefiles
গ্রন্থাগারটি ব্যবহার করে সমস্ত কোয়াড্ট্রি সেলগুলি বহুভুজ আকারের ফাইল হিসাবে লিখি । কোডটির ক্লিপিং রুটিনগুলি এমুলেট করে lines.quadtree
তবে এবার এটির জন্য কোষগুলির ভেক্টর বিবরণ উত্পন্ন করতে হবে। এগুলি shapefiles
লাইব্রেরির সাথে ব্যবহারের জন্য ডেটা ফ্রেম হিসাবে আউটপুট ।
cell <- function(q, xylim, ...) {
if (class(q)=="quadtree") f <- cell.quadtree else f <- cell.quadtree.leaf
f(q, xylim, ...)
}
cell.quadtree <- function(q, xylim, ...) {
i <- q$index
j <- 3 - q$index
clip <- function(xylim.clip, i, upper) {
if (upper) xylim.clip[1, i] <- max(q$threshold, xylim.clip[1,i]) else
xylim.clip[2,i] <- min(q$threshold, xylim.clip[2,i])
xylim.clip
}
d <- data.frame(id=NULL, x=NULL, y=NULL)
if(q$threshold > xylim[1,i]) d <- cell(q$lower, clip(xylim, i, FALSE), ...)
if(q$threshold < xylim[2,i]) d <- rbind(d, cell(q$upper, clip(xylim, i, TRUE), ...))
d
}
cell.quadtree.leaf <- function(q, xylim) {
data.frame(id = q$id,
x = c(xylim[1,1], xylim[2,1], xylim[2,1], xylim[1,1], xylim[1,1]),
y = c(xylim[1,2], xylim[1,2], xylim[2,2], xylim[2,2], xylim[1,2]))
}
পয়েন্টগুলি সেগুলি সরাসরি ব্যবহার করে read.shp
বা (x, y) স্থানাঙ্কের একটি ডেটা ফাইল আমদানি করে পড়া যায় ।
ব্যবহারের উদাহরণ:
qt <- quadtree(xy, k)
xylim <- cbind(x=c(min(xy[,1]), max(xy[,1])), y=c(min(xy[,2]), max(xy[,2])))
polys <- cell(qt, xylim)
polys.attr <- data.frame(id=unique(polys$id))
library(shapefiles)
polys.shapefile <- convert.to.shapefile(polys, polys.attr, "id", 5)
write.shapefile(polys.shapefile, "f:/temp/quadtree", arcgis=TRUE)
( xylim
উপমহলে উইন্ডো করতে বা বৃহত্তর অঞ্চলে ম্যাপিং প্রসারিত করতে এখানে যে কোনও পছন্দসই সীমা ব্যবহার করুন; এই কোডটি পয়েন্টগুলির সীমাতে ডিফল্ট হয়))
এটি একাই যথেষ্ট: মূল পয়েন্টগুলিতে এই বহুভুজগুলির একটি স্থানিক যোগদান ক্লাস্টারগুলি সনাক্ত করবে। একবার চিহ্নিত হয়ে গেলে, ডাটাবেস "সংক্ষিপ্তকরণ" ক্রিয়াকলাপগুলি প্রতিটি ঘরের মধ্যে পয়েন্টগুলির সংক্ষিপ্ত পরিসংখ্যান তৈরি করে।