এই সমস্যাটির কাছে যাওয়ার অনেক উপায় রয়েছে। ডেটার রাস্টার ফর্ম্যাটটি একটি রাস্টার-ভিত্তিক পদ্ধতির পরামর্শ দেয়; এই পদ্ধতির পর্যালোচনা করার সময়, বাইনারি পূর্ণসংখ্যার লিনিয়ার প্রোগ্রাম হিসাবে সমস্যার একটি সূত্রটি আশাব্যঞ্জক বলে মনে হচ্ছে, কারণ এটি অনেকগুলি জিআইএস সাইট-নির্বাচন বিশ্লেষণের আত্মায় খুব সহজেই এবং সহজেই তাদের সাথে খাপ খাইয়ে নিতে পারে।
এই সূচনায়, আমরা ফিলিং বহুভুজ (গুলি) এর সমস্ত সম্ভাব্য অবস্থান এবং ওরিয়েন্টেশনগুলি গণনা করি, যা আমি "টাইলস" হিসাবে উল্লেখ করব। প্রতিটি টাইলের সাথে যুক্ত এটি এর "ধার্মিকতা" এর একটি পরিমাপ। উদ্দেশ্যটি হ'ল অন-ওভারল্যাপিং টাইলগুলির একটি সংগ্রহ খুঁজে পাওয়া যায় যার সামগ্রিক কল্যাণ যতটা সম্ভব বিশাল। এখানে, আমরা প্রতিটি টাইলকে nessেকে রাখার ক্ষেত্রটির ভালতা নিতে পারি। (আরও ডেটা সমৃদ্ধ এবং পরিশীলিত সিদ্ধান্তের পরিবেশে আমরা প্রতিটি টাইলের মধ্যে অন্তর্ভুক্ত কোষগুলির বৈশিষ্ট্যগুলির সংমিশ্রণ হিসাবে দৃশ্যমানতা, অন্যান্য জিনিসের সান্নিধ্য ইত্যাদি সম্পর্কিত বৈশিষ্ট্যগুলির সংমিশ্রণ হিসাবে ভালতা গণনা করতে পারি))
এই সমস্যার সীমাবদ্ধতাগুলি হ'ল সমাধানের মধ্যে কোনও দুটি টাইল ওভারল্যাপ হতে পারে না।
বহুভুজের কোষগুলিকে পরিপূর্ণ করে ("অঞ্চল") 1, 2, ..., এম পরিমিত করে এটিকে দক্ষ গণনা করার উপযোগী করে কিছুটা বিমূর্তভাবে ফ্রেম করা যেতে পারে । যে কোনও টাইল বসানো স্থানটি শূন্য এবং এরগুলির একটি সূচক ভেক্টরের সাথে এনকোড করা যেতে পারে , যাকে অন্য কোথাও টাইল এবং শূন্য দ্বারা আবৃত কোষগুলির সাথে সামঞ্জস্য করে। এই এনকোডিংয়ে, টাইলস সংগ্রহের জন্য প্রয়োজনীয় সমস্ত তথ্য তাদের সূচক ভেক্টরগুলিকে সংশ্লেষের মাধ্যমে পাওয়া যাবে (উপাদান অনুসারে উপাদান হিসাবে, যথারীতি): যোগফলটি ননজারো হবে ঠিক যেখানে কমপক্ষে একটি টাইল একটি ঘরকে আচ্ছাদন করে এবং যোগফল আরও বেশি হবে একের চেয়েও কোথাও দুটি বা আরও টাইলস ওভারল্যাপ হয়। (যোগফল কার্যকরভাবে ওভারল্যাপের পরিমাণ গণনা করে))
আরও একটি সামান্য বিমূর্ততা: সম্ভাব্য টাইল স্থাপনের সেটটি নিজেই গণনা করা যেতে পারে, বলুন 1, 2, ..., এন । টাইল স্থাপনের কোনও সেট নির্বাচন নিজেই একটি সূচক ভেক্টরের সাথে মিলে যায় যেখানে টাইলগুলি স্থাপন করা উচিত।
ধারণাগুলি ঠিক করার জন্য এখানে একটি ছোট উদাহরণ রয়েছে । এটি গণনার জন্য ব্যবহৃত ম্যাথামেটিক কোডের সাথে রয়েছে , যাতে প্রোগ্রামিংয়ের অসুবিধা (বা এর অভাব) প্রকট হয়ে উঠতে পারে।
প্রথমে, আমরা একটি অঞ্চলকে টাইলসযুক্ত করে চিত্রিত করেছি:
region = {{0, 0, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
যদি আমরা এর ঘরগুলি বাম থেকে ডানদিকে শীর্ষে শুরু করে সংখ্যা নির্ধারণ করি তবে এই অঞ্চলের জন্য সূচক ভেক্টরের 16 টি প্রবেশ রয়েছে:
Flatten[region]
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
90 ডিগ্রির গুণমান দ্বারা সমস্ত আবর্তনের পাশাপাশি নীচের টাইলটি ব্যবহার করুন:
tileSet = {{{1, 1}, {1, 0}}};
ঘূর্ণন (এবং প্রতিচ্ছবি) উত্পন্ন করার কোড:
apply[s_List, alpha] := Reverse /@ s;
apply[s_List, beta] := Transpose[s];
apply[s_List, g_List] := Fold[apply, s, g];
group = FoldList[Append, {}, Riffle[ConstantArray[alpha, 4], beta]];
tiles = Union[Flatten[Outer[apply[#1, #2] &, tileSet, group, 1], 1]];
(এই কিছুটা অস্বচ্ছ গণনাটি /math//a/159159 এ একটি উত্তরে ব্যাখ্যা করা হয়েছে , যা এটি সহজেই টাইলের সমস্ত সম্ভাব্য আবর্তন এবং প্রতিবিম্ব উত্পাদন করে এবং তারপরে কোনও সদৃশ ফলাফলগুলি সরিয়ে দেয়))
মনে করুন আমরা এখানে টাইল স্থাপন করেছি:
3, 6 এবং 7 টি ঘর এই প্লেসমেন্টে আচ্ছাদিত। যা সূচক ভেক্টর দ্বারা মনোনীত করা হয়
{0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}
আমরা যদি এই টাইলটি এক কলামকে ডানদিকে সরিয়ে ফেলি, তবে সেই সূচক ভেক্টরটি পরিবর্তে
{0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
এই উভয় অবস্থানে একই সাথে টাইলস স্থাপনের চেষ্টা করার সংমিশ্রণটি এই সূচকগুলির যোগফল দ্বারা নির্ধারিত হয়,
{0, 0, 1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0}
সপ্তম অবস্থানে থাকা ২ টি একটি ঘরে এই ওভারল্যাপটি দেখায় (দ্বিতীয় সারিতে নীচে, বাম থেকে তৃতীয় কলাম)। কারণ আমরা ওভারল্যাপ চাই না, আমাদের প্রয়োজন হবে যে কোনও বৈধ সমাধানে ভেক্টরগুলির যোগফলের 1 এর বেশি হওয়া উচিত না।
দেখা যাচ্ছে যে এই সমস্যার জন্য, টাইলগুলির জন্য ওরিয়েন্টেশন এবং অবস্থানের 29 টি সংমিশ্রণ সম্ভব। (এটি একটি বিস্তৃত অনুসন্ধানের সাথে জড়িত একটি সহজ বিট কোডিংয়ের সাথে পাওয়া গেছে)) আমরা সমস্ত 29 সম্ভাব্য চিত্রগুলি কলামের ভেক্টর হিসাবে তাদের সূচকগুলি অঙ্কন করে চিত্রিত করতে পারি । (সারিগুলির পরিবর্তে কলামগুলি ব্যবহার করা প্রচলিত)) এখানে ফলাফল প্রাপ্ত অ্যারের একটি চিত্র দেওয়া হয়েছে, এতে 16 টি সারি থাকবে (আয়তক্ষেত্রের প্রতিটি সম্ভাব্য কক্ষের জন্য একটি) এবং 29 টি কলাম থাকবে:
makeAllTiles[tile_, {n_Integer, m_Integer}] :=
With[{ m0 = Length[tile], n0 = Length[First[tile]]},
Flatten[
Table[ArrayPad[tile, {{i, m - m0 - i}, {j, n - n0 - j}}], {i, 0, m - m0}, {j, 0, n - n0}], 1]];
allTiles = Flatten[ParallelMap[makeAllTiles[#, ImageDimensions[regionImage]] & , tiles], 1];
allTiles = Parallelize[
Select[allTiles, (regionVector . Flatten[#]) >= (Plus @@ (Flatten[#])) &]];
options = Transpose[Flatten /@ allTiles];
(পূর্ববর্তী দুটি সূচক ভেক্টর বাম দিকে প্রথম দুটি কলাম হিসাবে উপস্থিত হবে)) তীক্ষ্ণ চোখের পাঠক সমান্তরাল প্রক্রিয়াকরণের বেশ কয়েকটি সুযোগ লক্ষ্য করেছেন: এই গণনাগুলি কয়েক সেকেন্ড সময় নিতে পারে।
পূর্ববর্তী সমস্তগুলি ম্যাট্রিক্স স্বরলিপি ব্যবহার করে নিখুঁতভাবে পুনঃস্থাপন করা যেতে পারে:
এম হ'ল সারি এবং এন কলাম সহ এফ বিকল্পগুলির এই অ্যারে ।
এক্স দৈর্ঘ্য এন এর টাইল স্থাপনের একটি সেটের সূচক ।
বি হল একটি এন- ভেক্টর।
আর এই অঞ্চলের জন্য সূচক; এটি একটি এম- ভেক্টর।
যে কোনও সম্ভাব্য সমাধান এক্স এর সাথে যুক্ত মোট "ধার্মিকতা" আরএফএক্সের সমান , কারণ এফএক্স এক্স দ্বারা আচ্ছাদিত কোষগুলির সূচক এবং আর সহ এই পণ্যগুলির সংখ্যার যোগফল । (আমরা যদি অঞ্চলটির নির্দিষ্ট অঞ্চলগুলির পক্ষে বা এড়াতে চাইলে সমাধানগুলি চাইলে আমরা আর ওজন করতে পারতাম )) এটি সর্বাধিক করা উচিত। কারণ আমরা এটি ( আরএফ ) হিসাবে লিখতে পারি । এক্স , এটি একটি হল রৈখিক ফাংশন এক্স : এই গুরুত্বপূর্ণ। (নীচের কোডে ভেরিয়েবলে আরএফc
রয়েছে ))
সীমাবদ্ধতার হয় যে
এক্স এর সমস্ত উপাদান অবশ্যই অ-নেতিবাচক হতে হবে;
এক্স এর সমস্ত উপাদানগুলি 1 এর চেয়ে কম হওয়া উচিত (যা খ এর সাথে সম্পর্কিত এন্ট্রি );
এক্স এর সমস্ত উপাদান অবশ্যই অবিচ্ছেদ্য হতে হবে।
(1) এবং (2) সীমাবদ্ধতাগুলি এটি একটি রৈখিক প্রোগ্রাম করে , তৃতীয় প্রয়োজনীয়তা এটিকে পূর্ণসংখ্যায় পরিণত করে লিনিয়ার প্রোগ্রামে পরিণত করে।
ঠিক এই ফর্মটিতে প্রকাশিত পূর্ণসংখ্যার লিনিয়ার প্রোগ্রামগুলি সমাধান করার জন্য অনেকগুলি প্যাকেজ রয়েছে । তারা এম এবং এন এর মান দশকে বা কয়েক হাজারেও পরিচালনা করতে সক্ষম । কিছু বাস্তব-বিশ্বের অ্যাপ্লিকেশনগুলির জন্য এটি সম্ভবত যথেষ্ট ভাল।
আমাদের প্রথম উদাহরণ হিসাবে, আমি ম্যাথমেটিক 8 এর LinearProgramming
কমান্ড ব্যবহার করে পূর্ববর্তী উদাহরণের জন্য একটি সমাধান গণনা করেছি । (এটি একটি লিনিয়ার অবজেক্টিভ ফাংশনকে ন্যূনতম করে দেবে। বস্তুনিষ্ঠ ফাংশনটিকে উপেক্ষা করে ন্যূনতমকরণ সহজেই সর্বাধিককরণের দিকে পরিণত হয়)) এটি 0.011 সেকেন্ডে একটি সমাধান (টাইলস এবং তাদের অবস্থানের তালিকা হিসাবে) ফিরে এলো:
b = ConstantArray[-1, Length[options]];
c = -Flatten[region].options;
lu = ConstantArray[{0, 1}, Length[First[options]]];
x = LinearProgramming[c, -options, b, lu, Integers, Tolerance -> 0.05];
If[! ListQ[x] || Max[options.x] > 1, x = {}];
solution = allTiles[[Select[x Range[Length[x]], # > 0 &]]];
ধূসর কোষগুলি এই অঞ্চলে মোটেই নেই; সাদা কোষগুলি এই সমাধান দ্বারা আচ্ছাদিত করা হয়নি।
আপনি এটির মতো আরও অনেক টিলিংস (হাতের কাছে) কাজ করতে পারেন - তবে আপনি এর চেয়ে ভাল আর কোনও খুঁজে পেতে পারেন না। এটি এই পদ্ধতির সম্ভাব্য সীমাবদ্ধতা: এটি একের বেশি সমাধান থাকা সত্ত্বেও এটি আপনাকে একটি সেরা সমাধান দেয় । (কিছু কার্যক্ষেত্র রয়েছে: যদি আমরা এক্স এর কলামগুলি পুনরায় অর্ডার করি তবে সমস্যাটি অপরিবর্তিত থাকে, তবে সফ্টওয়্যারটি প্রায়শই ফলস্বরূপ আলাদা সমাধান বেছে নেয়, তবে, এই আচরণটি অনির্দেশ্য is)
দ্বিতীয় চিত্রণ হিসাবে , আরও বাস্তববাদী হতে, আসুন প্রশ্নে অঞ্চলটি বিবেচনা করুন। চিত্রটি আমদানি করে এবং এটি পুনরায় মডেল করে আমি এটি 69 বাই 81 গ্রিড দিয়ে উপস্থাপন করেছি:
অঞ্চলটিতে এই গ্রিডের 2156 টি কক্ষ রয়েছে।
জিনিসগুলিকে আকর্ষণীয় করে তোলার জন্য, এবং রৈখিক প্রোগ্রামিং সেটআপটির সাধারণতা চিত্রিত করতে, আসুন দুই প্রান্তের আয়তক্ষেত্র দিয়ে যতটা সম্ভব এই অঞ্চলটিকে কভার করার চেষ্টা করি :
একটি 17 বাই 9 (153 কোষ) এবং অন্যটি 15 বাই 11 (165 কোষ)। আমরা দ্বিতীয়টি ব্যবহার করতে পছন্দ করতে পারি, কারণ এটি বৃহত্তর, তবে প্রথমটি ত্বকযুক্ত এবং আরও শক্ত জায়গায় ফিট করতে পারে। দেখা যাক!
প্রোগ্রামে এখন এন = 5589 টি সম্ভাব্য টাইল স্থাপন করা জড়িত । এটি মোটামুটি বড়! গণনার 6.3 সেকেন্ড পরে, ম্যাথমেটিকা এই দশ-টাইল সমাধান নিয়ে এল:
কিছুটা স্ল্যাকের কারণে ( .eg, আমরা নীচে বাম টাইলটি চারটি কলাম পর্যন্ত তার বামে স্থানান্তরিত করতে পারি), সম্ভবত এই কয়েকটি থেকে কিছুটা পৃথক পৃথক সমাধান রয়েছে।