কোন অ্যালগোরিদম সংখ্যার সাজানো অ্যারের যোগফল গণনা করার জন্য আরও সঠিক?


22

প্রদত্ত ধনাত্মক সংখ্যার একটি ক্রমবর্ধমান সসীম ক্রম । নিম্নলিখিত দুটি অ্যালগরিদমের মধ্যে কোনটি সংখ্যার সমষ্টি গণনা করার জন্য ভাল?z1,z2,.....zএন

s=0; 
for \ i=1:n 
    s=s + z_{i} ; 
end

বা:

s=0; 
for \ i=1:n 
s=s + z_{n-i+1} ; 
end

আমার মতে সংখ্যাটি বৃহত্তম থেকে ক্ষুদ্রতম সংখ্যায় যুক্ত করা আরও ভাল হবে কারণ ত্রুটিটি আরও ছোট হয়। আমরা আরও জানি যে যখন আমরা খুব অল্প সংখ্যক খুব বড় সংখ্যায় যুক্ত করি তখন আনুমানিক ফলাফলটি বৃহত সংখ্যা হতে পারে।

এটা কি সঠিক? আর কী বলা যায়?

উত্তর:


18

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

তবে আপনি আরও ভাল ফলাফল পাবেন (এবং এটি দ্রুত চলে) আপনি যদি চারটি যোগফল তৈরি করেন, উদাহরণস্বরূপ: যোগফল 1, যোগ 2, যোগ 3, যোগ 4 দিয়ে শুরু করুন এবং যোগফল, যোগ 2, যোগ 3, যোগ 4 এর পরিবর্তে চারটি অ্যারের উপাদান যুক্ত করুন। যেহেতু প্রতিটি ফলাফলই মূল অঙ্কের গড় 1/4 র্থ হয়, তাই আপনার ত্রুটি চারগুণ ছোট।

আরও ভাল: জোড়ায় সংখ্যা যুক্ত করুন। তারপরে জোড়ায় ফলাফল যুক্ত করুন। সেই ফলাফলগুলিকে জোড়ায় আবার যুক্ত করুন এবং আপনার যোগ করার জন্য দুটি সংখ্যা না রেখে অবধি left

খুব সহজ: উচ্চতর নির্ভুলতা ব্যবহার করুন। ডাবলের যোগফল গণনা করতে লম্বা ডাবল ব্যবহার করুন। ভাসমানের যোগফল গণনা করতে ডাবল ব্যবহার করুন।

নিখুঁত কাছাকাছি: আগে বর্ণিত কাহানের অ্যালগরিদম দেখুন। সবচেয়ে অল্প সংখ্যক দিয়ে শুরু করে এখনও সেরা ব্যবহার করা হয়েছে।


26

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


24

অ্যানিম্যাল_ম্যাজিকের উত্তরটি সঠিক যে আপনার সংখ্যাটি সবচেয়ে ছোট থেকে বৃহত্তমতে যুক্ত করা উচিত, তবে কেন তা দেখানোর জন্য আমি একটি উদাহরণ দিতে চাই।

ধরুন আমরা একটি ভাসমান পয়েন্ট ফর্ম্যাটে কাজ করছি যা আমাদের চমকপ্রদ 3 অঙ্কের নির্ভুলতা দেয়। এখন আমরা দশটি সংখ্যা যুক্ত করতে চাই:

[1000, 1, 1, 1, 1, 1, 1, 1, 1, 1]

অবশ্যই সঠিক উত্তরটি 1009, তবে আমরা আমাদের 3 ডিজিটের ফর্ম্যাটে এটি পেতে পারি না। 3 টি সংখ্যার সাথে গোল করে, আমাদের কাছে পাওয়া সবচেয়ে সুনির্দিষ্ট উত্তরটি 1010 largest

Loop Index        s
1                 1
2                 2
3                 3
4                 4
5                 5
6                 6
7                 7
8                 8
9                 9
10                1009 -> 1010

সুতরাং আমরা আমাদের ফর্ম্যাটের জন্য সবচেয়ে সঠিক উত্তর পেতে পারি get এখন ধরে নেওয়া যাক যে আমরা বৃহত্তম থেকে ক্ষুদ্রকে যুক্ত করি।

Loop Index        s
1                 1000
2                 1001 -> 1000
3                 1001 -> 1000
4                 1001 -> 1000
5                 1001 -> 1000
6                 1001 -> 1000
7                 1001 -> 1000
8                 1001 -> 1000
9                 1001 -> 1000
10                1001 -> 1000

যেহেতু প্রতিটি অপারেশনের পরে ভাসমান পয়েন্ট সংখ্যাগুলি বৃত্তাকার হয়, তাই সমস্ত সংযোজন সমস্ত বৃত্তাকার হয়ে যায়, আমাদের ত্রুটিটি 1 থেকে 9 থেকে বাড়িয়ে তোলে। এখন ভাবুন যে যোগ করার জন্য আপনার সংখ্যার সেটটিতে 1000 এবং তার পরে একশ 1 বা 10 মিলিয়ন রয়েছে? নোট করুন যে সত্যই নির্ভুল হতে আপনি সর্বনিম্ন দুটি সংখ্যার যোগ করতে চান, তারপরে ফলাফলটিকে আপনার সংখ্যার সেটে রিসর্ট করুন।


15

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

রেফারেন্স হিসাবে, প্রতিটি প্রোগ্রামারকে ভাসমান-পয়েন্ট পাটিগণিত সম্পর্কে যা জানা উচিত তা পর্যাপ্ত বিবরণে মূল বিষয়গুলি অন্তর্ভুক্ত করে যে কেউ এটি 20 (+/- 10) মিনিটে পড়তে পারে এবং বেসিকগুলি বুঝতে পারে। গোল্ডবার্গের লেখা "ফ্লোটিং-পয়েন্ট পাটিগণিত সম্পর্কে প্রতিটি কম্পিউটার বিজ্ঞানীকে যা জানা উচিত" এটি শাস্ত্রীয় রেফারেন্স, তবে আমি জানি বেশিরভাগ লোকেরা যারা সুপারিশ করেন যে কাগজটি সেগুলি নিজেরাই বিশদভাবে পড়েনি, কারণ এটি প্রায় 50 পৃষ্ঠার (এর চেয়েও বেশি কিছুতে) মুদ্রণ), এবং ঘন গদ্যে লিখিত, তাই আমার পক্ষে লোকেদের প্রথম সারির রেফারেন্স হিসাবে সুপারিশ করতে সমস্যা হয়। বিষয়টিতে দ্বিতীয়বার দেখার জন্য এটি ভাল। একটি এনসাইক্লোপিডিক রেফারেন্স হিগামের নির্ভুলতা এবং সংখ্যাগত অ্যালগরিদমের স্থায়িত্ব, যা এই উপাদানটিকে আচ্ছাদন করে পাশাপাশি অন্যান্য অনেক অ্যালগরিদমে সংখ্যাসূচক ত্রুটি জমে; এটি 680 পৃষ্ঠাগুলি, সুতরাং আমি প্রথমে এই রেফারেন্সটি দেখব না।


2
সম্পূর্ণতার জন্য, হিগামের বইতে আপনি 82 পৃষ্ঠায় মূল প্রশ্নের উত্তর খুঁজে পাবেন : ক্রমবর্ধমান ক্রমটি সবচেয়ে ভাল। পদ্ধতির পছন্দ নিয়ে আলোচনা করার একটি বিভাগ (৪.6 )ও রয়েছে।
ফেদেরিকো পোলোনি

7

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

s=0; 
for \ i=1:n 
    printf("Hello World");
    s=s + z_{i} ; 
end

আপনার সমষ্টিতে নিম্ন নির্ভুলতা পাওয়ার জন্য যথেষ্ট (!!)। নির্ভুলতার জন্য পরীক্ষা করার সময় আপনি যদি আপনার কোড প্রিন্ট-ডিবাগ করতে চান তবে খুব সাবধান হন।

আগ্রহীদের জন্য, এই কাগজটি একটি বিস্তৃত ব্যবহৃত সংখ্যাসূচক রুটিন (ল্যাপের র‌্যাঙ্ক-প্রকাশকারী কিউআর ফ্যাক্টেরাইজেশন) এর একটি সমস্যার বর্ণনা দিয়েছে যার ডিবাগিং এবং বিশ্লেষণ এই সমস্যাটির কারণে খুব জটিল ছিল।


1
বেশিরভাগ আধুনিক মেশিনগুলি 64-বিট এবং তারা স্কেলার অপারেশনের জন্য এসএসই বা এভিএক্স ইউনিট ব্যবহার করে। এই ইউনিটগুলি 80-বিট পাটিগণিত সমর্থন করে না এবং অপারেশন আর্গুমেন্টগুলির মতো একই অভ্যন্তরীণ নির্ভুলতা ব্যবহার করে। X87 এফপিইউ ব্যবহার সাধারণত এখন নিরুৎসাহিত করা হয় এবং বেশিরভাগ 64৪-বিট সংকলককে এটি ব্যবহার করতে বাধ্য করার জন্য বিশেষ বিকল্প প্রয়োজন need
Hristo Iliev

1
@ হিস্টো এলিভ মন্তব্যটির জন্য ধন্যবাদ, আমি এটি জানতাম না!
ফেডেরিকো পোলোনি

4

2 টি বিকল্পের মধ্যে, ছোট থেকে বৃহত্তরতে যুক্ত করা সংখ্যাসূচক ত্রুটি তৈরি করবে তারপরে বড় থেকে ছোটতে যুক্ত হবে।

যাইহোক,> 20 বছর আগে আমার "সংখ্যার পদ্ধতিগুলি" শ্রেণিতে প্রশিক্ষক এটি বলেছিলেন এবং এটি আমার কাছে ঘটেছিল যে এটি সংযোজক এবং যে মানগুলি সংযোজন করা হচ্ছে তার মধ্যে পার্থক্যের পার্থক্যের কারণে এটি এখনও প্রয়োজনের তুলনায় আরও ত্রুটি প্রবর্তন করছে।

যৌক্তিকভাবে, একটি পছন্দসই সমাধান হ'ল তালিকায় 2 টি সর্বনিম্ন সংখ্যা যুক্ত করা, তারপরে সাজানো তালিকায় যোগফলটির মানটি আবার সন্নিবেশ করানো।

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


2

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


0

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


এটি মূল অ্যারে সংলগ্ন জোড় যুক্ত হিসাবে একই (যেহেতু এটি সাজানো হয়)। সমস্ত মান গাছের মধ্যে রাখার কোনও কারণ নেই।
গড্রিক

0

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

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


0

আমি কেবল এটি এখানে রেখেছি /programming//a/58006104/860099 (আপনি সেখানে গেলে, 'কোড স্নিপেট দেখান' ক্লিক করুন এবং এটি বোতামটি দিয়ে চালান

এটি জাভাস্ক্রিপ্ট উদাহরণ যা পরিষ্কারভাবে দেখায় যে বৃহত থেকে শুরু করে যোগফল বড় ত্রুটি দেয়

arr=[9,.6,.1,.1,.1,.1];

sum     =             arr.reduce((a,c)=>a+c,0);  // =  9.999999999999998
sortSum = [...arr].sort().reduce((a,c)=>a+c,0);  // = 10

console.log('sum:     ',sum);
console.log('sortSum:',sortSum);

কেবল লিঙ্ক-উত্তর এই সাইটে নিরুৎসাহিত করা হয়। লিঙ্কে কী সরবরাহ করা হয়েছে তা আপনি ব্যাখ্যা করতে পারেন?
নিকোগুয়ারো

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