המצגת נטענת. אנא המתן

המצגת נטענת. אנא המתן

מבוא למדעי המחשב 2019 תרגול 13 Graphs 1.

מצגות קשורות


מצגת בנושא: "מבוא למדעי המחשב 2019 תרגול 13 Graphs 1."— תמליל מצגת:

1 מבוא למדעי המחשב 2019 תרגול 13 Graphs 1

2 ראינו בהרצאה מחלקות אבסטרקטיות גרפים:
GraphAsAdjacencyMatrix– ייצוג ע"י מטריצת שכנויות. GraphAlgorithm: EvenDegreesAlgorithm ConnectivityAlgorithm

3 בתרגול היום Graphs GraphAsAdjacencyList שאלות ממבחנים מחסנית: 45 דק'
תזכורת 5 דק' בדיקת איזון סוגריים: מימוש פשוט 10 דק' פתרון כללי 10 דק' מימוש תור באמצעות מחסנית 20 דק' גרפים: 50 דקות: הגדרות + תזכורת על הממשק והמחלקות שראו 10 דקות. מחלקה אבסטרקטית ו-Edge – 10 דקות. GraphAsAdjacencyList – 10 דקות. שאלה ממבחן(סעיפים א,ב) – 20 דקות.

4 Graphs

5 הגדרה גרף הוא זוג סדור 𝑮= 𝑽,𝑬 כאשר
גרף הוא זוג סדור 𝑮= 𝑽,𝑬 כאשר 𝑉 קבוצה של קודקודים (n = מספר הקודקודים בגרף) 𝑬⊆𝑽×𝑽 קבוצה של קשתות. למשל: 𝑉= 0,1,2,3 𝐸={ 1, 2 , 1, 3 , 2, 3 , {0, 3}} אנחנו נניח שקבוצת הקודקודים מיוצגת (תמיד) כך: 𝑉={0,1,…,𝑛−1} מבוא למדעי המחשב 2019 ©

6 מושגים: קבוצת השכנים של קודקוד – קבוצת השכנים של קודקוד v הם כל הקודקודים שקיימת צלע שמחברת ביניהם לבין v. דרגה (degree) של קודקוד – נגדיר דרגה של קודקוד להיות מספר השכנים שלו בגרף. 1 {2,3} degree(0) = ? neighbors(1) = ?

7 מושגים: קבוצת השכנים של קודקוד – קבוצת השכנים של קודקוד v הם כל הקודקודים שקיימת צלע שמחברת ביניהם לבין v. דרגה (degree) של קודקוד – נגדיר דרגה של קודקוד להיות מספר השכנים שלו בגרף. 1 {2,3} עד כאן 3 דקות. degree(0) = 1 neighbors(1) = {2,3}

8 גרפים: ייצוג קשתות public class Edge { private int left ; private int right ; public Edge(int left, int right) { this.left = left ; this.right = right ; } public int getLeft() { return left; } public int getRight() { return right; } public boolean isEndpoint(int i) { return i == left | i == right ; } public int[] toArray() { return new int[] {left, right} ; } public String toString() { return "{" + left + ", " + right + "}" ; } public boolean equals(Object other) { if(!(other instanceof Edge)) return false ; Edge otherEdge = (Edge)other ; /* * why do we need min and max? * - remember that edges are undirected * so GraphEdge(1,2,3) == GraphEdge(2,1,3) */ int thisMin = Math.min(this.left, this.right) ; int thisMax = Math.max(this.left, this.right) ; int otherMin = Math.min(otherEdge.left, otherEdge.right) ; int otherMax = Math.max(otherEdge.left, otherEdge.right) ; return thisMin == otherMin & thisMax == otherMax ; } 5 דקות לשקף זה ראו בהרצאה רק בנאי ושדות, אפשר לעבור בזריזות על השיטות, להתעכב על זה שבגלל שהגרף לא מכוון. נוכל להחליט כי תמיד נייצג קשת כך ש left<right להסביר את ה-equals. מבוא למדעי המחשב 2019 ©

9 גרפים: הממשק Graph public interface Graph {
public int numberOfVertices() ; public int numberOfEdges() ; public boolean containsEdge(int i, int j) ; public void addEdge(int i, int j) ; public void removeEdge(int i, int j) ; public int degree(int v) ; public Set<Integer> neighborsOf(int v) ; public Set<Edge> edgeSet() ; } תזכורת – ראו בהרצאה. בשקף הבא תזכורת על מחלקה אבסטרקטית שמממשת את הממשק הזה יחד עם הסבר על מחלקה אבסטרקטית. מבוא למדעי המחשב 2019 ©

10 public abstract class AbstractGraph implements Graph { final private int nVertices ; public AbstractGraph(int nvertices) {} public int numberOfVertices() {} public int numberOfEdges() {} public int degree(int v) {} public Set<Integer> neighborsOf(int v) {} public Set<Edge> edgeSet() {} protected boolean rangeCheck(int i, int j) {} protected boolean rangeCheck(int i) {} public String toString() {} public boolean equals(Object other) {} public abstract boolean containsEdge(int i, int j); public abstract void addEdge(int i, int j); public abstract void removeEdge(int i, int j); } מוטיבציה. למה מחלקה אבסטרקטית: נוכל לממש חלק ניכר מהממשק הכל במונחים של פעולות הממשק ורק את הנותר במחלקות המרחיבות. מחלקות מופשטות הן פתרון ביניים בין מחלקות רגילות, בהן כל השיטות ממומשות, לבין ממשקים בהם אף שיטה אינה ממומשת. מחלקה היורשת ממחלקה אבסטרקטית חייבת למממש את השיטות האבסטרקטיות שלה. כל מחלקה בה לפחות אחת השיטות היא מופשטת חייבת להיות מוכרזת כמופשטת בעצמה. ההיפך אינו נכון. ניתן להכריז על מחלקה כעל מחלקה מופשטת למרות שכל השיטות בה ממומשות. הסבר על מחלקה אבסטרקטית בקצרה(ראו בהרצאה) 5 דקות לשקף זה. מדוע שנרצה לעשות כזה דבר? ייתכן מצב בו אנו רוצים לספק קוד עבור טיפול באובייקט מופשט, אך אין משמעות לקיום של אובייקט כזה בפני עצמו. לדוגמה, פריט במכירה ברשת. איננו מוכרים פריט לעולם. אנו מוכרים טלוויזיות, מחשבים פרחים ויין, אך לא מוכרים פריטים. למרות זאת, היינו מעונינים לתכנת את כל הקוד המשותף לכל הפריטים (טיפול במלאי, קוד פריט, שינוי מחיר) ורק אח"כ לרשת ע"י מחלקה יורשת גשמית כגון טלוויזיה. המחלקה המייצגת פריט לא חייבת לכלול שיטה מופשטת בשביל להיות מחלקה מופשטת. שיטות אבסטרקטיות

11 גרפים: מימוש הממשק Graph
Interface בהרצאה ראיתם מימוש גרף ע"י מטריצת שכנויות: AbstractGraph AbstractClass true false תזכורת למימוש אותו ראו בהרצאה GraphAsAdjacencyMatrix private boolean[][] edges ; class מבוא למדעי המחשב 2019 ©

12 גרפים: מימוש הממשק Graph
Interface היום נראה מימוש נוסף, באמצעות רשימת שכנויות: AbstractGraph AbstractClass GraphAsAdjacencyMatrix boolean[][] edges ; GraphAsAdjacencyList List<List<Integer>> לציין שעכשיו נראה מימוש נוסף. class class מבוא למדעי המחשב 2019 ©

13 ייצוג של גרף כרשימת שכנויות
נייצג כל קשת פעם אחת בלבד: (i , j) i < j 3 3 1 2 3 1 2 3 הסבר על הייצוג – אין כפילויות לחסכון מקום. כאן הם צריכים להבין שאנחנו הולכים להשתמש ברשימה של רשימות למימוש הגרף להגיע איתם למסקנה הזאת. עד השקף הזה 20 דקות כולל. 2 1 3 2 3 3 1 2 3 מבוא למדעי המחשב

14 GraphAsAdjacencyList
public class GraphAsAdjacencyList extends AbstractGraph { private List<List<Integer>> adj ; public GraphAsAdjacencyList(int nVertices) { super(nVertices); this.adj = new LinkedList<>(); for(int i = 0; i < nVertices; i = i + 1) adj.add(new LinkedList<Integer>()); } public GraphAsAdjacencyList(Graph other) { this(other.numOfVertices()); for(int i = 0; i < other.numOfVertices(); i = i + 1){ for(int j = i + 1; j < other.numOfVertices(); j = j + 1){ if(other.containsEdge(i, j)) addEdge(i, j); private Edge toEdge(int i, int j) { return new Edge(Math.min(i, j), Math.max(i, j)); public String toString() { String output = ""; for(int i = 0 ; i < numberOfVertices(); i = i+1) output = output + i + "-" + adj.get(i) + "\n"; return output; } 10 דקות להצגת המימוש, להוציא מהסטודנטים – איזה שיטות לממש (יורש ממחלקה אבסטרקטית) מה חסר לנו במימוש? מימוש השיטות האבסטרקטיות. מבוא למדעי המחשב 2019 ©

15 דוגמת שימוש דוגמא: public static void main(String[] args) {
Graph graph = new GraphAsAdjacencyList(4); graph.addEdge(0, 3); graph.addEdge(1, 2); graph.addEdge(1, 3); graph.addEdge(2, 3); graph.containsEdge(1, 3); graph.containsEdge(0, 1); } //true דוגמת שימוש, אפשר לדלג. //false נסו בעצמכם עוד דוגמאות בבית!

16 GraphAsAdjacencyList
מימוש השיטות האבסטרקטיות: containsEdge public class GraphAsAdjacencyList extends AbstractGraph { ... public boolean containsEdge(int i, int j) { Edge e = toEdge(i,j); List<Integer> leftNeighbors = adj.get(e.getLeft()); return leftNeighbors.contains(e.getRight()); } 10 דקות להצגת המימוש, להוציא מהסטודנטים – איזה שיטות לממש (יורש ממחלקה אבסטרקטית) לצייר דוגמא פשוטה על הלוח במעבר על כל שיטה כדי שלא יאבדו את זה, להזכיר בגישה לנתונים - יש לנו רשימה של רשימות. מבוא למדעי המחשב 2019 ©

17 GraphAsAdjacencyList
מימוש השיטות האבסטרקטיות: addEdge public class GraphAsAdjacencyList extends AbstractGraph { ... public void addEdge(int i, int j) { Edge e = toEdge(i, j); if(!containsEdge(e.getLeft(), e.getRight())){ List<Integer> leftNeighbors = adj.get(e.getLeft()); leftNeighbors.add(e.getRight()); } .... 10 דקות להצגת המימוש, להוציא מהסטודנטים – איזה שיטות לממש (יורש ממחלקה אבסטרקטית) לצייר דוגמא פשוטה על הלוח במעבר על כל שיטה כדי שלא יאבדו את זה, להזכיר בגישה לנתונים - יש לנו רשימה של רשימות. מבוא למדעי המחשב 2019 ©

18 GraphAsAdjacencyList
מימוש השיטות האבסטרקטיות: removeEdge public class GraphAsAdjacencyList extends AbstractGraph { ... public void removeEdge(int i, int j) { Edge e = toEdge(i, j); if(containsEdge(e.getLeft(), e.getRight())){ List<Integer> leftNeighbors = adj.get(e.getLeft()); leftNeighbors.remove(e.getRight()); } 10 דקות להצגת המימוש, להוציא מהסטודנטים – איזה שיטות לממש (יורש ממחלקה אבסטרקטית) לצייר דוגמא פשוטה על הלוח במעבר על כל שיטה כדי שלא יאבדו את זה, להזכיר בגישה לנתונים - יש לנו רשימה של רשימות. מבוא למדעי המחשב 2019 ©

19 שאלה ממועד ב 2017 בשאלה זו נעסוק בגרפים. נתונה לכם המחלקה Edge המייצגת קשת בגרף, והמחלקה האבסטרקטית GraphAlgorithm כפי שנלמדו בכיתה. public class Edge { private int left ; private int right ; public Edge(int left, int right) { this.left = left; this.right = right { public getLeft() { return left; public getRight() { return right; שיטות נוספות שאינן חשובות למבחן // } abstract public class GraphAlgorithm { protected Graph input ; public GraphAlgorithm(Graph input) { this.input = input ; } abstract public Object runAlgorithm(); } עד כאן 30 דקות(לא כולל) שאלה ממבחן – בשאלה הרבה מלל והיא כוללת 3 סעיפים, לדעתי אי אפשר להספיק ב-20 דקות. לכן שני הסעיפים הראשונים נעביר אנחנו, כתבתי שסעיף ג' כתרגיל בית. מי שיספיק מעולה. אפשר גם לעשות אותו בתחילת התרגול הבא או לנהל עליו דיון קצר.(השעה הראשונה בתרגול 13 גם בנושא של גרפים והם יראו שאלה נוספת ממבחנים). מבוא למדעי המחשב 2019 ©

20 שאלה ממועד ב 2017 בנוסף, נתונה המחלקה MysteryGraph, המממשת את הממשק Graph. בנאי המחלקה MysteryGraph יוצר גרף שקבוצת הקשתות שלו ריקה. הבנאי מקבל פרמטר יחיד מטיפוס int אשר מציין את מספר הקודקודים שבגרף המאותחל. בשאלה זו שלושה סעיפים שבהם תשלימו שתי מחלקות היורשות את המחלקה GraphAlgorithm. הערה: בשאלה זו יש להניח קלט תקין בכל הסעיפים ואין צורך לבדוק תקינות של פרמטרים. להלן תיאור המחלקה HasPathAlgorithm אותה תשלימו בסעיפים א' ו- ב'. המחלקה מתארת אלגוריתם אשר בהנתן גרף ושני קודקודים מציין האם קיים מסלול בגרף בין שני הקודקודים. בנאי המחלקה מקבל שלושה פרמטרים: גרף ושני קודקודים המיוצגים על ידי שני מספרים מטיפוס int. מבוא למדעי המחשב 2019 ©

21 שאלה ממועד ב 2017 public class HasPathAlgorithm extends GraphAlgorithm { private int vertex1, vertex2; public HasPathAlgorithm(Graph input, int vertex1, int vertex2){ super(input); this.vertex1 = vertex1; this.vertex2 = vertex2; } public void dfsVisit(int vertex, boolean[] visited){ סעיף א' – השלימו בדף התשובות // } public Object runAlgorithm() { boolean[] visited; סעיף ב' – השלימו בדף התשובות // } מבוא למדעי המחשב 2019 ©

22 שאלה ממועד ב 2017 סעיף א: (5 נקודות)
השלימו במחלקה HasPathAlgorithm את השיטה void dfsVisit(int vertex, boolean[] visited). השיטה מקבלת שני פרמטרים: vertex – מספר המייצג קודקוד בגרף הקלט. visited - מערך בוליאני שגודלו כמספר הקודקודים בגרף הקלט. קריאה לשיטה dfsVisit(i,visited) כאשר i קודקוד בגרף, ו- visited מערך שכל הערכים בו false תסתיים כאשר לכל קודקוד j בגרף, הערך visited[j] שווה ל-true אם ורק אם יש מסלול בגרף בין הקודקוד i לקודקוד j. במילים אחרות, השיטה מבצעת "טיול" בגרף החל מהקודקוד i ומסמנת, בהצבת הערך true, במערך visited באלו קודקודים ביקרה. בפרט, הערך visited[i] יהיה true. מומלץ לכתוב פתרון רקורסיבי. הניחו כי הקלט תקין: המערך visited שונה מ- null, אורכו כמספר הקודקודים בגרף והתאים שבו מאותחלים עם ערכי false. מבוא למדעי המחשב 2019 ©

23 שאלה ממועד ב 2017 דוגמה: בהנתן הגרף G, שבאיור משמאל, שבו שבעה קודקודים, קטע הקוד הבא: HasPathAlgorithm hpa = new HasPathAlgorithm(G,1,2); boolean[] visited = new boolean[7]; hpa.dfsVisit(3, visited); for (boolean b : visited) System.out.print(b + " "); System.out.println; ידפיס את השורה: false false false true true true false  שכן טיול שמתחיל בקודקוד 3 מבקר (רק) בקודקודים 3,4,5. שימו לב שבקטע קוד זה הסתמכנו על העובדה שב-java מערך בוליאני מאותחל בערכי ברירת המחדל false. מבוא למדעי המחשב 2019 ©

24 שאלה ממועד ב 2017 פתרון סעיף א:
public class HasPathAlgorithm extends GraphAlgorithm { private int vertex1, vertex2; public HasPathAlgorithm(Graph input, int vertex1, int vertex2){ super(input); this.vertex1 = vertex1; this.vertex2 = vertex2; } private void dfsVisit(int vertex, boolean[] visited){ visited[vertex] = true; Set<Integer> vAdj = input.neighborsOf(vertex); for(Integer v : vAdj){ if(!visited[v]){ dfsVisit(v, visited); } מבוא למדעי המחשב 2019 ©

25 שאלה ממועד ב 2017 סעיף ב': (10 נקודות)
סעיף ב': (10 נקודות) השלימו במחלקה HasPathAlgorithm את השיטה runAlgorithm(). הקלט לאלגוריתם הוא גרף ושני קודקודים השמורים בשדות המחלקה. הפלט מוחזר כערך מהטיפוס Boolean שמציין האם קיים מסלול בגרף בין שני הקודקודים. דוגמה: בהנתן הגרף G שבאיור משמאל, קטע הקוד הבא: GraphAlgorithm ga1 = new HasPathAlgorithm(G, 2, 1); System.out.println(ga1.runAlgorithm()); // true יודפס GraphAlgorithm ga2 = new HasPathAlgorithm(G, 6, 4); System.out.println(ga2.runAlgorithm()); // false יודפס מבוא למדעי המחשב 2019 ©

26 שאלה ממועד ב 2017 פתרון סעיף ב:
private void dfsVisit(int vertex, boolean[] visited){ visited[vertex] = true; Set<Integer> vAdj = input.neighborsOf(vertex); for(Integer v : vAdj){ if(!visited[v]){ dfsVisit(v, visited); } public Object runAlgorithm() { boolean[] visited = new boolean[input.numberOfVertices()]; dfsVisit(vertex1, visited); return visited[vertex2]; אם במבחן לא מצליחים את סעיף א' אבל מבינים איך להשתמש בו, אין סיבה לא לפתור את סעיף ב'. מבוא למדעי המחשב 2019 ©

27 שאלה ממועד ב 2017 סעיף ג – תרגיל בית הגדרה עבור סעיף ג:
בהנתן גרף קשיר G, גרף G' המוגדר על אותם הקודקודים ובו חלק או כל הקשתות של G כך שמתקיימים התנאים הבאים: הגרף G' קשיר. אין בגרף G' מעגלים. לגרף G' כזה נקרא גרף מקשר של G. עובדה מתמטית: לכל גרף קשיר קיים גרף מקשר. דוגמאות: הגרף G1 (באיור) קשיר ויש בו מעגלים (קשתות המעגלים מודגשות). הגרפים G2 ו- G3 הם גרפים מקשרים של G1. הגרף G4 אינו גרף מקשר כי יש בו מעגל. מבוא למדעי המחשב 2019 ©

28 שאלה ממועד ב 2017 להלן תיאור המחלקה ConnectingGraph אותה תשלימו בסעיף ג'. המחלקה מממשת אלגוריתם אשר בהינתן גרף קשיר מחזיר גרף מקשר שלו (ראו הגדרה לעיל). public class ConnectingGraph extends GraphAlgorithm{ public ConnectingGraph(Graph input) { super(input); } public Object runAlgorithm() { Graph outputGraph = new MysteryGraph(input.numberOfVertices()); סעיף ג' – השלימו בדף התשובות // return outputGraph; } מבוא למדעי המחשב 2019 ©

29 שאלה ממועד ב 2017 סעיף ג': (10 נקודות)
השלימו את השיטה Object runAlgorithm(). הקלט לאלגוריתם הוא גרף קשיר השמור בשדה input (אין צורך לבדוק קשירות). הפלט של האלגוריתם הוא גרף מקשר של הקלט . הדרכה: השיטה runAlgorithm() תבצע מעבר על קשתות גרף הקלט ותוסיף חלק מהן לגרף הפלט. בכל שלב, כשנשקול האם להוסיף קשת (u,v)של גרף הקלט לגרף הפלט נבדוק תחילה האם כבר קיים מסלול בין הקודקודים u ו-v בגרף הפלט. אם קיים מסלול כזה בגרף הפלט אז הוספת הקשת (u,v)לגרף הפלט תיצור בו מעגל. נוסיף לגרף הפלט את הקשת (u,v) רק במקרה שהיא לא יוצרת מעגל בגרף הפלט. יש לבצע מעבר על קשתות גרף הקלט ולכל קשת (u,v)ליצור מופע חדש של אובייקט מטיפוס HasPathAlgorithm בעזרת הפקודה GraphAlgorithm hpa = new HasPathAlgorithm(outputGraph, u, v) ולהשתמש ב-hpa על מנת לבדוק האם להוסיף את הקשת (u,v). מבוא למדעי המחשב 2019 ©

30 שאלה ממועד ב 2017 פתרון סעיף ג: public Object runAlgorithm() {
Graph outputGraph = new MysteryGraph(input.numberOfVertices()); GraphAlgorithm hpa; //HasPathAlgorithm Set<Edge> edges = input.edgeSet() for(Edge e: edges){ int vertex1 = e.getLeft(); int vertex2 = e.getRight(); hpa = new HasPathAlgorithm(outputGraph, vertex1, vertex2); if(!(Boolean)hpa.runAlgorithm()){ outputGraph.addEdge(vertex1, vertex2); } return outputGraph; מבוא למדעי המחשב 2019 ©

31 הפסקה

32 שאלה ממועד ג 2017 הסעיף הזה הוא בדיוק כמו isPermutation שהיה להם בעבודה 2 ובבוחן, רק הפעם עם רשימה. הסטודנטים אמורים להרגיש איתו בנח אז אפשר לעבור עליו יותר בזריזות.

33 שאלה ממועד ג 2017 פתרון סעיף א:
public static boolean containsNVertices(List<Integer> numbers, int n){ if (n < 0 || numbers.size()!=n) return false; int[] count = new int[n]; for (int i=0; i<n; i=i+1) count[i] = 0; for (Integer num: numbers){ if (num<0 || num>=n) count[num] = count[num] + 1; } for (int i=0; i<n; i=i+1){ if (count[i]!=1) return true; פתרון סעיף א: אפשר לדון עם הסטודנטים: איך ניתן לפתור עם מערך בוליאני?

34 שאלה ממועד ג 2017 פתרון נוסף:
public static boolean containsNVertices(List<Integer> numbers, int n){ if (n < 0 || numbers.size()!=n) return false; boolean[] tmp = new boolean[n]; for (int i=0; i<n; i=i+1) tmp[i] = false; for (Integer num: numbers){ if (num<0 || num>=n || tmp[num]) tmp[num] = true; } return true; פתרון נוסף: אפשר לדון עם הסטודנטים: איך ניתן לפתור עם מערך בוליאני?

35 שאלה ממועד ג 2017

36 שאלה ממועד ג 2017

37 שאלה ממועד ג 2017 s

38 שאלה ממועד ג 2017 פתרון סעיף ב: public Object runAlgorithm() {
int n = vertices.size(); if(n > 1){ Iterator<Integer> iter = vertices.iterator(); int v2 = iter.next(); int v1; while(iter.hasNext()){ v1 = v2; v2 = iter.next(); if(!input.containsEdge(v1, v2)) return false; } return true; לתת לסטודנטים לפתח את האלגוריתם. אם הסטודנטים לא מציעים פתרון כזה (שבו הדבר הראשון זה בודקים אם n>1) לזרום איתם, ואז לשאול אותם אם הפתרון שהציעו מתאים גם עבור מקרי הקצה (n=0,1). לפעמים יותר קל לחשוב קודם על מקרה כללי, בלי מקרי הקצה, ואז לבדוק אם חסר טיפול במקרים האלה. לפעמים נגיע למסקנה שהקוד שכתבנו עובד גם עבור מקרי הקצה, אחרת נוסיף שינויים קלים כדי שיעבוד גם עבורם. נקודה נוספת: אחד הדברים שהכי מבלבל סטודנטים בשאלות האלה זה כל הארכיטקטורה (איפה השיטה הזו כתובה? איך זה קשור למחלקה/ממשק גרף? האם המחלקה הזו היא סוג של גרף?). צריך כל הזמן לפקס אותם על העניין הזה, ולהזכיר שאנחנו במחלקה שמייצגת אלג' על גרפים, ושלמחלקה הזאת יש שדה שהוא גרף, ועוד שדות נוספים שהאלג' זקוק להם. זה אומר שכשאנחנו רוצים לשאול משהו על הגרף, אנחנו יכולים להפעיל עליו את כל שיטות הממשק, מעבר לזה אנחנו לא יודעים דבר על הגרף, בטח שלא יודעים איך הוא ממומש ובטח שאין לנו גישה לשדות שלו.

39 שאלה ממועד ג 2017 אפשר לציין פה שזה בדיוק "בעיית הטיול הגדול" מעבודה 2 אם רוצים.

40 שאלה ממועד ג 2017

41 שאלה ממועד ג 2017 פתרון סעיף ג: public Object runAlgorithm() {
int n = input.numberOfVertices(); boolean isPath = false; if(Q4.containsNVertices(vertices, n)){ GraphAlgorithm ipa = new IsPathAlgorithm(input, vertices); isPath = (Boolean)ipa.runAlgorithm(); } boolean isCycle = (n >= 3 && isPath && input.containsEdge(vertices.get(vertices.size()-1), vertices.get(0))); return (isPath & isCycle); אפשר לפתור אחרת, אבל חשוב שהסטודנטים ידעו לעבוד עם משתנים בוליאנים ונקודת יציאה אחת מהפונקציה, כי לפעמים זו הדרישה במבחן. כמו כן, יש פה יצירה של מופע של המחלקה isPathAlgorithm, דבר שגם הרבה פעמים נראה תמוה אצל הסטודנטים. להדגיש את זה – אנחנו רוצים להשתמש בסעיף ב' כדי לדעת אם מערך הקודקודים הוא מסלול בגרף, איך נעשה את זה? נייצר מופע של המחלקה שמייצגת אלג' למציאת מסלול בגרף, ועל המופע נפעיל את השיטה runAlgorithm. לשאול את הסטודנטים גם מה צריך להעביר לבנאי של המחלקה isPathAlgorithm בעת יצירת המופע.

42 מועד א 2016 public interface Comparable<T>{
public class Student implements Comparable<Student>{ private int id; private String name; private int grade; public Student(int id, String name, int grade){ this.id=id; this.name=name; this.grade=grade; } public int getGrade(){ return grade; public int compareTo(Student o) {...} public interface Comparable<T>{ public int compareTo(T o); } לא חובה להספיק את זה

43 מועד א 2016 סעיף א (5 נקודות) השלימו במחלקה Student את השיטה compareTo כך שתשווה בין שני סטודנטים – בין this לבין other (הפרמטר של השיטה) – על פי הציון (grade) שלהם. public int compareTo(Student o){ return getGrade()-o.getGrade(); }

44 מועד א 2016 public class PassingStudentsIterator implements Iterator<Student>{ private Link<Student> curr; private int threshold; public PassingStudentsIterator (Link<Student> first, int threshold){ ... } public Student next() { ... } public boolean hasNext() { ... } } להלן המחלקה PassingStudentIterator המחלקה מגדירה Iterator עבור סטודנטים שהציון שלהם גדול או שווה לאיזשהו ערך סף-מינימלי, threshold, למשל 85. הסטודנטים נתונים באמצעות רשימה מקושרת (כפי שהוגדר בשאלה) שעשויה להכיל גם סטודנטים שציונם נמוך מערך הסף-המינימאלי הנתון. המחלקה מגדירה בנאי פשוט שמקבל כפרמטר את החוליה הראשונה first של רשימת הסטודנטים ואת הערך הסף המינימלי threshold. על משמעות השדות ואופן השימוש בהם יהיה עליהם להחליט לבד. אופן השימוש של השיטות hasNext ו-next יוסבר בהמשך. שימו לב: threshold חוקי הינו ערך בין 56 ל-100 (כולל) שימו לב: בתשובתכם לשלות הסעיפים הבאים אין להוסיף למחלקה שדות מעבר לאלו שנתונים במסגרת שלמעלה. public interface Iterator <T>{ public T next(); public boolean hasNext(); }

45 מועד א 2016 סעיף ד (5 נקודות) השלימו את הבנאי של המחלקה PassingStudentIterator. אם הם אינם תקינים יש לזרוק חריגת זמן ריצה מטיפוס RuntimeException public PassingStudentsIterator (Link<Student> first, int threshold){ if (threshold > 100 | threshold < 56) throw new RuntimeException("threshold should be between 56 and 100"); this.threshold = threshold; curr = first; while(curr!=null && curr.getData().getGrade() < threshold) curr = curr.getNext(); }

46 מועד א 2016 public boolean hasNext() { return curr != null; }
סעיף ה (5 נקודות) השלימו את השיטה Public boolean hasNext() על השיטה להחזיר true כל זמן שיש לפחות סטודנט אחד ברשימה שעדיין לא הוחזר על ידי השיטה next. אחרת על השיטה להחזיר false. public boolean hasNext() { return curr != null; }

47 סיכום ומשימות תרגלנו: Graphs משימות: עבודה 5


הורד את "ppt "מבוא למדעי המחשב 2019 תרגול 13 Graphs 1.

מצגות קשורות


מודעות Google