অনুশীলনে অন্যান্য বাছাই করা অ্যালগরিদমের চেয়ে কুইকোর্টটি আরও ভাল কেন?


308

একটি প্রমিত আলগোরিদিম অবশ্যই আমরা শেখানো হয় যে quicksort হয় গড় এবং এর সবচেয়ে খারাপ ক্ষেত্রে। একই সময়ে, অন্যান্য বাছাই আলগোরিদিম চর্চিত যা হয় সবচেয়ে খারাপ ক্ষেত্রে (যেমন মধ্যে mergesort এবং heapsort , এবং শ্রেষ্ঠ ক্ষেত্রে (যেমন এমনকি রৈখিক সময়) bubblesort ) কিন্তু মেমরি কিছু অতিরিক্ত চাহিদার সঙ্গে।O(nlogn)O(n2)O(nlogn)

আরও কিছু চলমান সময়ে তাত্ক্ষণিকভাবে দেখার পরে বলা স্বাভাবিক যে কুইকোর্ট অন্যের মতো দক্ষ হওয়া উচিত নয়

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

তাহলে, কেন কুইকোর্টগুলি অনুশীলনে অন্যান্য বাছাই করা অ্যালগরিদমকে ছাড়িয়ে যায়? এটি কি বাস্তব-বিশ্বের ডেটাগুলির কাঠামোর সাথে সম্পর্কযুক্ত ? কম্পিউটারে মেমরিটি যেভাবে কাজ করে তার সাথে এটির কি সম্পর্ক আছে? আমি জানি যে কিছু স্মৃতি অন্যের চেয়ে দ্রুততর হয় তবে আমি জানি না যে এই পাল্টা-স্বজ্ঞাত পারফরম্যান্সের আসল কারণ কিনা (তাত্ত্বিক অনুমানের সাথে তুলনা করলে)।


আপডেট 1: একটি প্রমিত উত্তর বলছে যে গড় মামলার এর সাথে জড়িত ধ্রুবকগুলি অন্যান্য অ্যালগরিদমে জড়িত ধ্রুবকগুলির চেয়ে ছোট are তবে, আমি কেবল এর স্বজ্ঞাত ধারণাগুলির পরিবর্তে সুনির্দিষ্ট গণনা সহ এর সঠিক যুক্তি দেখতে পাইনি see( এন লগ এন )O(nlogn)O(nlogn)

যাইহোক, এটি বাস্তব পার্থক্যের মতোই মনে হয়, যেমন কিছু উত্তরগুলি মেমোরি স্তরে বলে, যেখানে বাস্তবায়নগুলি কম্পিউটারের অভ্যন্তরীণ কাঠামোর সুবিধা গ্রহণ করে, উদাহরণস্বরূপ, ক্যাশে মেমরিটি র‌্যামের চেয়ে দ্রুত হয়। আলোচনা ইতিমধ্যে আকর্ষণীয়, কিন্তু আমি এখনও মেমরি ব্যবস্থাপনা থেকে সম্মান সঙ্গে আরো বিস্তারিত দেখতে চাই মনে হচ্ছে যেহেতু যে উত্তর এটা দিয়ে কি হবে।


আপডেট 2: বেশ কয়েকটি ওয়েব পৃষ্ঠাগুলি রয়েছে বাছাই অ্যালগরিদমগুলির তুলনা করে যা অন্যদের তুলনায় কিছু ফ্যানসিয়ার (সর্বাধিক উল্লেখযোগ্যভাবে বাছাই করা- অ্যালগরিদমস.কম )। একটি দুর্দান্ত ভিজ্যুয়াল এইড উপস্থাপন করা ব্যতীত, এই পদ্ধতিটি আমার প্রশ্নের উত্তর দেয় না।


2
মার্জ বাছাইটি সবচেয়ে খারাপ ক্ষেত্রে হয় এবং পূর্ণসংখ্যার একটি অ্যারে বাছাই করা হয় যেখানে সংখ্যার সাজানোর সাহায্যে সময়ে করা যেতে পারে inte ( এন )O(nlogn)O(n)
কার্ল ম্যামার্ট

13
বাছাই- algorithms.com এর বাছাই করা অ্যালগরিদমগুলির একটি সম্পূর্ণ পুঙ্খানুপুঙ্খ তুলনা রয়েছে।
জো

2
বিজ্ঞাপন আপডেট 1: আমি অনুমান করি যে আপনার কাছে কঠোর বিশ্লেষণ বা বাস্তববাদী অনুমান থাকতে পারে। দুটোই দেখিনি। উদাহরণস্বরূপ, বেশিরভাগ আনুষ্ঠানিক বিশ্লেষণ কেবল তুলনাগুলি গণনা করে।
রাফেল

9
এই প্রশ্নটি প্রোগ্রামারগুলিতে একটি সাম্প্রতিক প্রতিযোগিতা জিতেছে SE এসই !
রাফেল

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

উত্তর:


215

সংক্ষিপ্ত উত্তর

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

দীর্ঘ উত্তর

সবার আগে,

গড় কেস অস্তিত্ব নেই!

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

নোটেশন কেন ?O

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

দুটি উপায় আছে:

  1. কিছু মেশিন মডেল ঠিক করুন।

    এটি লেখকের উদ্ভাবিত কৃত্রিম "সাধারণ" কম্পিউটারের জন্য ডন নুথের বইয়ের সিরিজ "দ্য আর্ট অফ কম্পিউটার প্রোগ্রামিং" এ সম্পন্ন হয়েছে। ভলিউম 3 এ আপনি অনেকগুলি বাছাই করা অ্যালগরিদমের উদাহরণস্বরূপ গড় কেস ফলাফলগুলি খুঁজে পান eg

    • :11.667(n+1)ln(n)1.74n18.74
    • একত্রিতকরণ:12.5nln(n)
    • হিপসোর্ট: 16nln(n)+0.01n
    • অন্তর্ভুক্তকরণ: [ উত্স ]2.25n2+7.75n3ln(n) বেশ কয়েকটি বাছাই অ্যালগরিদমের রানটাইম

    এই ফলাফলগুলি ইঙ্গিত দেয় যে কুইকোর্ট দ্রুততম। তবে, এটি কেবল নথের কৃত্রিম মেশিনে প্রমাণিত, এটি আপনার x86 পিসি বলার জন্য অগত্যা কিছু বোঝায় না। এটিও লক্ষ করুন যে অ্যালগোরিদমগুলি ছোট ইনপুটগুলির জন্য পৃথকভাবে সম্পর্কিত:
    ছোট ইনপুটগুলির জন্য একাধিক বাছাই অ্যালগরিদমের রানটাইম
    [ উত্স ]

  2. বিমূর্ত বেসিক ক্রিয়াকলাপগুলি বিশ্লেষণ করুন ।

    তুলনা ভিত্তিক বাছাইয়ের জন্য, এটি সাধারণত অদলবদল এবং কী তুলনা হয় । রবার্ট সেডজউইকের বইগুলিতে, যেমন "অ্যালগোরিদম" -তে এই পদ্ধতির অনুসরণ করা হয়েছে। আপনি সেখানে খুঁজে পাবেন

    • কুইকোর্ট: তুলনা এবং গড়ে12nln(n)13nln(n)
    • একত্রিতকরণ: তুলনা, তবে অ্যারে অ্যাক্সেসগুলি (সংযোজন সোয়াপ ভিত্তিক নয়, তাই আমরা এটি গণনা করতে পারি না)।8.66 এন এলএন ( এন )1.44nln(n)8.66nln(n)
    • অন্তর্ভুক্তকরণ: তুলনা এবং on গড়ে।114n214n2

    আপনি দেখতে পাচ্ছেন, এটি সঠিকভাবে রানটাইম বিশ্লেষণ হিসাবে সহজেই অ্যালগরিদমের তুলনা করার অনুমতি দেয় না, তবে ফলাফলগুলি মেশিনের বিশদ থেকে পৃথক।

অন্যান্য ইনপুট বিতরণ

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


8
টাইপ ২ এর ফলাফল মেশিন-নির্ভর ধ্রুবক সন্নিবেশ করে প্রকার 1 এর ফলাফলগুলিতে রূপান্তরিত করা যায়। সুতরাং, আমি 2 তর্ক করব একটি উচ্চতর পদ্ধতির।
রাফেল

2
@ রাফেল +1। আমি মনে করি আপনি ধরে নিচ্ছেন যে মেশিন-নির্ভরও বাস্তবায়ন-নির্ভর, তাই না? মানে, দ্রুত মেশিন + দুর্বল বাস্তবায়ন সম্ভবত খুব দক্ষ নয়।
জানোমা

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

3
প্রকৃতপক্ষে, টাইপ 2 বিশ্লেষণটি অনুশীলনে নিম্নমানের। রিয়েল ওয়ার্ল্ড মেশিনগুলি এত জটিল যে টাইপ 2 থেকে প্রাপ্ত ফলাফলগুলি 1 টি টাইপ করে সহজেই অনুবাদ করা যায় না type টাইপ 1 এর সাথে তুলনা করুন: পরীক্ষামূলক চলমান সময়গুলি প্লট করতে 5 মিনিটের কাজ লাগে।
জুলাই

4
@Jules: হয় "পরীক্ষামূলক চলমান সময় ষড়যন্ত্র" না টাইপ 1; এটি কোনও ধরণের আনুষ্ঠানিক বিশ্লেষণ নয় এবং এটি অন্যান্য মেশিনে স্থানান্তরযোগ্য নয়। এজন্য আমরা সর্বোপরি প্রথাগত বিশ্লেষণ করি।
রাফেল

78

এই প্রশ্নটি সম্পর্কে একাধিক পয়েন্ট তৈরি করা যেতে পারে।

কুইকসোর্ট সাধারণত দ্রুত হয়

যদিও কুইকসোর্টের সবচেয়ে খারাপ পরিস্থিতি আচরণ রয়েছে, এটি সাধারণত দ্রুত: র্যান্ডম পিভট নির্বাচনটি ধরে নিলে, আমাদের খুব বড় সম্ভাবনা রয়েছে যে আমরা কিছু সংখ্যক বাছাই করি যা ইনপুটটিকে একই আকারের দুটি উপচ্ছেদে পৃথক করে, যা আমরা ঠিক তাই করতে চাই exactly আছে।O(n2)

বিশেষত, এমনকি যদি আমরা একটি পাইভট বাছাই করি যা প্রতি 10 টি স্প্লিট (যা একটি মেহ বিভক্ত) এবং একটি 1 উপাদান - 10-90 উপাদান বিভাজন তৈরি করে (অন্যথায় উপাদান বিভক্ত হয় (যা আপনি পেতে পারেন সবচেয়ে খারাপ বিভাজন)) , আমাদের চলমান সময় এখনও (নোট করুন যে এটি ধ্রুবকগুলিকে এমন এক বিন্দুতে উড়িয়ে দেবে যে মার্জ সাজানোর কাজটি যদিও দ্রুততর হবে)।( এন লগ এন )n1O(nlogn)

কুইকসোর্টটি বেশিরভাগ ধরণের চেয়ে দ্রুত হয়

Quicksort সাধারণত প্রকারের যে তুলনায় ধীর চেয়ে দ্রুততর (বলুন, তার সঙ্গে সন্নিবেশ সাজানোর চলমান সময়), কারণ বৃহৎ জন্য কেবল তাদের চলমান বার বিস্ফোরিত করা।( এন 2 ) এনO(nlogn)O(n2)n

হিপসোর্টের মতো অন্যান্য অন্যান্য অ্যালগরিদমের তুলনায় কুইকসোর্ট কেন অনুশীলনে এত তাড়াতাড়ি আসার একটি ভাল কারণ এটি তুলনামূলকভাবে ক্যাশে-দক্ষ। এটির চলমান সময়টি আসলে ( এন)O(nlogn), যেখানেবিব্লকের আকার size অন্যদিকে হিপসোর্টের তেমন কোনও স্পিডআপ নেই: এটি মেমরির ক্যাশে-দক্ষতার সাথে অ্যাক্সেস করার মতো নয়।O(nBlog(nB))B

এই ক্যাশে দক্ষতার কারণ হ'ল এটি লাইনগতভাবে ইনপুট স্ক্যান করে এবং লাইনারি পার্টিশনগুলি ইনপুট। এর অর্থ আমরা যে ক্যাশে লোড করি প্রতিটি ক্ষেত্রেই আমরা ক্যাশের মধ্যে লোড হওয়া প্রতিটি নম্বরকে অন্যের জন্য সেই ক্যাশে অদলবদলের আগে সর্বাধিক করতে পারি। বিশেষত, অ্যালগরিদমটি ক্যাশে-বিস্মৃত, যা প্রতিটি ক্যাশে স্তরের জন্য ভাল ক্যাশে পারফরম্যান্স দেয়, এটি অন্য জয়।

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

কুইকসোর্টটি সাধারণত মার্জেসোর্টের চেয়ে দ্রুত

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

নোট করুন যে কুইকসোর্ট আরও পুনরাবৃত্তি কল করবে, তবে স্ট্যাকের জায়গা বরাদ্দ করা সস্তা (প্রায় বিনামূল্যে নিখরচায়, যতক্ষণ না আপনি স্ট্যাকটি ফুঁকান না) এবং আপনি এটি পুনরায় ব্যবহার করেন। (অথবা আপনার হার্ড ড্রাইভে যদি গাদা উপর একটি দৈত্য ব্লক বণ্টন হয় সত্যিই বড়) বেশ একটু বেশি ব্যয়বহুল, কিন্তু উভয় হে ( লগ ইন করুন এন ) overheads যে তুলনায় ফ্যাকাশে হে ( ) কাজ উপরে উল্লেখ করেছে।nO(logn)O(n)

সবশেষে, নোট করুন যে কুইকসোর্ট সঠিকভাবে হওয়া ইনপুটটির প্রতি সামান্য সংবেদনশীল, সেই ক্ষেত্রে এটি কিছু বদলে যেতে পারে। মার্জেসোর্টের এমন কোনও অপ্টিমাইজেশন নেই, যা মেরিক্সোর্টের তুলনায় কুইকসোর্টকে কিছুটা দ্রুত করে তোলে।

আপনার প্রয়োজন অনুসারে বাছাই করুন

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


3
আপনার শেষ মন্তব্যটি বিশেষভাবে মূল্যবান। আমার এক সহকর্মী বর্তমানে বিভিন্ন ইনপুট বিতরণে কুইকোর্টের বাস্তবায়ন বিশ্লেষণ করে। উদাহরণস্বরূপ, তাদের মধ্যে কয়েকটি বহু নকলের জন্য ভেঙে যায়।
রাফেল

4
O(n2)

8
"[টি] এর পিছনে এখানে কোনও তত্ত্ব নেই, এটি কেবল দ্রুত হওয়ার জন্য ঘটে।" এই বক্তব্যটি বৈজ্ঞানিক দৃষ্টিকোণ থেকে অত্যন্ত অসন্তুষ্টিজনক। কল্পনা করুন নিউটন বলেছিলেন, "প্রজাপতিগুলি উড়ে যায়, আপেল পড়ে যায়: এর পিছনে কোনও তত্ত্ব নেই, আপেল কেবল পড়ে যায়।"
ডেভিড রিচার্বি

2
@ অ্যালেক্স টেন ব্রিংক, "বিশেষত, অ্যালগরিদমটি ক্যাশে-বিস্মৃত " এর অর্থ কী?
Hibou57

4
@ ডেভিড রিচার্বি, "এই বক্তব্যটি একটি বৈজ্ঞানিক দৃষ্টিকোণ থেকে অত্যন্ত অসন্তুষ্টিজনক": তিনি হয়তো আমাদের সত্যিকারের ভান করা উচিত না বলে ভেবেই একটি সত্য প্রত্যক্ষ করছেন। কিছু অ্যালগরিদম পরিবার সম্পূর্ণ আনুষ্ঠানিককরণের অভাবে ভোগেন; হ্যাশিং ফাংশন একটি উদাহরণ ক্ষেত্রে।
Hibou57

45

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

এটি ডেভিড আর ম্যাকআইভারের একটি দুর্দান্ত ব্লগ নিবন্ধ যা টিমসোর্টকে অভিযোজিত মার্জোর্টের ফর্ম হিসাবে ব্যাখ্যা করে।


17
@ রাফেল এটিকে দৃc়ভাবে বলতে গেলে, টিমসোর্ট হ'ল সংক্ষিপ্ত ইনপুটগুলির জন্য অ্যাসিপটিক্স প্লাস সন্নিবেশ সাজানোর জন্য মার্জ সাজ্ট এবং মাঝে মধ্যে ইতিমধ্যে সাজানো বিস্ফোরণ (যা অনুশীলনে প্রায়শই ঘটে) এর সাথে দক্ষতার সাথে মোকাবিলা করার জন্য কিছু হিউরিস্টিকস যুক্ত হয়। ডাই: অ্যালগরিদম ছাড়াও, list.sortপেশাদারদের দ্বারা অপ্টিমাইজড বিল্ট-ইন ফাংশন হওয়া থেকে উপকার পাওয়া যায়। একটি সুন্দর তুলনা একই স্তরের প্রচেষ্টা একই স্তরে সমস্ত ফাংশন লিখিত হবে।
গিলস

1
@ ডাই: আপনি কমপক্ষে কোন ধরণের ইনপুট (শ্রদ্ধার জন্য তাদের বিতরণ) কোন পরিস্থিতিতে (কম র‌্যাম, একটি বাস্তবায়ন সমান্তরালভাবে করেছেন ...) আপনি নিজের ফলাফল পেয়েছেন তা দিয়ে আপনি অন্তত বর্ণনা করতে পারেন।
রাফেল

7
আমরা এলোমেলো সংখ্যার তালিকায় পরীক্ষা করেছি এবং আংশিকভাবে বাছাই করেছি, সম্পূর্ণভাবে বাছাই করেছি এবং বিপরীতভাবে বাছাই করেছি। এটি প্রথম শিক্ষাবর্ষের প্রাথমিক পাঠ্যক্রম ছিল, সুতরাং এটি একটি গভীর অভিজ্ঞতামূলক গবেষণা ছিল না। তবে এটি এখন সরকারীভাবে জাভা এসই 7 এ এবং অ্যান্ড্রয়েড প্ল্যাটফর্মে অ্যারেগুলি বাছাই করতে ব্যবহৃত হয় এর অর্থ কিছুটা।
দাই

3
এটি এখানেও আলোচনা করা হয়েছিল: cstheory.stackexchange.com/a/927/74
Jukka Suomela

34

আমি মনে করি যে অন্যান্য বাছাই করা অ্যালগরিদমের তুলনায় কুইকসোর্টটি এত তাড়াতাড়ি হওয়ার অন্যতম প্রধান কারণ হ'ল এটি ক্যাশে বান্ধব। যখন কিউএস একটি অ্যারের অংশকে প্রসেস করে তখন সেগমেন্টের শুরু এবং শেষের অংশে অ্যাক্সেস করে সেগমেন্টের কেন্দ্রের দিকে চলে যায়।

সুতরাং, যখন আপনি শুরু করেন, আপনি অ্যারেতে প্রথম উপাদানটি অ্যাক্সেস করেন এবং মেমরির একটি অংশ ("অবস্থান") ক্যাশে লোড হয়। এবং যখন আপনি দ্বিতীয় উপাদানটি অ্যাক্সেস করার চেষ্টা করেন, এটি ইতিমধ্যে ক্যাশে রয়েছে (তাই সম্ভবত) এটি খুব দ্রুত।

হিপস্পোর্টের মতো অন্যান্য অ্যালগরিদমগুলি এর মতো কাজ করে না, তারা অ্যারেটিতে প্রচুর লাফ দেয়, যা তাদের ধীর করে তোলে।


5
এটি বিতর্কিত ব্যাখ্যা: মার্জোর্টটিও ক্যাশে বান্ধব।
Dmytro Korduban

2
আমি মনে করি এই উত্তরটি মূলত সঠিক, তবে এখানে কিছু বিবরণ এখানে youtube.com/watch?v=aMnn0Jq0J-E
rgrig

3
সম্ভবত দ্রুত সাজানোর গড় ক্ষেত্রে সময় জটিলতার জন্য গুণক ধ্রুবকটি আরও ভাল (আপনি উল্লিখিত ক্যাশে ফ্যাক্টারের থেকে পৃথক)।
কাভেঃ

1
আপনি যে বক্তব্যটি উল্লেখ করেছেন তা তাত্ক্ষণিকভাবে অন্যান্য ভাল বৈশিষ্ট্যের তুলনায় গুরুত্বপূর্ণ নয়।
এমএমএস

1
@ কাভাহ: "দ্রুত সাজানোর গড় ক্ষেত্রে সময়ের জটিলতার জন্য গুণক ধ্রুবক আরও ভাল" এই বিষয়ে আপনার কোনও ডেটা আছে কি?
জর্জিও

29

অন্যরা ইতিমধ্যে বলেছেন যে কুইকোর্টের অ্যাসেম্পটোটিক গড় রানটাইম অন্যান্য বাছাই করা অ্যালগরিদমের (নির্দিষ্ট সেটিংসে) তুলনায় ভাল (ধ্রুবক অবস্থায়) ভাল।

O(nlogn)

নোট করুন যে কুইকসোর্টের অনেকগুলি রূপ রয়েছে (উদাহরণস্বরূপ সেডজউইকের গবেষণামূলক সংস্করণ)। তারা বিভিন্ন ইনপুট বিতরণে আলাদাভাবে সঞ্চালন করে (অভিন্ন, প্রায় বাছাই করা, প্রায় বিপরীতভাবে সাজানো, অনেকগুলি নকল, ...) এবং অন্যান্য অ্যালগোরিদম কারওর পক্ষে ভাল be

k10


20

O(nlgn)

PS: সুনির্দিষ্টভাবে বলতে গেলে, অন্যান্য অ্যালগরিদমের চেয়ে ভাল হওয়া কার্যনির্ভর। কিছু কাজের জন্য অন্যান্য বাছাই করা অ্যালগরিদম ব্যবহার করা ভাল।

আরো দেখুন:


3
@ জানোমা এটি আপনি কোন ভাষা এবং সংকলক ব্যবহার করেন তা একটি বিষয়। প্রায় সমস্ত কার্যকরী ভাষা (এমএল, লিস্প, হাস্কেল) অপ্টিমাইজেশন করতে পারে যা স্ট্যাকটিকে বাড়তে বাধা দেয় এবং জরুরী ভাষার জন্য স্মার্ট সংকলকগুলিও এটি করতে পারে (জিসিসি, জি ++, এবং আমি বিশ্বাস করি যে এমএসভিসি সমস্ত এটি করে)। উল্লেখযোগ্য ব্যতিক্রম জাভা, যা কখনই এই অপটিমাইজেশনটি করবে না, তাই আপনার পুনরাবৃত্তিটিকে পুনরাবৃত্তি হিসাবে পুনরায় লিখতে জাভাতে বোঝা যায়।
রাফ কেটলার

4
@ জেডি, আপনি কুইকোর্টের সাথে টেল কল অপ্টিমাইজেশন ব্যবহার করতে পারবেন না (কমপক্ষে সম্পূর্ণ নয়), কারণ এটি নিজেকে দু'বার কল করে। আপনি দ্বিতীয় কলটি অপ্টিমাইজ করতে পারেন তবে প্রথম কলটি নয়।
সুইভ

1
@ জানোমা, আপনার আসলে পুনরাবৃত্তির প্রয়োগের দরকার নেই। উদাহরণস্বরূপ, আপনি যদি সিটিতে qsort ফাংশনটির বাস্তবায়নটি দেখে থাকেন তবে এটি পুনরাবৃত্ত কলগুলি ব্যবহার করে না এবং তাই বাস্তবায়নটি আরও দ্রুত হয়ে যায়।
কাভেঃ

1
হিপসোর্টটিও স্থানে রয়েছে, কেন QS প্রায় দ্রুত হয়?
কেভিন

6
23240

16

Θ(n2)Θ(nlogn)

দ্বিতীয় কারণ হ'ল এটি in-placeবাছাই করে এবং ভার্চুয়াল-মেমরি পরিবেশের সাথে খুব ভাল কাজ করে।

আপডেট:: (জেনোমার এবং সুইভের মন্তব্যের পরে)

এটি আরও ভালভাবে বর্ণনা করার জন্য আমাকে মার্জ সাজান্ট ব্যবহার করে একটি উদাহরণ দেই (কারণ মার্জ সাজ্ট হ'ল দ্রুত সাজানোর পরে পরবর্তী ব্যাপকভাবে গৃহীত সাজানো অ্যালগরিদম, আমি মনে করি) এবং আপনাকে বলতে পারি অতিরিক্ত ধ্রুবকগুলি কোথা থেকে আসে (আমার জ্ঞানের সেরাটিতে এবং কেন আমি মনে করি দ্রুত বাছাই ভাল):

নিম্নলিখিত সিকোয়েন্স বিবেচনা করুন:

12,30,21,8,6,9,1,7. The merge sort algorithm works as follows:

(a) 12,30,21,8    6,9,1,7  //divide stage
(b) 12,30   21,8   6,9   1,7   //divide stage
(c) 12   30   21   8   6   9   1   7   //Final divide stage
(d) 12,30   8,21   6,9   1,7   //Merge Stage
(e) 8,12,21,30   .....     // Analyze this stage

আপনি যদি যত্ন নেন তবে শেষ পর্যায়টি কীভাবে ঘটছে তা পুরোপুরি দেখুন, প্রথম 12 টি 8 এর সাথে তুলনা করা হয় এবং 8 টি ছোট হয় তাই এটি প্রথমে যায়। এখন 12 আবার 21 এর সাথে তুলনা করে আবার 12 এবং আরও অনেক কিছু এগিয়ে যায়। যদি আপনি চূড়ান্ত সংশ্লেষ অর্থাৎ 4 টি অন্যান্য উপাদানগুলির সাথে 4 টি উপাদান গ্রহণ করেন তবে এটি কনস্ট্যান্ট হিসাবে প্রচুর এক্সট্রা তুলনা করে যা দ্রুত সাজানোর ক্ষেত্রে ব্যয় হয় না। এই কারণেই দ্রুত বাছাই করা পছন্দ করা হয়।


1
কিন্তু কনস্ট্যান্টগুলি এত ছোট করে তোলে কী?
সুইভ

1
@ এসভিক কারণ এগুলি বাছাই করা হয়েছে in-place, কোনও অতিরিক্ত মেমরির প্রয়োজন নেই।
0x0

Θ(nlgn)

15

বাস্তব বিশ্বের ডেটা নিয়ে কাজ করার আমার অভিজ্ঞতা হ'ল কুইকোর্টটি একটি খারাপ পছন্দ । কুইকসোর্ট র্যান্ডম ডেটা দিয়ে ভাল কাজ করে তবে বাস্তব বিশ্বের ডেটা প্রায়শই এলোমেলোভাবে হয় না।

২০০৮ সালে আমি কুইকোর্টের ব্যবহারের জন্য একটি ঝুলন্ত সফ্টওয়্যার বাগ ট্র্যাক করেছি। কিছুক্ষণ পরে আমি সন্নিবেশ বাছাই, কুইকোর্ট, হিপ সারণি এবং মার্জ সাজানোর সহজ ইমপ্লিমেন্টস লিখে এগুলি পরীক্ষা করেছিলাম। আমার সংযুক্তি বাছাই বড় ডেটা সেটগুলিতে কাজ করার সময় অন্য সকলকে ছাড়িয়ে গেছে।

তার পর থেকে মার্জ করা বাছাই করা আমার পছন্দ অনুসারে বাছাই করা অ্যালগরিদম। এটি মার্জিত। এটি কার্যকর করা সহজ। এটি একটি স্থিতিশীল বাছাই। এটি চটকদার মতো চতুষ্কোণ আচরণে অধঃপতিত হয় না। আমি ছোট অ্যারেগুলিকে সাজানোর জন্য সন্নিবেশ সাজানোর দিকে স্যুইচ করি।

অনেক সময় আমি আমার আত্ম-ভাবনা খুঁজে পেয়েছি যে প্রদত্ত বাস্তবায়ন কেবল কুইকোর্টের জন্য আশ্চর্যজনকভাবে কাজ করে কেবল এটি অনুসন্ধান করার জন্য যে এটি আসলে চিকুইসোর্ট নয়। কখনও কখনও বাস্তবায়ন কুইকোর্ট এবং অন্য একটি অ্যালগরিদমের মধ্যে স্যুইচ করে এবং কখনও কখনও এটি কুইকোর্টটি মোটেও ব্যবহার করে না। উদাহরণ হিসাবে, GLibc এর qsort () ফাংশনগুলি আসলে মার্জ সাজ্ট ব্যবহার করে। শুধু কাজ স্থান বণ্টন ব্যর্থ তাতে জায়গা quicksort ফিরে আসবে করলে যা একটি কোড মন্তব্য কল "ধীর অ্যালগরিদম"

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


আমি এর অনুরূপ কিছু দেখেছি কারণ আমরা ইতিমধ্যে সাজানো ডেটার ব্যাচে constantlyোকানোর জন্য ক্রমাগত সংযোজন / অবলম্বন করে যাচ্ছিলাম। আপনি একটি এলোমেলোভাবে quicksort ব্যবহার করে গড়ে এই সমস্যা এড়ানোর কাজ করতে পারেন (এবং বিরল এবং র্যান্ডম ভয়ঙ্কর ধীর সাজানোর বিস্মিত পেতে), অথবা আপনি একটি সবসময় ধীর সাজানোর যা কখনো শেষ করতে সময় একটি বিস্ময়কর পরিমাণ সময় লাগে সহ্য করতে পারে। কখনও কখনও আপনার পাশাপাশি বাছাই স্থায়িত্ব প্রয়োজন। জাভা একত্রীকরণের ভেরিয়েন্টে মার্জ সাজানোর ব্যবহার থেকে চলে গেছে from
রব

@ রব এটি সঠিক নয়। জাভা এখনও আজও একীভূতকরণ (টিমসোর্ট) এর বৈকল্পিক ব্যবহার করে। এটি কুইকোর্টেরও বৈকল্পিক ব্যবহার করে (ডুয়েল-পিভট কুইকোর্ট)।
এরওয়ান লেগ্রান্ড

14

1 - দ্রুত বাছাইয়ের জায়গা রয়েছে (ধ্রুবক পরিমাণ ব্যতীত অতিরিক্ত মেমোরির প্রয়োজন হয় না))

2 - দ্রুত দক্ষ বাছাই করা অন্যান্য দক্ষ বাছাই করা অ্যালগরিদমের তুলনায় কার্যকর করা সহজ।

3 - দ্রুত সাজানোর অন্যান্য দক্ষ বাছাইকরণ অ্যালগরিদমের তুলনায় চলমান সময়টিতে আরও কম ধ্রুবক কারণ রয়েছে।

আপডেট: মার্জ সাজানোর জন্য, আপনাকে কিছু "মার্জিং" করতে হবে যা মার্জ করার আগে ডেটা সংরক্ষণ করার জন্য অতিরিক্ত অ্যারে (গুলি) দরকার; কিন্তু দ্রুত সাজানোর মধ্যে, আপনি না। যে কারণে দ্রুত সাজানোর জায়গা রয়েছে। মার্জ করার জন্য কিছু অতিরিক্ত তুলনাও করা হয়েছে যা মার্জ সাজানোর ক্ষেত্রে ধ্রুবক কারণগুলি বাড়ায়।


3
আপনি কি জায়গায় উন্নত, পুনরাবৃত্ত কুইকোর্টের বাস্তবায়ন দেখেছেন ? এগুলি অনেকগুলি জিনিস তবে "সহজ" নয়।
রাফেল

2
নম্বর 2 আমার প্রশ্নের মোটেও উত্তর দেয় না , এবং আমার মতে 1 এবং 3 নম্বরগুলির যথাযথ ন্যায়সঙ্গততা প্রয়োজন।
জানোমা

@ রাফেল: এগুলি সহজ। পয়েন্টারগুলির পরিবর্তে অ্যারে ব্যবহার করে দ্রুত সাজানোর জায়গাটিতে প্রয়োগ করা অনেক সহজ। এবং জায়গাটিতে থাকার জন্য এটি পুনরাবৃত্ত হওয়ার দরকার নেই।
এমএমএস

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

@ 1 মার্জসোর্টটি পাশাপাশি স্থান হতে পারে। @ 2 দক্ষতার সংজ্ঞা কী? আমি মার্জটি বাছাই করতে পছন্দ করি কারণ এটি আমার মতে অত্যন্ত সাধারণ এবং তবুও দক্ষ। @ 3 অপ্রাসঙ্গিক যখন আপনি প্রচুর পরিমাণে ডেটা বাছাই করেন এবং প্রয়োজন হয় যে অ্যালগোরিদম দক্ষতার সাথে প্রয়োগ করা হয়েছে।
ওসকার স্কোগ

11

কোন শর্তে একটি নির্দিষ্ট বাছাই করা অ্যালগরিদম আসলে দ্রুততম হয়?

Θ(log(n)2)Θ(nlog(n)2)

Θ(nk)Θ(nm)k=2#number_of_Possible_valuesm=#maximum_length_of_keys

3) অন্তর্নিহিত ডেটা কাঠামোতে কি লিঙ্কযুক্ত উপাদান রয়েছে? হ্যাঁ -> সর্বদা স্থান একত্রিত করার পদ্ধতিতে ব্যবহার করুন। সংযুক্ত ডেটা স্ট্রাকচারের জন্য স্থির আকার বা অভিযোজিত (আর্ফ প্রাকৃতিক) নীচের অংশে বিভিন্ন ধরণের একত্রীকরণের জন্য প্রয়োগ করা সহজ এবং যেহেতু তাদের প্রতিটি পদক্ষেপে পুরো ডেটা অনুলিপি করার প্রয়োজন হয় না এবং তাদের কখনও পুনরাবৃত্তির প্রয়োজন হয় না, তাই তারা অন্যান্য সাধারণ তুলনা-ভিত্তিক প্রকারের চেয়ে দ্রুত, দ্রুত বাছাইয়ের চেয়েও দ্রুত।

Θ(n)

5) অন্তর্নিহিত ডেটার আকারটি একটি ছোট থেকে মাঝারি আকারের সাথে আবদ্ধ হতে পারে? যেমন এন <10,000 ... 100,000,000 (অন্তর্নিহিত আর্কিটেকচার এবং ডেটা কাঠামোর উপর নির্ভর করে)? হ্যাঁ -> বিটোনিক বাছাই বা ব্যাচার বিজোড়-এমনকি মেশানো ব্যবহার করুন। গোটো 1)

Θ(n)Θ(n2)Θ(nlog(n)2)সবচেয়ে খারাপ ক্ষেত্রে রান সময় পরিচিত হয়, বা সম্ভবত চিরুনি সাজানোর চেষ্টা করুন। আমি নিশ্চিত নই যে শেল বাছাই বা চিরুনি সাজানোর অভ্যাসটি যথাযথভাবে ভাল সম্পাদন করবে।

Θ(log(n))Θ(n)Θ(n)Θ(log(n))Θ(n2)Θ(n)Θ(n)Θ(log(n))Θ(nlog(n))

Θ(nlog(n))

কুইকোর্টের জন্য বাস্তবায়নের ইঙ্গিত:

Θ(n)Θ(log(n))Θ(nlogk(k1))

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

একীভূতকরণের জন্য কার্যকরকরণের ইঙ্গিতগুলি:

1) বোতল-আপ সংযুক্তি শীর্ষ-ডাউন সংযুক্তির চেয়ে সর্বদা দ্রুততর হয়, কারণ এতে কোনও পুনরাবৃত্তি কলের প্রয়োজন হয় না।

2) খুব নিখুঁত একত্রীকরণটি ডাবল বাফার ব্যবহার করে গতি বাড়িয়ে দিতে পারে এবং প্রতিটি পদক্ষেপের পরে অস্থায়ী অ্যারে থেকে ডেটা অনুলিপি করার পরিবর্তে বাফারটি স্যুইচ করতে পারে।

3) অনেক রিয়েল-ওয়ার্ল্ড ডেটার জন্য, অভিযোজিত মার্জোর্ট স্থির-আকারের মার্জোর্টের চেয়ে অনেক দ্রুত।

Θ(k)Θ(log(k))Θ(1)Θ(n)

আমি যা লিখেছি তা থেকে এটি পরিষ্কার হয়ে গেছে যে কুইকোর্টটি প্রায়শই দ্রুতগতির অ্যালগরিদম হয় না, তবে নিম্নলিখিত শর্তগুলি যখন প্রযোজ্য তখনই:

1) সম্ভাব্য মানগুলির তুলনায় আরও কয়েকটি রয়েছে

2) অন্তর্নিহিত ডেটা কাঠামোটি লিঙ্কযুক্ত নয়

3) আমরা একটি স্থিতিশীল অর্ডার প্রয়োজন হয় না

৪) ডেটা যথেষ্ট পরিমাণে বড় যে বিটোনিক সর্টর বা ব্যাচারের বিজোড়-এমনকি মেশানো ক্রিসের সামান্য সাব-অপটিমামাল এ্যাসিম্পটিক রান-টাইম

5) ডেটা প্রায় বাছাই করা হয় না এবং ইতিমধ্যে বড় আকারে সাজানো অংশ থাকে না

6) আমরা একাধিক স্থান থেকে এক সাথে ডেটা সিকোয়েন্স অ্যাক্সেস করতে পারি

Θ(log(n))Θ(n)

PS: কারও পাঠ্যের বিন্যাসে আমাকে সহায়তা করা দরকার।


(৫): অ্যাপলের বাছাইয়ের প্রয়োগটি প্রথমে অ্যারের শুরুতে এবং শেষে উভয়দিকে আরোহী বা অবতরণ ক্রমে একটি রান পরীক্ষা করে। এই জাতীয় উপাদানগুলি খুব বেশি না থাকলে এটি খুব দ্রুত এবং যদি এগুলির মধ্যে n / ln এন এর বেশি থাকে তবে খুব কার্যকরভাবে এই উপাদানগুলি পরিচালনা করতে পারে। দুটি বাছাই করা অ্যারে সংঘবদ্ধ করে ফলাফলটি বাছাই করুন এবং আপনি মার্জ করুন
gnasher729

8

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

ab


5
ক্যুইসকোর্ট বনাম মার্জ সাজানোর বিষয়ে আপনার যুক্তি জল ধরে না। কুইকসোর্টটি একটি বড় পদক্ষেপের সাথে শুরু হয়, তারপরে আরও ছোট এবং আরও ছোট চালগুলি তৈরি করে (প্রতিটি ধাপে প্রায় অর্ধেক বড়)। মার্জ বাছাই একটি ছোট পদক্ষেপের সাথে শুরু হয়, তারপরে আরও বৃহত্তর এবং বৃহত্তর পদক্ষেপগুলি তৈরি করে (প্রতিটি ধাপে প্রায় দ্বিগুণ বড়)। এটি অন্যটির তুলনায় একজনের চেয়ে বেশি দক্ষ হওয়ার বিষয়টি নির্দেশ করে না।
গিলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.