ใครช่วยอธิบายให้ฉันเข้าใจง่ายๆว่ากราฟอะไซคลิกคืออะไร


109

ใครช่วยอธิบายให้ฉันเข้าใจง่ายๆว่ากราฟอะไซคลิกคืออะไร ฉันได้ดู Wikipedia แล้ว แต่มันไม่ได้ทำให้ฉันเห็นว่ามันใช้ในการเขียนโปรแกรมได้จริงๆ


26
วิกิพีเดียมักมีเนื้อหาทางเทคนิคมากมายซึ่งจะทำให้ผู้เริ่มต้นเรียนรู้อย่างมากเพื่อทำความเข้าใจ ไซต์ความช่วยเหลือทางคณิตศาสตร์หลายแห่งนั้นเหนือกว่าในเรื่องนี้ แต่น่าเสียดายที่พวกเขามักจะไม่เข้าสู่วิชาที่เกี่ยวข้องกับการคำนวณ
Jonathon Faust

1
ใครใช้ git ใช้ DAG จริงโดยไม่รู้ตัวericsink.com/vcbe/html/directed_acyclic_graphs.html
Qiulang

คำตอบ:


87

จุดที่มีเส้นชี้ไปยังจุดอื่น ๆ


23
นี่เป็นหนึ่งในคำตอบที่ดีที่สุดเพราะเป็นวิธีง่ายๆในการอธิบายว่าอะไรคือแนวคิดง่ายๆที่ฝังอยู่ในคำศัพท์ที่ซับซ้อน (ถ้าเราถามคำถามนี้เราอาจไม่รู้ทฤษฎีกราฟ ... หรือแม้กระทั่งจำเป็นต้องรู้) ตัวแปรของฉันน่าจะเป็น "กระโดดบาร์ที่คุณไม่สามารถไปที่แถบเดิมซ้ำสองครั้ง" แม้ว่าตัวอย่างแผนผังครอบครัวจากคำตอบอื่นอาจเป็นแนวคิดที่ง่ายกว่าโดยเฉพาะอย่างยิ่งสำหรับพวกเราที่ไม่ใช่นักศึกษาหรือผู้ติดสุรา
Tom Harrison

28
... ในทิศทางเดียว
Mark Robson

3
นี่เป็นตัวอย่างที่ดีของความล้มเหลวในการแสดงแนวคิดที่ซับซ้อนโดยเนื้อแท้ในแง่ที่เป็นไปได้น้อยกว่า นั่นเป็นเหตุผลที่ข้อที่ห้าของ Euclid ยังคงมีอยู่
Xaqron

4
คุณต้องใส่ "โดยที่เส้นไม่ก่อเป็นวัฏจักร" มิฉะนั้นคุณเพียงแค่อธิบายกราฟที่กำหนดทิศทางไม่ใช่กราฟอะไซคลิกที่กำหนดทิศทาง
Pharap

"จุดที่มีเส้นชี้ไปยังจุดอื่น ๆ โดยไม่มีการวนซ้ำ" จะเป็นการปรับปรุง
John DeRegnaucourt

173

กราฟ = โครงสร้างประกอบด้วยโหนดที่เชื่อมต่อกันด้วยขอบ

กำกับ = การเชื่อมต่อระหว่างโหนด (ขอบ) มีทิศทาง: A -> B ไม่เหมือนกับ B -> A

acyclic = "non-circular" = ย้ายจากโหนดไปยังโหนดโดยไปตามขอบคุณจะไม่พบโหนดเดียวกันอีกเป็นครั้งที่สอง

ตัวอย่างที่ดีของกราฟ acyclic ที่กำหนดทิศทางคือต้นไม้ อย่างไรก็ตามโปรดทราบว่ากราฟ acyclic ที่กำหนดทิศทางทั้งหมดไม่ใช่ต้นไม้


ฉันเข้าใจว่าโหนดคืออะไร เมื่อคุณพูดว่า "edge" คุณหมายถึงลูกศรที่ชี้จากโหนด A ถึงโหนด B ใช่หรือไม่
appshare.co

อธิบายดีกว่า. แล้วสิ่งนี้เกี่ยวข้องกับการเขียนโปรแกรมอย่างไร? เกี่ยวข้องกับการเขียนโปรแกรมเชิงฟังก์ชันหรือไม่?
appshare.co

2
โดยทั่วไปจะแสดงด้วยลูกศร แต่จริงๆแล้วมันมีความสัมพันธ์ระหว่าง A และ B ในโปรแกรมของคุณซึ่งอาจเป็นค่าที่แท้จริงในเมทริกซ์ adjacency ที่ดัชนีที่แสดงทั้งสองโหนด
tvanfosson

42
ต้นไม้กำกับทั้งหมดคือ DAG แต่ไม่ใช่ DAG ทั้งหมดที่เป็นต้นไม้ DAG A-> B, A-> C, B-> C ไม่สามารถแสดงเป็นต้นไม้ได้เนื่องจากโหนด C มีพาเรนต์มากกว่าหนึ่งตัว
Jason S

2
ความตรงของขอบไม่ใช่คุณสมบัติเดียวที่แยก DAG ออกจากต้นไม้ DAG สามารถมีได้มากกว่า | V | -1 ขอบซึ่งแตกต่างจากต้นไม้ ตัวอย่างเช่น A-> B, A-> C, B-> D, C-> D เป็น DAG แต่ไม่ใช่ต้นไม้อย่างชัดเจนเนื่องจากมีจำนวนขอบและโหนดเท่ากัน
Anonym Mus

49

ฉันเห็นคำตอบมากมายที่ระบุความหมายของ DAG (Directed Acyclic Graph) แต่ไม่มีคำตอบเกี่ยวกับการใช้งาน นี่คือสิ่งที่ง่ายมาก -

กราฟวิชาบังคับก่อน - ในระหว่างหลักสูตรวิศวกรรมนักเรียนทุกคนต้องเผชิญกับภารกิจในการเลือกวิชาที่เป็นไปตามข้อกำหนดเช่นข้อกำหนดเบื้องต้น ตอนนี้เป็นที่ชัดเจนว่าคุณไม่สามารถเรียนวิชาปัญญาประดิษฐ์ [B] ได้หากไม่มีหลักสูตรที่จำเป็นเบื้องต้นเกี่ยวกับอัลกอริทึม [A] ดังนั้น B จึงขึ้นอยู่กับ A หรือในแง่ที่ดีกว่า A จึงมีขอบนำไปสู่ ​​B ดังนั้นเพื่อที่จะไปถึงโหนด B คุณต้องไปที่โหนด A ในไม่ช้ามันจะชัดเจนว่าหลังจากเพิ่มเรื่องทั้งหมดที่มีข้อกำหนดเบื้องต้นลงในกราฟแล้ว มันจะกลายเป็น Directed Acyclic Graph

ถ้ามีรอบแล้วคุณจะไม่จบหลักสูตร: p

ระบบซอฟต์แวร์ในมหาวิทยาลัยที่อนุญาตให้นักศึกษาลงทะเบียนหลักสูตรสามารถจำลองวิชาเป็นโหนดเพื่อให้แน่ใจว่านักเรียนได้เรียนหลักสูตรที่จำเป็นก่อนลงทะเบียนสำหรับหลักสูตรปัจจุบัน

อาจารย์ของฉันให้การเปรียบเทียบนี้และช่วยให้ฉันเข้าใจ DAG ได้ดีที่สุดแทนที่จะใช้แนวคิดที่ซับซ้อน!

อีกตัวอย่างเรียลไทม์ -> ตัวอย่างเรียลไทม์ของการใช้ DAG ในระบบเวอร์ชัน


4
นี่ควรเป็นคำตอบที่ติดอันดับสูงที่สุด การเปรียบเทียบอย่างง่ายและไม่ใช้คำจำกัดความของหนังสือเรียนทำให้ OP ไม่สามารถเข้าใจได้ง่าย
kimathie

25

ตัวอย่างการใช้กราฟ acyclic ที่กำหนดทิศทางในการเขียนโปรแกรมรวมถึงสิ่งต่างๆที่แสดงถึงการเชื่อมต่อและสาเหตุ

ตัวอย่างเช่นสมมติว่าคุณมีไปป์ไลน์การคำนวณที่กำหนดค่าได้ที่รันไทม์ จากตัวอย่างนี้สมมติว่าการคำนวณ A, B, C, D, E, F และ G ขึ้นอยู่กับซึ่งกันและกัน: A ขึ้นอยู่กับ C, C ขึ้นอยู่กับ E และ F, B ขึ้นอยู่กับ D และ E และ D ขึ้นอยู่กับ F. สิ่งนี้สามารถแสดงเป็น DAG เมื่อคุณมี DAG ในหน่วยความจำคุณสามารถเขียนอัลกอริทึมเพื่อ:

  • ตรวจสอบให้แน่ใจว่าการคำนวณได้รับการประเมินตามลำดับที่ถูกต้อง (การเรียงลำดับโทโพโลยี )
  • หากการคำนวณสามารถทำได้แบบขนาน แต่การคำนวณแต่ละครั้งมีเวลาดำเนินการสูงสุดคุณสามารถคำนวณเวลาดำเนินการสูงสุดของทั้งชุดได้

เหนือสิ่งอื่นใด

นอกขอบเขตของการเขียนโปรแกรมแอปพลิเคชันเครื่องมือสร้างอัตโนมัติที่เหมาะสม (make, ant, scons และอื่น ๆ ) จะใช้ DAG เพื่อให้แน่ใจว่าลำดับการสร้างส่วนประกอบของโปรแกรมที่เหมาะสม


+1 สำหรับการกล่าวถึงเวรกรรม สิ่งนี้เกิดขึ้นมากเมื่อคุณต้องการแสดงระบบที่ซับซ้อนโดยที่ผลลัพธ์ของกระบวนการหนึ่งเป็นอินพุตสำหรับกระบวนการอื่นอย่างน้อยหนึ่งกระบวนการ
Alex Feinman

14

คำตอบหลายคำได้ยกตัวอย่างการใช้กราฟ (เช่นการสร้างแบบจำลองเครือข่าย) และคุณถามว่า "สิ่งนี้เกี่ยวข้องกับการเขียนโปรแกรมอย่างไร"

คำตอบสำหรับคำถามย่อยนั้นก็คือไม่มีอะไรเกี่ยวข้องกับการเขียนโปรแกรมมากนัก มันเกี่ยวข้องกับการแก้ปัญหา

เช่นเดียวกับรายการที่เชื่อมโยงเป็นโครงสร้างข้อมูลที่ใช้สำหรับปัญหาบางประเภทกราฟมีประโยชน์ในการแสดงความสัมพันธ์บางอย่าง รายการที่เชื่อมโยงต้นไม้กราฟและโครงสร้างนามธรรมอื่น ๆ มีเพียงการเชื่อมต่อกับการเขียนโปรแกรมซึ่งคุณสามารถนำไปใช้ในโค้ดได้ มีอยู่ในระดับที่สูงขึ้นของนามธรรม ไม่เกี่ยวกับการเขียนโปรแกรม แต่เป็นการใช้โครงสร้างข้อมูลในการแก้ปัญหา


สามารถนำไปใช้ในการเขียนโปรแกรม ใช่ฉันชอบแบบนั้นเนื่องจากกราฟมีอยู่ในโลกแห่งความเป็นจริงโดยไม่ขึ้นกับคอมพิวเตอร์!
appshare.co

13

Directed Acyclic Graphs (DAG) มีคุณสมบัติดังต่อไปนี้ซึ่งแตกต่างจากกราฟอื่น ๆ :

  1. ขอบของมันแสดงทิศทาง
  2. พวกเขาไม่มีรอบ

ตอนนี้ฉันสามารถนึกถึงการใช้งานครั้งเดียว - DAG (เรียกว่าWait-For-Graphs - รายละเอียดทางเทคนิคเพิ่มเติม ) มีประโยชน์ในการตรวจจับการหยุดชะงักเนื่องจากแสดงให้เห็นถึงการพึ่งพาระหว่างชุดของกระบวนการและทรัพยากร (ทั้งสองเป็นโหนดใน DAG) . การหยุดชะงักจะเกิดขึ้นเมื่อตรวจพบวงจร


1
Andriyev, +1 สำหรับตัวอย่างการหยุดชะงัก นี่คือความจริงที่ใช้โดยเอ็นจิ้น InnoDB ของ MySQL และพวกเขาเรียกมันว่า "wait-for-graph" ในขณะที่ "แถวนั้นต้องรอให้การล็อกแถวนั้นคลายออก"
Roland Bouman

ใช่คุณตายด้วยชื่อ - รอกราฟ บางคนพลาดไปได้อย่างไร อัปเดตการตอบกลับ :)
Arnkrishn

พวกเขารู้ได้อย่างไรว่ามีการพึ่งพา? โดยการตรวจสอบว่าสองโหนดมีบรรพบุรุษร่วมกันหรือไม่?
appshare.co

ลิงค์นี้ - cis.temple.edu/~ingargio/cis307/readings/deadlock.htmlมีรายละเอียดทางเทคนิคมากขึ้น
Arnkrishn

11

ฉันถือว่าคุณรู้คำศัพท์พื้นฐานเกี่ยวกับกราฟแล้ว มิฉะนั้นคุณควรเริ่มต้นจากบทความเกี่ยวกับทฤษฎีกราฟ

กำกับหมายถึงความจริงที่ว่าขอบ (การเชื่อมต่อ) มีทิศทาง ในแผนภาพทิศทางเหล่านี้จะแสดงโดยลูกศร ตรงกันข้ามคือกราฟที่ไม่มีทิศทางซึ่งขอบจะไม่ระบุทิศทาง

Acyclicหมายความว่าหากคุณเริ่มต้นจากโหนด X ใด ๆ โดยพลการใด ๆ และเดินผ่านขอบที่เป็นไปได้ทั้งหมดคุณจะไม่สามารถกลับไปที่ X ได้โดยไม่ต้องกลับไปที่ขอบที่ใช้ไปแล้ว

หลายแอปพลิเคชัน:

  • สเปรดชีต; มีอธิบายไว้ในบทความDAG
  • การควบคุมการแก้ไข : หากคุณดูแผนภาพในหน้านั้นคุณจะเห็นว่ามีการกำกับวิวัฒนาการของโค้ดที่ควบคุมการแก้ไข (มันจะ "ลง" ในแผนภาพนี้) และแบบ acyclic (จะไม่ย้อนกลับ "ขึ้น") .
  • แผนผังครอบครัว: มันกำกับ (คุณเป็นลูกพ่อแม่ของคุณไม่ใช่ในทางอื่น) และทางอ้อม (บรรพบุรุษของคุณไม่สามารถเป็นลูกหลานของคุณได้)

5

DAG คือกราฟที่ทุกอย่างไหลไปในทิศทางเดียวกันและไม่มีโหนดใดสามารถอ้างอิงกลับมาที่ตัวมันเองได้

นึกถึงต้นไม้บรรพบุรุษ; จริงๆแล้วพวกมันคือ DAG

DAG ทั้งหมดมี

  • โหนด (สถานที่จัดเก็บข้อมูล)
  • Directed Edges (ชี้ไปในทิศทางเดียวกัน)
  • โหนดบรรพบุรุษ (โหนดที่ไม่มีผู้ปกครอง)
  • ใบไม้ (โหนดที่ไม่มีลูก)

DAG แตกต่างจากต้นไม้ ในโครงสร้างที่เหมือนต้นไม้ต้องมีเส้นทางที่ไม่ซ้ำกันระหว่างทุก ๆ สองโหนด ใน DAGs โหนดสามารถมีโหนดแม่ได้สองโหนด

นี่เป็นบทความที่ดีเกี่ยวกับ DABs ความ ฉันหวังว่าจะช่วยได้


4

กราฟทุกประเภทใช้ในการเขียนโปรแกรมเพื่อสร้างแบบจำลองความสัมพันธ์ในโลกแห่งความจริงที่แตกต่างกัน ตัวอย่างเช่นเครือข่ายสังคมมักแสดงด้วยกราฟ (ในกรณีนี้เป็นวงจร) ในทำนองเดียวกันโครงสร้างเครือข่ายต้นไม้ครอบครัวเส้นทางสายการบิน ...


2

จากซอร์สโค้ดหรือแม้กระทั่งสามมุมมองของโค้ดแอดเดรส (TAC) คุณสามารถเห็นภาพปัญหาได้อย่างง่ายดายที่หน้านี้ ...

http://cgm.cs.mcgill.ca/~hagha/topic30/topic30.html#Exptree

หากคุณไปที่ส่วนแผนภูมินิพจน์จากนั้นเลื่อนหน้าลงเล็กน้อยจะแสดง "การเรียงลำดับโทโพโลยี" ของทรีและอัลกอริทึมสำหรับวิธีประเมินนิพจน์

ดังนั้นในกรณีนี้คุณสามารถใช้ DAG เพื่อประเมินนิพจน์ซึ่งมีประโยชน์เนื่องจากโดยปกติแล้วการประเมินผลจะถูกตีความและการใช้ผู้ประเมิน DAG ดังกล่าวจะทำให้ผู้รวบรวมข้อมูลที่เรียบง่ายเร็วขึ้นในส่วนหลักเนื่องจากไม่ได้ผลักดันและโผล่ไปยังสแต็กและเนื่องจากเป็นการกำจัด นิพจน์ย่อยทั่วไป

อัลกอริทึมพื้นฐานในการคำนวณ DAG ในภาษาอียิปต์ที่ไม่ใช่ภาษาอียิปต์โบราณ (เช่นภาษาอังกฤษ) คือ:

1) ทำให้วัตถุ DAG ของคุณเป็นเช่นนั้น

คุณต้องมีรายการสดและรายการนี้มีโหนด DAG และนิพจน์ย่อย DAG ปัจจุบันทั้งหมด นิพจน์ย่อย DAG คือ DAG Node หรือเรียกอีกอย่างว่าโหนดภายใน สิ่งที่ฉันหมายถึงโดย live DAG Node คือถ้าคุณกำหนดให้กับตัวแปร X มันจะกลายเป็นสด นิพจน์ย่อยทั่วไปที่ใช้ X จะใช้อินสแตนซ์นั้น ถ้า X ถูกกำหนดให้อีกครั้ง NEW DAG NODE จะถูกสร้างและเพิ่มลงในรายการสดและ X เก่าจะถูกลบออกดังนั้นนิพจน์ย่อยถัดไปที่ใช้ X จะอ้างถึงอินสแตนซ์ใหม่และจะไม่ขัดแย้งกับนิพจน์ย่อยที่ ใช้ชื่อตัวแปรเดียวกันเท่านั้น

เมื่อคุณกำหนดให้กับตัวแปร X แล้วโดยบังเอิญโหนดนิพจน์ย่อย DAG ทั้งหมดที่อยู่ ณ จุดที่กำหนดจะกลายเป็นไม่อยู่เนื่องจากการกำหนดใหม่ทำให้ความหมายของนิพจน์ย่อยไม่ถูกต้องโดยใช้ค่าเก่า

class Dag {
  TList LiveList;
  DagNode Root;
}

// In your DagNode you need a way to refer to the original things that
// the DAG is computed from. In this case I just assume an integer index
// into the list of variables and also an integer index for the opertor for
// Nodes that refer to operators. Obviously you can create sub-classes for
// different kinds of Dag Nodes.
class DagNode {
  int Variable;
  int Operator;// You can also use a class
  DagNode Left;
  DagNode Right;
  DagNodeList Parents;
}

ดังนั้นสิ่งที่คุณทำคือเดินผ่านต้นไม้ของคุณในโค้ดของคุณเองเช่นโครงสร้างของนิพจน์ในซอร์สโค้ดเป็นต้น เรียกโหนดที่มีอยู่เช่น XNodes

ดังนั้นสำหรับแต่ละ XNode คุณต้องตัดสินใจว่าจะเพิ่มเข้าไปใน DAG อย่างไรและมีความเป็นไปได้ที่จะมีอยู่แล้วใน DAG

นี่เป็นรหัสหลอกที่ง่ายมาก ไม่ได้มีไว้สำหรับการรวบรวม

DagNode XNode::GetDagNode(Dag dag) {
  if (XNode.IsAssignment) {
    // The assignment is a special case. A common sub expression is not
    // formed by the assignment since it creates a new value.

    // Evaluate the right hand side like normal
    XNode.RightXNode.GetDagNode();  


    // And now take the variable being assigned to out of the current live list
    dag.RemoveDagNodeForVariable(XNode.VariableBeingAssigned);

    // Also remove all DAG sub expressions using the variable - since the new value
    // makes them redundant
    dag.RemoveDagExpressionsUsingVariable(XNode.VariableBeingAssigned);

    // Then make a new variable in the live list in the dag, so that references to
    // the variable later on will see the new dag node instead.
    dag.AddDagNodeForVariable(XNode.VariableBeingAssigned);

  }
  else if (XNode.IsVariable) {
    // A variable node has no child nodes, so you can just proces it directly
    DagNode n = dag.GetDagNodeForVariable(XNode.Variable));
    if (n) XNode.DagNode = n;
    else {
      XNode.DagNode = dag.CreateDagNodeForVariable(XNode.Variable);
    }
    return XNode.DagNode;
  }
  else if (XNode.IsOperator) {
    DagNode leftDagNode = XNode.LeftXNode.GetDagNode(dag);
    DagNode rightDagNode = XNode.RightXNode.GetDagNode(dag);


    // Here you can observe how supplying the operator id and both operands that it
    // looks in the Dags live list to check if this expression is already there. If
    // it is then it returns it and that is how a common sub-expression is formed.
    // This is called an internal node.
    XNode.DagNode = 
      dag.GetOrCreateDagNodeForOperator(XNode.Operator,leftDagNode,RightDagNode) );

    return XNode.DagNode;
  }
}

นั่นคือวิธีหนึ่งในการมอง การเดินขั้นพื้นฐานของต้นไม้และเพียงแค่เพิ่มและอ้างถึงโหนด Dag เมื่อมันไป รากของ dag คืออะไรก็ตามที่ DagNode รูทของต้นไม้จะส่งกลับเช่น

เห็นได้ชัดว่าขั้นตอนตัวอย่างสามารถแบ่งออกเป็นส่วนย่อย ๆ หรือทำเป็นคลาสย่อยด้วยฟังก์ชันเสมือน

สำหรับการจัดเรียง Dag คุณจะต้องผ่าน DagNode แต่ละอันจากซ้ายไปขวา กล่าวอีกนัยหนึ่งทำตาม DagNodes ขอบด้านซ้ายมือแล้วตามด้วยขอบด้านขวามือ ตัวเลขจะถูกกำหนดกลับกัน กล่าวอีกนัยหนึ่งเมื่อคุณไปถึง DagNode โดยไม่มีลูกให้กำหนด Node นั้นให้เป็นหมายเลขการเรียงลำดับปัจจุบันและเพิ่มหมายเลขการเรียงลำดับดังนั้นเมื่อการเรียกซ้ำคลายตัวเลขที่ได้รับมอบหมายตามลำดับที่เพิ่มขึ้น

ตัวอย่างนี้จัดการเฉพาะต้นไม้ที่มีโหนดที่มีลูกศูนย์หรือสองลูก เห็นได้ชัดว่าต้นไม้บางต้นมีโหนดที่มีลูกมากกว่าสองลูกดังนั้นตรรกะจึงยังคงเหมือนเดิม แทนที่จะคำนวณซ้ายและขวาให้คำนวณจากซ้ายไปขวาเป็นต้น ...

// Most basic DAG topological ordering example.
void DagNode::OrderDAG(int* counter) {
  if (this->AlreadyCounted) return;

  // Count from left to right
  for x = 0 to this->Children.Count-1
    this->Children[x].OrderDag(counter)

  // And finally number the DAG Node here after all
  // the children have been numbered
  this->DAGOrder = *counter;

  // Increment the counter so the caller gets a higher number
  *counter = *counter + 1;

  // Mark as processed so will count again
  this->AlreadyCounted = TRUE;
}

1

หากคุณรู้ว่าต้นไม้ใดอยู่ในการเขียนโปรแกรม DAG ในการเขียนโปรแกรมจะคล้ายกัน แต่อนุญาตให้โหนดมีพาเรนต์มากกว่าหนึ่งตัว สิ่งนี้มีประโยชน์เมื่อคุณต้องการปล่อยให้โหนดรวมกันเป็นกลุ่มภายใต้มากกว่าพาเรนต์เดียว แต่ไม่มีปัญหาเรื่องความยุ่งเหยิงของกราฟทั่วไปที่มีรอบ คุณยังคงสามารถนำทาง DAG ได้อย่างง่ายดาย แต่มีหลายวิธีในการกลับไปที่รูท (เนื่องจากอาจมีพาเรนต์มากกว่าหนึ่งตัว) โดยทั่วไป DAG เดียวอาจมีหลายราก แต่ในทางปฏิบัติอาจดีกว่าที่จะยึดติดกับรากเดียวเช่นต้นไม้ หากคุณเข้าใจการสืบทอดแบบเดี่ยวกับหลายรายการใน OOP คุณก็จะรู้ว่าทรีเทียบกับ DAG ฉันตอบนี้แล้วที่นี่


1

ชื่อนี้บอกคุณถึงสิ่งที่คุณต้องรู้มากที่สุดเกี่ยวกับคำจำกัดความของมัน: เป็นกราฟที่ทุกขอบไหลไปในทิศทางเดียวเท่านั้นและเมื่อคุณคลานไปตามขอบเส้นทางของคุณจะไม่มีวันกลับคุณไปยังจุดยอดที่คุณเพิ่งจากไป

ฉันไม่สามารถพูดถึงการใช้งานทั้งหมดได้ (Wikipedia ช่วยที่นั่น) แต่สำหรับฉัน DAGs มีประโยชน์อย่างมากเมื่อพิจารณาการอ้างอิงระหว่างทรัพยากร เครื่องมือเกมของฉันแสดงถึงทรัพยากรที่โหลดทั้งหมด (วัสดุพื้นผิวเฉดสีข้อความธรรมดา parsed json ฯลฯ ) เป็น DAG เดียว ตัวอย่าง:

วัสดุคือโปรแกรม N GL ซึ่งแต่ละตัวต้องการเฉดสีสองตัวและแต่ละเฉดสีต้องการแหล่งที่มาของ shader แบบธรรมดา ด้วยการแทนทรัพยากรเหล่านี้เป็น DAG ฉันสามารถสืบค้นกราฟสำหรับทรัพยากรที่มีอยู่ได้อย่างง่ายดายเพื่อหลีกเลี่ยงการโหลดซ้ำ สมมติว่าคุณต้องการให้วัสดุหลายอย่างใช้จุดยอดเฉดสีด้วยซอร์สโค้ดเดียวกัน เป็นการสิ้นเปลืองที่จะโหลดซอร์สใหม่และคอมไพล์เฉดสีใหม่สำหรับการใช้งานทุกครั้งเมื่อคุณสามารถสร้างขอบใหม่ให้กับทรัพยากรที่มีอยู่ได้ ด้วยวิธีนี้คุณสามารถใช้กราฟเพื่อตรวจสอบว่ามีสิ่งใดขึ้นอยู่กับทรัพยากรหรือไม่และถ้าไม่ให้ลบออกและเพิ่มหน่วยความจำในความเป็นจริงสิ่งนี้เกิดขึ้นโดยอัตโนมัติ

โดยส่วนขยาย DAG มีประโยชน์สำหรับการแสดงไปป์ไลน์การประมวลผลข้อมูล ลักษณะทางอ้อมหมายความว่าคุณสามารถเขียนโค้ดการประมวลผลตามบริบทได้อย่างปลอดภัยซึ่งสามารถติดตามตัวชี้ไปตามขอบจากจุดยอดโดยไม่ต้องคำนึงถึงจุดยอดเดียวกันอีกครั้ง ภาษาโปรแกรมภาพเช่นVVVV , Max MSPหรืออินเทอร์เฟซที่ใช้โหนดของ Autodesk Maya ล้วนพึ่งพา DAGs


-5

กราฟอะไซคลิกที่กำหนดทิศทางมีประโยชน์เมื่อคุณต้องการแสดง ... ตัวอย่างที่เป็นที่ยอมรับคือแผนผังครอบครัวหรือลำดับวงศ์ตระกูล


อาก็เข้าท่าเหมือนกัน แต่สิ่งนี้เกี่ยวข้องกับการเขียนโปรแกรมอย่างไร?
appshare.co

1
โครงสร้างข้อมูลเกี่ยวข้องกับการเขียนโปรแกรมอย่างไร
Jonathan Feinberg

โอเคฉันเข้าใจ. เพียงแค่คุณไม่ได้พูดถึง "โครงสร้างข้อมูล" ในคำตอบของคุณ
appshare.co

5
Tautology! = คำอธิบาย
Eva
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.