فصل سوم: برنامه نویسی پویا

Slides:



Advertisements
Similar presentations
Recursion.
Advertisements

1 Data Structures - CSCI 102 CS102 C++ Operator Overloading Prof Tejada.
1 CS 240A : Numerical Examples in Shared Memory with Cilk++ Matrix-matrix multiplication Matrix-vector multiplication Hyperobjects Thanks to Charles E.
1 Jake’s Pizza Shop Owner Jake Manager Chef Brad Carol Waitress Waiter Cook Helper Joyce Chris Max Len.
Problem: Given an array of positive integers, find a pair of integers in the array that adds up to 10 (or indicate none exist). Your code should be as.
Recursion practice. Problem 0 Using recursion (and no arrays), write the code to read in a series of numbers (until EOF) and then print them backwards.
CPSC 311, Fall 2009: Dynamic Programming 1 CPSC 311 Analysis of Algorithms Dynamic Programming Prof. Jennifer Welch Fall 2009.
The Template Class Chain Chain Linear list. Each element is stored in a node. Nodes are linked together using pointers.
Dynamic Programming Optimization Problems Dynamic Programming Paradigm
CPSC 411 Design and Analysis of Algorithms Set 5: Dynamic Programming Prof. Jennifer Welch Spring 2011 CPSC 411, Spring 2011: Set 5 1.
1 Dynamic Programming Andreas Klappenecker [based on slides by Prof. Welch]
Algorithms All pairs shortest path
Searching Arrays Linear search Binary search small arrays
Data Structures.  Consider storing data for 100 employees by their Social Security Numbers (SSN)  SSN range: –  A fast search:
Matrices Jordi Cortadella Department of Computer Science.
Dynamic Programming Dynamic Programming Dynamic Programming is a general algorithm design technique for solving problems defined by or formulated.
Algorithms April-May 2013 Dr. Youn-Hee Han The Project for the Establishing the Korea ㅡ Vietnam College of Technology in Bac Giang.
General Trees CS 400/600 – Data Structures. General Trees2.
Data Structures Using C++1 Search Algorithms Sequential Search (Linear Search) Binary Search.
1 CSE 1342 Programming Concepts Trees. 2 Basic Terminology Trees are made up of nodes and edges. A tree has a single node known as a root. –The root is.
INTRODUCTION TO BINARY TREES P SORTING  Review of Linear Search: –again, begin with first element and search through list until finding element,
CS 8833 Algorithms Algorithms Dynamic Programming.
 Trees Data Structures Trees Data Structures  Trees Trees  Binary Search Trees Binary Search Trees  Binary Tree Implementation Binary Tree Implementation.
CSCI 333 Data Structures Chapter 6 30 September and 2 and 4 October 2002.
Class Constructors class Student { private: string id, firstName, lastName; float gpa; public: Student() Student(string sID) Student(string first, string.
Introduction to Programming (in C++) Multi-dimensional vectors Jordi Cortadella, Ricard Gavaldà, Fernando Orejas Dept. of Computer Science, UPC.
UNCA CSCI September, 2001 These notes were prepared by the text’s author Clifford A. Shaffer Department of Computer Science Virginia Tech Copyright.
Prof. Amr Goneid, AUC1 CSCE 210 Data Structures and Algorithms Prof. Amr Goneid AUC Part 6. Dictionaries(3): Binary Search Trees.
CS 1430: Programming in C++ 1. Class StudentList class StudentList { private: int numStudents; Student students[MAX_SIZE]; int find(const Student& s)
Chapter 11 Binary Trees Dr. Youssef Harrath
AL-HUSEEN BIN TALAL UNIVERSITY College of Engineering Department of Computer Engineering Algorithms and Data Structures Binary Tree Course No.:
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 15. Dictionaries (1): A Key Table Class.
1 Trees What is a Tree? Tree terminology Why trees? What is a general tree? Implementing trees Binary trees Binary tree implementation Application of Binary.
C:\Temp\Templates 4 5 Use This Main Program 6.
Int fact (int n) { If (n == 0) return 1; else return n * fact (n – 1); } 5 void main () { Int Sum; : Sum = fact (5); : } Factorial Program Using Recursion.
TU/e Algorithms (2IL15) – Lecture 3 1 DYNAMIC PROGRAMMING
1 Binary Search Trees. 2 Binary Search Trees Binary Search Trees The Binary Search Tree (BST) Search, Insertion and Traversal of BST Removal of nodes.
Computer Skills2 / Scientific Colleges 1 Arrays Topics to cover: Arrays Data Types One-dimensional Arrays Two-dimensional Arrays.
Nested Structures struct TDate { int year, month, day; }; struct StudentType { string id, firstName, lastName; float gpa; TDate DOB; }; struct SectionType.
1 Data Structures and Algorithms Linked List. 2 Lists Lists The Linked List ADT Linked List The Linked List Class Definition Linked List Class implementation.
Searching Arrays Linear search Binary search small arrays
CSCE 210 Data Structures and Algorithms
CSCE 210 Data Structures and Algorithms
Outline In this topic we will look at:
Search Algorithms Sequential Search (Linear Search) Binary Search
درس طراحی الگوریتم ها (با شبه کد های c ++)
Chapter 20: Binary Trees.
Multiway Search Trees.
Recursion.
Chapter 21: Binary Trees.
© המרכז להוראת המדעים האוניברסיטה העברית בירושלים
CSCE 411 Design and Analysis of Algorithms
null, true, and false are also reserved.
برنامه نویسی پویا (Dynamic Programming)
Tree A tree is a data structure in which each node is comprised of some data as well as node pointers to child nodes
Chapter 8 Dynamic Programming
CS2606 Trees.
Arrays Topics to cover: Arrays Data Types One-dimensional Arrays
2018, Fall Pusan National University Ki-Joune Li
Data Structure and Algorithms
Non-Linear Structures
Heap code in C++ template <class eType>
2019/4/10 chapter25.
BST Insert To insert an element, we essentially do a find( ). When we reach a NULL pointer, we create a new node there. void BST::insert(const Comp &
//****************************************
Class StudentList class StudentList { private: int numStudents;
Matrix Chain Multiplication
Tree traversals BST properties Search Insertion
The Sequential Search (Linear Search)
CS 1430: Programming in C++.
Presentation transcript:

فصل سوم: برنامه نویسی پویا

برنامه نویسی پویا، از این لحاظ که نمونه به نمونه های کوچکتر تقسیم می شود ، مشابه روش تقسیم و حل است ولی در این روش ، نخست نمونه های کوچک تر را حل می کنیم ، نتایج را ذخیره می کنیم و بعدا هر گاه به یکی از آن ها نیاز پیدا شد، به جای محاسبه دوباره کافی است آن را بازیابی کنیم.

مراحل بسط یک الگوریتم برنامه نویسی پویا به شرح زیر است: 1- ارائه یک ویژگی بازگشتی برای حل نمونه ای از مسئله . 2- حل نمونه ای از مسئله به شیوه جزء به کل با حل نمونه های کوچک تر.

ضريب دوجمله اي با استفاده از تقسيم و حل فرمول مرسوم بدست آوردن ضريب دو جمله اي براي كليه مقادير n ≥ k ≥0 بصورت روبرو است: اما همانطور كه مشاهده مي كنيد، بدليل استفاده از عمل فاكتوريل ، حتي براي مقادير كوچك متغيرهاي k و n ، مقدار k! و يا n! بزرگ (و يا حتي بسيار بزرگ) خواهد بود. پس ما نمي توانيم ضريب دوجمله اي را مستقيماً از اين روش بدست آوريم.

ضريب دوجمله اي با استفاده از تقسيم و حل با استفاده از فرمول زير نياز به محاسبه ي n! و يا k! را به (n-1)! و يا (k-1)! تقليل مي دهيم. 0 < k < n K = 0 يا k = n همانطور كه ملاحظه مي كنيد، براي محاسبه ي اين عبارت، آن را به دو عبارت كوچكتر تبديل مي كنيم و به محاسبه ي آنها مي پردازيم. پس همانطور كه ملاحظه مي كنيد به الگوريتم تقسيم و حل مي رسيم.

ضريب دوجمله اي با استفاده از تقسيم و حل الگوريتم محاسبه ضريب دو جمله اي در اين روش با استفاده از متد بازگشتي بصورت زير مي باشد: int bin (int n, int k) { if (k == 0 || n == k) return 1; else return bin(n-1, k-1) + bin(n-1, k); } ورودي ها: اعداد صحيح و مثبت n و k هستند كه در آن k ≤ n است. خروجي ها: ضريب دو جمله اي n و k بصورت يك عدد صحيح.

ضريب دوجمله اي با استفاده از تقسيم و حل حال با استفاده از يك مثال به توضيح اين الگوريتم مي پردازيم. فرض كنيد قرار است با استفاده از اين الگوريتم ضريب دو جمله اي (2 ،4) را محاسبه كنيم. پس n = 4 و k = 2 خواهد بود، بنابراين تابع ما بصورت زير فراخواني خواهد شد: bin (4, 2) (بدليل استفاده از فراخواني هاي بازگشتي و درك موضوع، درخت اين سلسله فراخواني ها را ترسيم مي كنيم.)

ضريب دوجمله اي با استفاده از تقسيم و حل bin (4, 2) 6 bin (3,1) bin (3, 2) 3 3 bin (2, 0) bin (2, 1) bin (2, 1) bin (2, 2) 1 2 2 1 1 bin (1, 0) bin (1, 1) bin (1, 0) bin (1, 1) 1 1 1 1 1 1 1 1 1

ضريب دوجمله اي با استفاده از تقسيم و حل bin (4, 2) 6 bin (3,1) bin (3, 2) 3 3 bin (2, 0) bin (2, 1) bin (2, 1) bin (2, 2) 1 2 2 1 1 bin (1, 0) bin (1, 1) bin (1, 0) bin (1, 1) 1 1 1 1 1 1 1 1 1 اما همانطور كه مشاهده مي كنيد، در فراخواني هاي بازگشتي، تعدادي از نمونه ها چندين بار حل مي شوند و بطور جداگانه محاسبه مي شوند.

ضريب دوجمله اي با استفاده از تقسيم و حل هماننده آنچه مشاهده كرديد براي محاسبه bin(n-1, k-1) و bin(n-1, k) هر دو نياز به نتيجه ي bin(n-2, k-1) دارند و اين مورد در هر باز فراخواني به طور جداگانه اي محاسبه مي شود. پس در روش تقسيم و حل تا زماني كه نمونه به چند نمونه كوچكتر تقسيم شود كه آن نمونه ها تقريباً به بزرگي نمونه اوليه باشند، اين الگوريتم كارايي ندارد، آنچنانكه براي تعيين نياز به محاسبه ي جمله خواهد بود. حال با استفاده از الگوريتم پويا، الگوريتمي با كارايي بيشتر و بالاتر طراحي ميكنيم.

ضريب دوجمله اي با استفاده از برنامه نويسي پويا با استفاده از همان فرمولي كه در الگوريتم قبلي بيان كرديم: 0 < k < n K = 0 يا k = n اين بار با استفاده از برنامه نويسي پويا پياده سازي مي كنيم. با آرايه اي دو بعدي مثلاً با نام B كه B[i][j] مبين است. 0 < j < i j = i يا j = 0

ضريب دوجمله اي با استفاده از برنامه نويسي پويا مسئله را به شيوه ي جزء به كل حل كرده و به پيش مي رويم. سلولهاي آرايه را به ترتيب از سطر و ستونهاي كوچك شروع كرده و به جلو ميرويم، تا آنجا كه به B[n][k] كه همان است برسيم.

الگوریتم 2-3: ضریب دو جمله ای با استفاده از برنامه نویسی پویا int bin2 ( int n , int k ) { index i , j ; int B [0..n][0..k] for ( i = 0; i ≤ n ; i ++) if ( j == 0 || j == i ) B [i] [j] = 1; else B [i] [j] = B [ i – 1 ] [ j -1 ] + B [ i -1 ] [j]; return B[n] [k]: }

ضريب دوجمله اي با استفاده از برنامه نويسي پويا حال با ذكر يك مثال به توضيح اين الگوريتم نيز مي پردازيم. فرض كنيد بخواهيم ضريب دوجمله اي (4, 2) را اين بار با استفاده از اين الگوريتم بدست آوريم. همانطور كه مي دانيد: n = 4 و k = 2 B k n 1 2 3 4 1 B[0][0] = 1 B[1][0] = 1 B[4][2] = B[3][1]+B[3][2] = 3 + 3 = 6 B[2][1] = B[1][0]+B[1][1] = 1 + 1 = 2 B[3][0] = 1 B[2][2] = 1 B[2][0] = 1 B[1][1] = 1 B[3][1] = B[2][0]+B[2][1] = 1 + 2 = 3 B[3][2] = B[2][1]+B[2][2] = 2 + 1 = 3 B[4][0] = 1 B[4][1] = B[3][0]+B[3][1] = 1 + 3 = 4 1 1 1 2 1 1 3 3 1 4 6

ضريب دوجمله اي با استفاده از برنامه نويسي پويا همانطور كه مشاهده كرديد با استفاده از آرايه اي دو بعدي و الگوريتم برنامه نويسي پويا به حل مسئله پرداختيم. ديديم كه در اين روش برخلاف روش قبلي سربار اضافي نداشتيم (محاسبه ي مجدد موردهاي محاسبه شده) چرا كه اين الگوريتم جزء به كل بوده و براي محاسبه مقادير جديد مورد نياز، آنها را از مقادير قبلي بدست مي آورد. (نه آنكه مجدداً به محاسبه آنها از نو بپردازد) در نهايت به مقايسه ي كارايي دو الگوريتم مي پردازيم.

مقايسه الگوريتم هاي ضريب دوجمله اي همانطور كه قبلاً بيان شد، در الگوريتم تقسيم و حل، تعداد جملاتي كه الگوريتم براي تعيين محاسبه مي كند است. اين در حالي است كه تعداد كل گذرها در الگوريتم برنامه نويسي پويا با اثبات زير برابر خواهد بود. تعداد گذرها از حلقه j : 1+2+3+4+...+k+(k+1)+(k+1)+...+(k+1) پس: n-k+1 بار

الگوریتم فلوید نمونه سوال: یک مشکل متداول در سفرهای هوایی , هنگامی که پرواز مستقیم وجود نداشته باشد , تعیین کوتاه ترین مسیرپرواز از شهری به شهردیگر است. کوتاهترین مسیر بین جفت نودهای گراف

تعاریف حلقه: مسیری از خود راس به خودش مسیر ساده:اگرمسیری هیچگاه از دو راس نگذرد را مسیر ساده گویند. طول مسیر: در یک گراف وزن دارحاصل جمع وزن ها را گویند و در یک گراف بدون وزن تعداد رئوس موجود مسئله کو تاه ترین مسیر که یک مسئله بهینه سازی می باشد شامل موارد زیر است: از یک نود به نود دیگر از یک نود به تمامی نودها از تمامی نودها به همدیگر

روش محاسبه تمامی مسیرها فرض کنید از هر راس به همه رئوس دیگر یک یال وجود دارد در این صورت , زیر مجموعه ای از همه مسیر ها , عبارت از مجموعه ای خواهد بود که راس نخست شروع می شود و به راسی دیگر ختم می شود واز همه رئوس دیگر عبور می کنند. چون راس دوم در چنین مسیری می تواند هر یک از n-2 راس باشد, راس سوم در چنین مسیری می تواند هر یک ازn-3 راس باشد, ... وراس دومی به آخری روی چنین مسیری فقط می تواند یک راس باشد, تعداد کل مسیرها از یک راس که از همه رئوس دیگر بگذرد (n-2)(n-3)…1=(n-2)!

برنامه نویسی پویا و کوتاهترین مسیر با استفاده از برنامه نویسی پویا, یک الگوریتم زمانی درجه سوم برای این مسئله ایجاد می کنیم.

الگوریتم 3-3: الگوریتم فلوید برای یافتن کوتاه ترین مسیر void floyd ( int n const number W [][], number D [][], { index i , j , k ; D = W ; for ( k = 1 ; k ≤ n ; k ++) for ( i = 1; i ≤ n ; i++) for ( j = 1 ; j ≤ n ; j ++) D [i] [j] = minimum ( D [i][j], D[i][k] + D[k][j]); }

T (n) = n × n × n = n³ Є θ (n³) عمل اصلی: دستورهای موجود در حلقه for . تحلیل پیچیدگی زمانی در بدترین حالت برای ا لگوریتم3-3 (الگوریتم فلوید برای یافتن کوتاهترین مسیر) عمل اصلی: دستورهای موجود در حلقه for . اندازه ورودی:n ، تعداد رئوس گراف. T (n) = n × n × n = n³ Є θ (n³)

الگوریتم 4-3:الگوریتم فلوید برای یافتن کوتاهترین مسیر 2 void floyd2 ( int n, const number W [][], number D [][], index P [][]) { index i , j , k ; for ( i = 1 ; i ≤ n ; i ++) for ( j = 1 ; j ≤ n ; j++)

P [i] [j] = 0; D = W; for ( k = 1 ; k <= n ; k ++) for ( i = 1 ; i <= n ; i ++) for ( j = 1 ; j <= n ; j ++) if ( D [i] [k] + D [k] [j] < D [i] [j] ) { P [i] [j] = k; D [i] [j] = D [i] [k] + D [k] [j]; }

الگوریتم 5-3:چاپ کوتاهترین مسیر مسئله: چاپ رئوس واسطه روی کوتاه ترین مسیر از راسی به راس دیگر در یک گراف موزون. void path ( index q , r) { if (P [q] [r] != 0 ) { path (q , P [q] [r] ); cout << “v” << P [q] [r]; path (P [q] [r] , r ); }

3-3 برنامه نویسی پویا و مسائل بهینه سازی حل بهینه ، سومین مرحله از بسط یک الگوریتم برنامه نویسی پویا برای مسائل بهینه سازی است. مراحل بسط چنین الگوریتمی به شرح زیر است:

1- ارائه یک ویژگی بازگشتی که حل بهینه ی نمونه ای از مسئله را به دست می دهد. 2- محاسبه مقدار حل بهینه به شیوه ی جزء به کل. 3- بنا کردن یک حل نمونه به شیوه ی جزء به کل.

هر مسئله بهینه سازی را نمی توان با استفاده از برنامه نویسی پویا حل کرد چرا که باید اصل بهینگی در مسئله صدق کند. اصل بهینگی در یک مسئله صدق می کند اگریک حل بهینه برای نمونه ای از مسئله ، همواره حاوی حل بهینه برای همه ی زیر نمونه ها باشد.

ضرب زنجیره ای ماتریس ها ضرب دو ماتريس الگوريتم تحليل پيچيدگي زماني

ضرب دو ماتريس 2 1 3 4 5 6 * 7 8 9 4* 3 براي ضرب دو ماتريس فوق بايد هر سطر از ماتريس اول در ستونهاي ماتريس دوم ضرب شود و حاصل هر يك با هم جمع شود. 6*3+2*2+7*1 7*3+3*2+8*1 8*3+4*2+9*1 9*3+5*2+1*1 6*6+2*5+7*4 7*6+3*5+8*4 8*6+4*5+9*4 9*6+5*5+1*4 بنابراين ماتريس حاصلضرب يك ماتريس 4*2 است.

تعداد عمل ضرب بنابراين بطور كلي براي ضرب يك ماتريسي كه داراي I سطر و K ستون است در يك ماتريس با K سطر و J ستون تعداد اعمال ضرب به اين صورت است: A i*k * Bk*j  I * K * J

پرانتزگذاری متفاوت ضرب زنجیره ای ماتریسها ضرب ماتريسها مانند ضرب اعداد در رياضي داراي خاصيت شركت پذيري است. اگر تعدادي ماتريس داشته باشيم كه بين آنها علامت * است مي توان با استفاده از خاصيت شركت پذيري به شيوه هاي مختلف آنها را در هم ضرب كرد. براي مثال : مي خواهيم 4 ماتريس زير را در هم ضرب كنيم و سپس تعداد اعمال ضرب را در هر حالت به دست آوريم : A * B * C * D 20*2 2*30 30*12 12*8 A (B (CD) تعداد اعمال ضرب: 30*8*12 + 2*8*30 + 20*8*2 = 3680 (AB)(CD) تعداد اعمال ضرب: 20*30*2 + 30*8*12 + 20*8*2 = 8880 A ( (BC) D) تعداد اعمال ضرب: 2*12*30 + 2*8*12 + 20*8*2 = 1232 ((AB)C)D تعداد اعمال ضرب: 20*30*2 + 20*12*30 + 20*8*12 = 10320 (A(BC))D تعداد اعمال ضرب: 2*12*30 + 20*12*2 + 20*8*12 = 3120

بررسی تمام حالات هدف: الگوريتمي داشته باشيم كه براي Nماتريس ترتيب بهينه را پيدا كند همانطور كه ملاحظه شد ترتيب بهينه فقط به ابعاد ماتريسها بستگي دارد. بنابراين ورودي الگوريتم N (تعداد ماتريسها) وابعاد ماتريسها D است. معايب اين الگوريتم: اين الگوريتم غير هوشمند است زيرا حداقل بصورت نمايي خواهد بود. توضيح:فرض كنيد Tnتعداد ترتيبهاي متفاوت براي ضرب N ماتريس A1,A2,A3,…,An زير مجموعه اي از ترتيب ها A1(A2 A3…An) و (A1A2 A3…)An و .... Tn>=Tn-1 + Tn-1 T2=1

برنامه نویسی پویا-مثال 6 ماتريس زير را ميخواهيم در هم ضرب كنيم: A1 * A2 * A3 * A4 * A5 * A6 5*2 2*3 3*4 4*6 6*7 7*8 D= [ 5 2 3 4 6 7 8] براي ضرب A4 تا A6 دو ترتيب زير را داريم: 1: (A4 A5) A6 = D3*D4*D5 + D3*D5*D6= 4*6*7+4*7*8 = 392 2: A4 (A5 A6) = D4*D5*D6 + D3*D4*D6= 6*7*8+4*6*8 = 528 M[4][6] = Min(392,528) = 392

ضرب زنجیره ای مجموعه ماتريسهاي زير را در نظر بگيريد: A1*A2*…*Ai*…*Aj*…*An منظور از M[i][j] حداقل تعداد ضرب براي ماتريسهاي iام تا jام است بشرطی که i<j يك ماتريس بالا مثلثي است M[i][i]=0 M[i][i+1]=di-1*di*di+1

مثال 2 3 4 5 6 7 8 d0 d1 d2 d3 d4 d5 d6 d 1 2 3 4 5 6 30 M[2][3]=?

مثال در اين صورت دو ترتيب براي ضرب وجود خواهد داشت: 1: (A1 A2)(A3) همانطور كه در قبل اشاره كرديم حداقل تعداد ضرب دو ماتريس را با M[1][3] بيان مي كنيم. 1: (A1*A2) * (A3) = A1 * A2 * A3 M[1][2] + M[3][3]+ d0*d1*d2 2: (A1) * (A2*A3) = A1 * A2 * A3 M[1][1] + M[2][3] + d0*d1*d2

مثال حال در واقع داريم : 1: M[1][2] + M[3][3] + d0*d2*d3 = 30 + 4 + 5*3*4 =94 2: M[1][1] + M[2][3] + d0*d1*d3 = 0 + 24 + 5*2*4 =64 بايد بين دوترتيب فوق مينيمم بگيريم . مقدار مينيمم در M[1][3] قرار ميگيرد. M[1][3]= 64 در اينصورت براي بدست آوردن درايه M[i][j]از فرمول زير استفاده ميكنيم : M[i][j] = Minimum (M[i][k] + M[k+1][j] + di-1 dk dj) به شرطي كه : و داريم: i<j , i<=k<=j-1 M[i][j]=0

مثال 2 3 4 5 6 7 8 d0 d1 d2 d3 d4 d5 d6 d 1 2 3 4 5 6 30 64 132 226 348 24 72 156 268 198 366 168 392

الگوریتم 6-3: حداقل ضرب ها int minimult ( int n,const int d [],index P [][] ){ index i , j , k , diagonal; int M [1..n] [1..n]; for ( i = 1 ; i ≤ n ; i ++) M [i] [i] = 0:

for (diagonal = 1; diagonal ≤ n -1 ; diagonal ++) for ( i = 1 ; i ≤ n – diagonal ; i ++) { j = i + diagonal ; M[i][j] = minimum (M[i][k] + M[k +1 ][j] + d [ i – 1] * d [k] * d [j]); i<=k<j P [i][j] = a value of k that gave the minimum; } return M[1][n];

تحليل پيچيدگي زماني n-1 [(n-diagonal) * diagonal] diagonal=1 n(n-1)(n+1) 6 N ^ 3

تحلیل پیچیدگی زمانی حالت معمول برای ا لگوریتم6-3( حداقل ضرب ها) تحلیل پیچیدگی زمانی حالت معمول برای ا لگوریتم6-3( حداقل ضرب ها) عمل اصلی: می توان دستورات اجرا شده برای هر مقدار k را عمل اصلی در نظر بگیریم. مقایسه ای را که برای آزمون حداقل انجام می شود، به عنوان عمل اصلی در نظر می گیریم. اندازه ورودی: n ، تعداد ماتریس ها که باید ضرب شوند. N (n -1) (n + 1) / 6 Є θ (n³)

الگوریتم 7-3: چاپ ترتیب بهینه مسئله: چاپ ترتیب بهینه برای ضرب n ماتریس. void order ( index i, index j) { if ( i == j) cout << “A” << i ; else { k = P [i] [j]; cout << “(“; order ( i , k); order ( k +1 , j ); cout << “)”; }

5-3 درخت های جست و جوی دودویی بهینه درخت جست و جوی دودویی یک دودویی از عناصر( که معمولا کلید نامیده می شوند)است که از یک مجموعه مرتب حاصل می شود، به قسمی که: 1- هر گره حاوی یک کلید است.

2- کلید های موجود در زیردرخت چپ یک گره مفروض، کوچک تر یا مساوی کلید آن گره هستند. 3- کلیدهای موجود درزیردرخت راست یک گره مفروض، بزرگ تر یا مساوی کلید آن گره هستند.

الگوریتم 8-3: درخت جست و جوی دودویی void search ( node _ pointer tree , keytype keyin, node _ poiner & p) { bool found ; p = tree; found = false; while (! found)

if ( p - > key == keyin ) found = true ; else if ( keyin < p - > key ) p = p -> left ; else p = p - > right ; }

الگوریتم 9-3 : درخت جست و جوی بهینه مسئله: تعیین یک درخت جست وجوی بهینه برای مجموعه ای از کلید ها، هر یک با احتمالی مشخص. void optsearchtree ( int n , const float p[]; float & minavg, index R[][]) { index i , j , k , diagonal ;

float A [1..n + 1] [0..n]; for ( i = 1 ; i ≤ n ; i ++) { A [i] [i -1] = 0 A [i] [i] = p [i]; R [i] [i] = i ; R [i] [ i – 1 ] = 0; } A[ n + 1 ] [n] = 0 ; R[ n + 1 ] [n] = 0 ;

for (diagonal = 1;diagonal ≤ n – 1; diagonal++) for ( i = 1; i ≤ n – diagonal ; i ++) { j = i + diagonal ; A[i][j] = minimum(A[i][k-1]+A[k+1][j])+∑pm R[i][j] = a value of k that gave the minimum; } minavg = A [1][n];

تحلیل پیچیدگی زمانی حالت معمول برای ا لگوریتم درخت جستجوی دودویی بهینه عمل اصلی: دستورات اجرا شده به ازای هر مقدار از k .این دستورات شامل یک مقایسه برای آزمون حداقل است. اندازه ورودی: n ، تعداد کلید. T(n) = n ( n -1) ( n + 4 ) / 6 Є θ ( n³ )

الگوریتم 10 -3: ساخت درخت جست و جوی دودویی بهینه node _ pointer tree ( index i , j ) { index k ; node _ pointer p ; k = R [i] [j]; if ( k == 0 ) return NULL; else {

p = new nodetype ; p - > key = key [k] ; p - > left = tree (i , k – 1); p - > right = tree ( k+1 , j); return P; }

الگوریتم11-3:الگوریتم برنامه نویسی پویا برای مسئله فروشنده دوره گرد void tarvel ( int , n const number W[ ][ ] , index P[ ] [ ] , number & minlength) { index i , j , k ; number D[1..n][subset of V - { v1 } ] ; for ( i = 2 ; i ≤ n ; i ++)