Κοινή χρήση τεχνολογίας

Wen Xin Yi Yan VS iFlytek Spark VS chatgpt (300) -- Εισαγωγή στους αλγόριθμους 22.1 4 ερωτήσεις

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

4. Δίνονται πολλές εικόνες G = ( V , E ) G=(V,E)σολ=(V,μι)συνδεδεμένη λίστα γειτνίασης (το πολύγραφο είναι ένα γράφημα που επιτρέπει επαναλαμβανόμενες ακμές και άκρες αυτο-βρόχου), παρακαλούμε δώστε ένα χρόνο O ( V + E ) O(V+E)Ο(V+μι)αλγόριθμος, που χρησιμοποιείται για τον υπολογισμό του "ισοδύναμου" μη κατευθυνόμενου γραφήματος του γραφήματος G ′ = ( V , E ′ ) G^{'}=(V,E^{'})σολ=(V,μι) αντιπροσωπεύεται από μια συνδεδεμένη λίστα γειτνίασης.εδώ Ε 'Ε^{'}μιΘα είναι EEμι Οι περιττές ακμές μπαίνουν και οι υπόλοιπες άκρες μετά τη διαγραφή των άκρων αυτο-βρόχου. Η αφαίρεση των υπολοίπων ακμών αναφέρεται στην αντικατάσταση πολλαπλών άκρων μεταξύ δύο κόμβων με ένα άκρο. Εάν θέλετε να γράψετε κώδικα, χρησιμοποιήστε τη γλώσσα go.

Τα λόγια του Wen Xin:

Αναπαράσταση λίστας συνδεδεμένης γειτνίασης

Στην αναπαράσταση λίστας με συνδεδεμένη γειτνίαση, κάθε κορυφή vvv Υπάρχει μια συνδεδεμένη λίστα και κάθε κόμβος στη συνδεδεμένη λίστα αντιπροσωπεύει έναν slave vvv Αρχική άκρη.για να υπολογίσετε GTG^TσολΤ, πρέπει να διασχίσουμε GGσολ για κάθε άκρη του , και αντιστρέφοντας την κατεύθυνση της άκρης, προσθέστε στο GTG^TσολΤ στην αντίστοιχη συνδεδεμένη λίστα.

Υλοποίηση γλώσσας Go

package main

import (
    "fmt"
)

// Graph 使用邻接链表表示
type Graph struct {
    vertices int
    adjList  map[int][]int
}

// NewGraph 创建一个新的图
func NewGraph(vertices int) *Graph {
    return &Graph{
        vertices: vertices,
        adjList:  make(map[int][]int),
    }
}

// AddEdge 添加一条边到图中
func (g *Graph) AddEdge(u, v int) {
    g.adjList[u] = append(g.adjList[u], v)
}

// Transpose 计算图的转置
func (g *Graph) Transpose() *Graph {
    gT := NewGraph(g.vertices)
    for u, adj := range g.adjList {
        for _, v := range adj {
            gT.AddEdge(v, u) // 反转边的方向
        }
    }
    return gT
}

func main() {
    g := NewGraph(4)
    g.AddEdge(0, 1)
    g.AddEdge(0, 2)
    g.AddEdge(1, 2)
    g.AddEdge(2, 0)
    g.AddEdge(2, 3)

    gT := g.Transpose()

    fmt.Println("Original Graph:")
    for u, adj := range g.adjList {
        fmt.Printf("%d -> %vn", u, adj)
    }

    fmt.Println("nTransposed Graph:")
    for u, adj := range gT.adjList {
        fmt.Printf("%d -> %vn", u, adj)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

χρονική πολυπλοκότητα

  • Η χρονική πολυπλοκότητα της διέλευσης κάθε άκρης είναι O ( E ) O(E)Ο(μι),σε EEμι είναι ο αριθμός των άκρων.
  • Για κάθε ακμή, εκτελούμε μια πράξη σταθερού χρόνου (προσθήκη στη λίστα γειτνίασης ενός άλλου γραφήματος).
  • Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( E ) O(E)Ο(μι)

Αναπαράσταση πίνακα γειτνίασης

Στην αναπαράσταση του πίνακα γειτνίασης, χρησιμοποιούμε έναν δισδιάστατο πίνακα για την αποθήκευση πληροφοριών ακμών, όπου matrix[u][v] Υποδεικνύει εάν υπάρχει γραμμή από uuu φθάνω vvv πλευρά.για να υπολογίσετε GTG^TσολΤ, διασχίζουμε το πάνω τρίγωνο (ή το κάτω τρίγωνο, ανάλογα με τις συνήθειες αναπαράστασης του πίνακα) του πίνακα και αντιστρέφουμε την κατεύθυνση των άκρων, δηλαδή, matrix[u][v] Η τιμή εκχωρείται σεmatrixT[v][u]

Υλοποίηση γλώσσας Go(Απλοποιημένη έκδοση, εξετάζει μόνο την ύπαρξη και δεν λαμβάνει υπόψη τα βάρη ακμών):

// 假设使用二维布尔切片表示邻接矩阵
type GraphMatrix [][]bool

// Transpose 计算图的转置
func (g GraphMatrix) Transpose() GraphMatrix {
    n := len(g)
    gT := make(GraphMatrix, n)
    for i := range gT {
        gT[i] = make([]bool, n)
    }

    for i := 0; i < n; i++ {
        for j := 0; j < n; j++ {
            gT[j][i] = g[i][j] // 反转边的方向
        }
    }
    return gT
}

// 注意:这里没有完整的GraphMatrix类型实现,因为示例仅关注Transpose函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

χρονική πολυπλοκότητα

  • Απαιτείται επανάληψη σε κάθε στοιχείο του πίνακα O ( V 2 ) O(V^2)Ο(V2) χρόνο, μεταξύ των οποίων VVV είναι ο αριθμός των κορυφών.
  • Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( V 2 ) O(V^2)Ο(V2) . Αυτό μπορεί να μην είναι το πιο αποτελεσματικό όταν ο αριθμός των κορυφών είναι πολύ μεγαλύτερος από τον αριθμό των ακμών.

Εισαγάγετε την περιγραφή της εικόνας εδώ

Εισαγάγετε την περιγραφή της εικόνας εδώ

Εισαγάγετε την περιγραφή της εικόνας εδώ

Εισαγάγετε την περιγραφή της εικόνας εδώ

iFlytek Spark:

Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από μια λίστα γειτνίασης, μπορούμε να προσθέσουμε τις γειτονικές κορυφές κάθε κορυφής στη λίστα γειτνίασης της μετατιθέμενης κορυφής του νέου γραφήματος διασχίζοντας τη λίστα γειτνίασης κάθε κορυφής. Τα συγκεκριμένα βήματα είναι τα εξής:

  1. Δημιουργήστε μια νέα λίστα γειτνίασης GTG^{T}σολΤ, αρχικοποιήθηκε σε άδεια.
  2. Διασχίστε την αρχική εικόνα GGσολ κάθε κορυφή του vvv
  3. Τραβέρσες κορυφές vvv συνδεδεμένη λίστα γειτνίασης, κάθε γειτονική κορυφή uuu Προσθήκη σε νέα εικόνα GTG^{T}σολΤ μεσαία κορυφή vvv στη συνδεδεμένη λίστα γειτνίασης.
  4. Επιστροφή στη νέα εικόνα GTG^{T}σολΤ

Ανάλυση χρονικής πολυπλοκότητας: απαιτείται η διέλευση κάθε κορυφής του αρχικού γραφήματος O ( ∣ V ∣ ) O(|V|)Ο(V) Ο χρόνος που απαιτείται για τη διέλευση της λίστας γειτνίασης κάθε κορυφής είναι O ( ∣ E ∣ ) O(|E|)Ο(μι) χρόνος, άρα η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(V+μι)

Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, μπορούμε να λάβουμε τον πίνακα γειτνίασης ενός νέου γραφήματος μεταφέροντας τον πίνακα γειτνίασης του αρχικού γραφήματος. Τα συγκεκριμένα βήματα είναι τα εξής:

  1. Δημιουργήστε ένα νέο με μέγεθος ∣ V ∣ × ∣ V ∣ |V| φορές |V|V×V μήτρα GTG^{T}σολΤ, αρχικοποιημένο σε έναν πίνακα όλων των μηδενικών.
  2. Διασχίστε τη μήτρα γειτνίασης της αρχικής εικόνας GGσολ,Θα G [ i ] [ j ] G[i][j]σολ[Εγώ][ι] Η τιμή εκχωρείται σε GT [ j ] [ i ] G^{T}[j][i]σολΤ[ι][Εγώ]
  3. Επιστρέφει τον πίνακα γειτνίασης του νέου γραφήματος GTG^{T}σολΤ

Ανάλυση χρονικής πολυπλοκότητας: απαιτείται η διέλευση του πίνακα γειτνίασης του αρχικού γραφήματος O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2) χρόνος, άρα η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2)

Ο παρακάτω είναι ο κώδικας που εφαρμόζεται στη γλώσσα Go:

// 邻接链表表示的有向图转置
func transposeAdjList(G map[int][]int) map[int][]int {
    GT := make(map[int][]int)
    for v, neighbors := range G {
        for _, u := range neighbors {
            GT[u] = append(GT[u], v)
        }
    }
    return GT
}

// 邻接矩阵表示的有向图转置
func transposeAdjMatrix(G [][]int) [][]int {
    n := len(G)
    GT := make([][]int, n)
    for i := range GT {
        GT[i] = make([]int, n)
    }
    for i := 0; i < n; i++ {
        for j := 0; j < n; j++ {
            GT[j][i] = G[i][j]
        }
    }
    return GT
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

360 Ευφυής Εγκέφαλος:

Αναπαράσταση λίστας συνδεδεμένης γειτνίασης

Στην αναπαράσταση λίστας με συνδεδεμένη γειτνίαση, μπορούμε να διασχίσουμε απευθείας την αρχική εικόνα GGσολΗ λίστα γειτνίασης κάθε κόμβου προστίθεται στη συνέχεια στο νέο γράφημα αφού αντιστραφεί η κατεύθυνση κάθε ακμής. GTG^{T}σολΤστον αντίστοιχο κόμβο.

Εφαρμογή κώδικα γλώσσας Go:
type Graph struct {
    Vertices []*Node // 存储图中所有节点的指针
}

type Node struct {
    Value int
    Adjacent []*Node // 存储与该节点相邻的所有节点的指针
}

func (g *Graph) Transpose() *Graph {
    transposed := &Graph{make([]*Node, len(g.Vertices))}
    for i, node := range g.Vertices {
        transposed.Vertices[i] = &Node{node.Value, make([]*Node, 0)}
    }
    for _, node := range g.Vertices {
        for _, adj := range node.Adjacent {
            // 将边反向添加到转置图中
            transposed.Vertices[adj.Value].Adjacent = append(transposed.Vertices[adj.Value].Adjacent, transposed.Vertices[node.Value])
        }
    }
    return transposed
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
Ανάλυση χρονικής πολυπλοκότητας:
  • Διασχίστε κάθε κόμβο στο αρχικό γράφημα: O ( ∣ V ∣ ) O(|V|)Ο(V)
  • Διασχίστε τη λίστα γειτνίασης κάθε κόμβου: O ( ∣ E ∣ ) O(|E|)Ο(μι)

Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(V+μι)

Σημειογραφία μήτρας γειτνίασης

Στη σημειογραφία μήτρας γειτνίασης, μπορούμε να δημιουργήσουμε μια νέα μήτρα γειτνίασης και στη συνέχεια να διασχίσουμε την αρχική εικόνα GGσολμήτρα γειτνίασης, κάθε στοιχείο στη μήτρα ( i , j ) (i, j)(Εγώ,ι)εκχωρήθηκε στη νέα μήτρα ( j , i ) (j, i)(ι,Εγώ)θέση, ολοκληρώνοντας έτσι την αναστροφή της άκρης.

Εφαρμογή κώδικα γλώσσας Go:
type MatrixGraph struct {
    Matrix [][]bool // 存储邻接矩阵
}

func (mg *MatrixGraph) Transpose() *MatrixGraph {
    transposed := &MatrixGraph{make([][]bool, len(mg.Matrix))}
    for i := range mg.Matrix {
        transposed.Matrix[i] = make([]bool, len(mg.Matrix))
        for j := range mg.Matrix[i] {
            // 将边反向赋值到转置矩阵中
            transposed.Matrix[i][j] = mg.Matrix[j][i]
        }
    }
    return transposed
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Ανάλυση χρονικής πολυπλοκότητας:
  • Δημιουργήστε μια νέα μήτρα γειτνίασης: O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2)
  • Διασχίστε τη μήτρα γειτνίασης της αρχικής εικόνας: O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2)

Επομένως, η συνολική χρονική πολυπλοκότητα είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2)

Συνοψίζω

Για την αναπαράσταση λίστας συνδεδεμένης γειτνίασης, η χρονική πολυπλοκότητα του αλγόριθμου μεταφοράς είναι O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|)Ο(V+μι)και για την αναπαράσταση του πίνακα γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου μεταφοράς είναι O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2) .Σε πρακτικές εφαρμογές, εάν το γράφημα είναι σχετικά αραιό (δηλ. ∣ E ∣ |E|μιπολύ μικρότερο από ∣ V ∣ 2 |V|^2V2 ), θα ήταν πιο αποτελεσματικό να χρησιμοποιήσετε την αναπαράσταση της συνδεδεμένης λίστας γειτνίασης.Εάν το γράφημα είναι πυκνό (δηλ. ∣ E ∣ |E|μικοντά ∣ V ∣ 2 |V|^2V2), τότε η αναπαράσταση του πίνακα γειτνίασης μπορεί να είναι πιο κατάλληλη.

Σαφείς λέξεις του φάσματος σοφίας:

Στην αναπαράσταση γραφήματος, οι λίστες συνδεδεμένες με γειτνίαση και οι πίνακες γειτνίασης είναι και οι δύο μέθοδοι που χρησιμοποιούνται συνήθως. Οι λίστες γειτονικών συνδέσεων χρησιμοποιούνται για την αναπαράσταση μη κατευθυνόμενων και κατευθυνόμενων γραφημάτων, ενώ οι πίνακες γειτνίασης χρησιμοποιούνται συνήθως για την αναπαράσταση μη κατευθυνόμενων γραφημάτων. Για τη μεταφορά ενός κατευθυνόμενου γραφήματος, μπορούμε να λειτουργήσουμε ξεχωριστά τη συνδεδεμένη λίστα γειτνίασης και τον πίνακα γειτνίασης.

Μεταφορά συνδεδεμένης λίστας γειτνίασης

Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από μια συνδεδεμένη λίστα γειτνίασης, η μεταφορά του γραφήματος μπορεί να επιτευχθεί διασχίζοντας κάθε κορυφή του αρχικού γραφήματος και τροποποιώντας τις εξερχόμενες ακμές του αρχικού γραφήματος σε εισερχόμενες ακμές.

package main
import (
	"fmt"
)
// 定义图的顶点结构
type Vertex struct {
	Name   string
	Edges  []*Vertex
	Visited bool
}
// 计算图的转置
func Transpose(g *Vertex) {
	for _, v := range g.Edges {
		// 遍历顶点v的所有出边
		for _, w := range v.Edges {
			// 在原图中查找顶点w指向顶点v的边,并反转
			for i, e := range w.Edges {
				if e == v {
					w.Edges[i] = v
					break
				}
			}
		}
	}
}
func main() {
	// 创建顶点
	a := &Vertex{Name: "A"}
	b := &Vertex{Name: "B"}
	c := &Vertex{Name: "C"}
	// 建立有向图关系
	a.Edges = []*Vertex{b, c}
	b.Edges = []*Vertex{a}
	c.Edges = []*Vertex{a}
	// 打印原图
	fmt.Println("原图:")
	PrintGraph(a)
	// 计算转置图
	Transpose(a)
	// 打印转置图
	fmt.Println("转置图:")
	PrintGraph(a)
}
// PrintGraph 用于打印图的邻接链表表示
func PrintGraph(g *Vertex) {
	g.Visited = true
	for _, v := range g.Edges {
		if !v.Visited {
			fmt.Println(g.Name, "->", v.Name)
			PrintGraph(v)
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

Μεταφορά πίνακα γειτνίασης

Για ένα κατευθυνόμενο γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, η μεταφορά του γραφήματος μπορεί να επιτευχθεί μετατρέποντας κάθε σειρά του αρχικού γραφήματος στην αντίστοιχη στήλη του νέου γραφήματος.

package main
import (
	"fmt"
)
// 计算邻接矩阵的转置
func TransposeMatrix(mat [][]int) [][]int {
	transposed := make([][]int, len(mat[0]))
	for i := range transposed {
		transposed[i] = make([]int, len(mat))
	}
	for i, row := range mat {
		for j, val := range row {
			if val == 1 {
				transposed[j][i] = 1
			}
		}
	}
	return transposed
}
func main() {
	// 创建邻接矩阵
	originalMatrix := [][]int{
		{0, 1, 1},
		{0, 0, 1},
		{1, 0, 0},
	}
	// 计算转置矩阵
	transposedMatrix := TransposeMatrix(originalMatrix)
	// 打印转置矩阵
	fmt.Println("转置矩阵:")
	for _, row := range transposedMatrix {
		fmt.Println(row)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

Ανάλυση χρόνου εκτέλεσης αλγορίθμου

  1. Για τη μεταφορά μιας λίστας συνδεδεμένης γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου είναι O(E), όπου E είναι ο αριθμός των ακμών στο γράφημα. Αυτό συμβαίνει επειδή κάθε άκρη πρέπει να διασχιστεί μία φορά.

  2. Για τη μεταφορά του πίνακα γειτνίασης, η χρονική πολυπλοκότητα του αλγορίθμου είναι O(V^2), όπου V είναι ο αριθμός των κορυφών στο γράφημα. Αυτό συμβαίνει επειδή κάθε στοιχείο πίνακα πρέπει να διασχιστεί μία φορά και το μέγεθος του πίνακα είναι V×V.
    Αυτοί οι αλγόριθμοι είναι όλοι αποτελεσματικοί και εκτελούνται

Tiangong:

Να εφαρμόσει έναν αλγόριθμο για τον υπολογισμό ενός κατευθυνόμενου γραφήματος GGσολ μεταφορά του GTG^{T}σολΤ , μπορούμε να επεξεργαστούμε τις δύο αναπαραστάσεις της συνδεδεμένης λίστας γειτνίασης και της μήτρας γειτνίασης αντίστοιχα. Παρακάτω θα περιγράψω τους αλγόριθμους για αυτές τις δύο περιπτώσεις αντίστοιχα και θα δώσω παραδείγματα κώδικα στη γλώσσα Go.

Αναπαράσταση λίστας συνδεδεμένης γειτνίασης

Βήματα αλγορίθμου:
  1. Δημιουργήστε μια νέα λίστα γειτνίασης newAdjList Χρησιμοποιείται για την αποθήκευση του μεταφερόμενου γραφήματος.
  2. Διασχίστε τη συνδεδεμένη λίστα γειτνίασης της αρχικής εικόνας adjList
  3. για κάθε άκρη (u, v), προσθέστε το σε newAdjList[v] Μέσης.
  4. Επιστρέφει τη νέα λίστα γειτνίασης newAdjList
Παράδειγμα κώδικα γλώσσας Go:
type Graph struct {
    vertices []*Vertex
}

type Vertex struct {
    key      int
    adjacent []*Vertex
}

func (g *Graph) Transpose() *Graph {
    gt := &Graph{make([]*Vertex, len(g.vertices))}
    for i := range g.vertices {
        gt.vertices[i] = &Vertex{key: i}
    }
    for _, u := range g.vertices {
        for _, v := range u.adjacent {
            // Add edge (v, u) to the transpose graph.
            gt.vertices[v.key].adjacent = append(gt.vertices[v.key].adjacent, gt.vertices[u.key])
        }
    }
    return gt
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
Ανάλυση χρόνου εκτέλεσης:

Ο χρόνος εκτέλεσης αυτού του αλγόριθμου είναι O(|V| + |E|), όπου |V| είναι ο αριθμός των κορυφών και |E|. Αυτό συμβαίνει γιατί πρέπει να διασχίσουμε όλες τις κορυφές και τις ακμές μία φορά.

Σημειογραφία μήτρας γειτνίασης

Βήματα αλγορίθμου:
  1. Δημιουργήστε μια νέα μήτρα γειτνίασης newAdjMatrix Χρησιμοποιείται για την αποθήκευση του μεταφερόμενου γραφήματος.
  2. Διασχίστε τη μήτρα γειτνίασης της αρχικής εικόνας adjMatrix
  3. για κάθε στοιχείο adjMatrix[i][j], αναθέστε το σε newAdjMatrix[j][i]
  4. Επιστρέφει τον νέο πίνακα γειτνίασης newAdjMatrix
Παράδειγμα κώδικα γλώσσας Go:
type Graph struct {
    matrix [][]bool
}

func (g *Graph) Transpose() *Graph {
    gt := &Graph{make([][]bool, len(g.matrix))}
    for i := range gt.matrix {
        gt.matrix[i] = make([]bool, len(g.matrix))
    }
    for i := range g.matrix {
        for j := range g.matrix[i] {
            // Copy the adjacency values with swapped indices.
            gt.matrix[j][i] = g.matrix[i][j]
        }
    }
    return gt
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
Ανάλυση χρόνου εκτέλεσης:

Ο χρόνος εκτέλεσης αυτού του αλγόριθμου είναι O(|V|^2), όπου |V| είναι ο αριθμός των κορυφών. Αυτό συμβαίνει επειδή πρέπει να διασχίσουμε ολόκληρο τον πίνακα γειτνίασης και το μέγεθος του πίνακα γειτνίασης είναι |V x |V|.

Το παραπάνω παράδειγμα κώδικα είναι μόνο το βασικό μέρος του αλγορίθμου Σε πραγματικές εφαρμογές, ενδέχεται να χρειαστεί να προστεθούν άλλες λειτουργίες, όπως ο χειρισμός σφαλμάτων, η είσοδος και η έξοδος. Επιπλέον, για να απλοποιηθεί ο κώδικας, θεωρείται ότι δεν υπάρχουν επαναλαμβανόμενες ακμές στο γράφημα και οι αριθμοί κορυφής αριθμούνται διαδοχικά ξεκινώντας από το 0.

chatgpt:

Ο παρακάτω είναι ένας αλγόριθμος γραμμένος σε γλώσσα Go για τον υπολογισμό του G^T από το γράφημα G και δίνονται επίσης οι αντίστοιχες συνδεδεμένες γειτονικές μέθοδοι αναπαράστασης λίστας και μήτρας γειτνίασης:

package main

import "fmt"

// 图的节点结构体
type Node struct {
    Value int       // 节点的值
    Next  *Node     // 下一个节点指针
}

// 邻接链表表示法的图结构体
type Graph struct {
    Vertices []*Node   // 图中所有节点的数组
}

// 添加有向边到邻接链表
func (g *Graph) AddEdge(u, v int) {
    newNode := &Node{Value: v}
    if g.Vertices[u] == nil {
        g.Vertices[u] = newNode
    } else {
        curr := g.Vertices[u]
        for curr.Next != nil {
            curr = curr.Next
        }
        curr.Next = newNode
    }
}

// 输出邻接链表表示的图信息
func (g *Graph) Print() {
    for i, node := range g.Vertices {
        fmt.Printf("顶点 %d:", i)
        for node != nil {
            fmt.Printf("%d ", node.Value)
            node = node.Next
        }
        fmt.Println()
    }
}

// 获取图 G 的转置图 G^T 的邻接链表表示法
func GetTranspose(g *Graph) *Graph {
    transpose := &Graph{
        Vertices: make([]*Node, len(g.Vertices)),
    }

    for i, node := range g.Vertices {
        for node != nil {
            v := node.Value

            // 在转置图中添加反向边
            transpose.AddEdge(v, i)

            node = node.Next
        }
    }

    return transpose
}

// 输出邻接链表表示的转置图信息
func PrintTranspose(g *Graph) {
    fmt.Println("转置图 G^T:")
    g.Print()
}

// 邻接矩阵表示法的图结构体
type Matrix struct {
    Vertices [][]int   // 邻接矩阵,存储边的连接关系(0 表示无边,1 表示有边)
}

// 初始化邻接矩阵表示的图
func InitMatrix(numVertices int) *Matrix {
    matrix := &Matrix{
        Vertices: make([][]int, numVertices),
    }

    for i := range matrix.Vertices {
        matrix.Vertices[i] = make([]int, numVertices)
    }

    return matrix
}

// 添加有向边到邻接矩阵
func (m *Matrix) AddEdge(u, v int) {
    m.Vertices[u][v] = 1
}

// 获取图 G 的转置图 G^T 的邻接矩阵表示法
func GetTransposeMatrix(m *Matrix) *Matrix {
    numRows := len(m.Vertices)
    numCols := len(m.Vertices[0])

    transpose := InitMatrix(numRows)

    for i := 0; i < numRows; i++ {
        for j := 0; j < numCols; j++ {
            if m.Vertices[i][j] == 1 {
                // 在转置矩阵中添加反向边
                transpose.AddEdge(j, i)
            }
        }
    }

    return transpose
}

// 输出邻接矩阵表示的转置图信息
func PrintTransposeMatrix(m *Matrix) {
    numRows := len(m.Vertices)
    numCols := len(m.Vertices[0])

    fmt.Println("转置图 G^T:")
    for i := 0; i < numRows; i++ {
        fmt.Printf("顶点 %d:", i)
        for j := 0; j < numCols; j++ {
            if m.Vertices[i][j] == 1 {
                fmt.Printf("%d ", j)
            }
        }
        fmt.Println()
    }
}

func main() {
    // 邻接链表表示的有向图 G
    g := &Graph{
        Vertices: make([]*Node, 4),
    }

    g.AddEdge(0, 1)
    g.AddEdge(1, 2)
    g.AddEdge(2, 3)
    g.AddEdge(3, 1)

    // 输出原始图 G 的邻接链表表示法
    fmt.Println("原始图 G:")
    g.Print()

    // 获取转置图 G^T 的邻接链表表示法并输出
    transpose := GetTranspose(g)
    PrintTranspose(transpose)

    
	// 邻接矩阵表示的有向图 G
	m := InitMatrix(4)

	m.AddEdge(0, 1)
	m.AddEdge(1, 2)
	m.AddEdge(2, 3)
	m.AddEdge(3, 1)

	// 输出原始图 G 的邻接矩阵表示法
	fmt.Println("原始图 G:")
	for _, row := range m.Vertices {
		fmt.Println(row)
	}

	// 获取转置图 G^T 的邻接矩阵表示法并输出
	transposeMatrix := GetTransposeMatrix(m)
	PrintTransposeMatrix(transposeMatrix)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164

Η χρονική πολυπλοκότητα αυτού του αλγορίθμου είναι O(V + E), όπου V είναι ο αριθμός των κορυφών και E είναι ο αριθμός των ακμών. Η διαδικασία κατασκευής του μετατιθέμενου γραφήματος απαιτεί τη διέλευση όλων των άκρων του αρχικού γραφήματος και την πρόσθεσή τους στο μεταφερόμενο γράφημα αντίστροφα, έτσι ώστε η συνολική χρονική πολυπλοκότητα να είναι ανάλογη με τον αριθμό των κορυφών και των ακμών.

Κίμι:

Τα μεταφερθέντα γραφήματα κατευθυνόμενων γραφημάτων μπορούν να αναπαρασταθούν από δύο κύριες δομές δεδομένων: λίστες συνδεδεμένες με γειτνίαση και πίνακες γειτνίασης. Παρακάτω θα παρουσιάσω τους αλγόριθμους σε αυτές τις δύο περιπτώσεις αντίστοιχα και θα παράσχω δείγμα κώδικα στη γλώσσα Go.

Αναπαράσταση λίστας συνδεδεμένης γειτνίασης

Για ένα γράφημα που αντιπροσωπεύεται από μια συνδεδεμένη λίστα γειτνίασης, μπορούμε να μεταφέρουμε το γράφημα διασχίζοντας τη λίστα γειτνίασης κάθε κορυφής και στη συνέχεια προσθέτοντας μια αντίστροφη ακμή σε κάθε σημείο γειτονίας. Η χρονική πολυπλοκότητα αυτής της μεθόδου είναι O(V + E), όπου V είναι ο αριθμός των κορυφών και E είναι ο αριθμός των ακμών.

Δείγμα κώδικα γλώσσας Go:
type Vertex struct {
    Value int
    Adj []Vertex
}

func transposeGraph(graph []Vertex) []Vertex {
    transposed := make([]Vertex, len(graph))
    for _, v := range graph {
        for _, adjV := range v.Adj {
            // 为邻接点添加反向边
            found := false
            for _, tV := range transposed[adjV.Value].Adj {
                if tV.Value == v.Value {
                    found = true
                    break
                }
            }
            if !found {
                transposed[adjV.Value].Adj = append(transposed[adjV.Value].Adj, v)
            }
        }
    }
    return transposed
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Αναπαράσταση πίνακα γειτνίασης

Για ένα γράφημα που αντιπροσωπεύεται από έναν πίνακα γειτνίασης, μπορούμε να εφαρμόσουμε τη μεταφορά ανταλλάσσοντας τις γραμμές και τις στήλες του πίνακα. Η χρονική πολυπλοκότητα αυτής της μεθόδου είναι O(V^2).

Δείγμα κώδικα γλώσσας Go:
func transposeMatrix(matrix [][]int) [][]int {
    n := len(matrix)
    transposed := make([][]int, n)
    for i := 0; i < n; i++ {
        transposed[i] = make([]int, n)
        for j := 0; j < n; j++ {
            transposed[i][j] = matrix[j][i]
        }
    }
    return transposed
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Ανάλυση Αλγορίθμων

  • λίστα γειτνίασης : Ο αλγόριθμος πρέπει να διασχίσει τη λίστα γειτνίασης κάθε κορυφής και για κάθε άκρη, πρέπει να προστεθεί μια αντίστροφη ακμή στη λίστα γειτνίασης του διπλανού σημείου. Εάν το μέσο μήκος της λίστας γειτόνων είναι k, η χρονική πολυπλοκότητα του αλγορίθμου είναι O(V + E * k). Στη χειρότερη περίπτωση, το k μπορεί να είναι κοντά στο V και η χρονική πολυπλοκότητα είναι κοντά στο O(V^2). Στην καλύτερη περίπτωση, το k είναι κοντά στο 1 και η χρονική πολυπλοκότητα είναι κοντά στο O(E).
  • μήτρα γειτνίασης : Ο αλγόριθμος πρέπει να περάσει από κάθε στοιχείο του πίνακα και να ανταλλάξει τις γραμμές και τις στήλες. Δεδομένου ότι ο πίνακας είναι VxV, η χρονική πολυπλοκότητα είναι O(V^2).

Σε πρακτικές εφαρμογές, ποιος αλγόριθμος να επιλέξει εξαρτάται από την αραιότητα του γραφήματος και τη διαθέσιμη μνήμη. Για αραιά γραφήματα, οι λίστες γειτονικών συνδέσεων μπορεί να είναι πιο αποδοτικές στη μνήμη για πυκνά γραφήματα, οι πίνακες γειτνίασης μπορεί να είναι πιο αποτελεσματικοί.

Hunyuan:

Για να υπολογίσετε ένα κατευθυνόμενο γράφημα G = ( V , E ) G=(V,E)σολ=(V,μι) μεταφορά του GT = ( V , ET ) G^T=(V,E^T)σολΤ=(V,μιΤ), μπορούμε να δώσουμε αντίστοιχους αλγόριθμους για τις δύο μεθόδους αναπαράστασης της συνδεδεμένης λίστας γειτνίασης και της μήτρας γειτνίασης αντίστοιχα, και να αναλύσουμε τον χρόνο εκτέλεσης τους.

Αναπαράσταση λίστας συνδεδεμένης γειτνίασης

Περιγραφή αλγορίθμου
  1. Αρχικοποιήστε μια κενή λίστα γειτνίασης για να αποθηκεύσετε τις άκρες του μεταφερόμενου γραφήματος.
  2. Διασχίστε την αρχική εικόνα GGσολ όλων των κόμβων.
  3. για κάθε κόμβο uuu, διασχίζει όλους τους γειτονικούς κόμβους στη λίστα γειτονικών του vvv
  4. Προσθήκη νέας λίστας γειτνίασης από vvv φθάνω uuu πλευρά.
  5. Μετά την ολοκλήρωση της διέλευσης, η νέα συνδεδεμένη λίστα γειτνίασης είναι το μεταφερόμενο γράφημα GTG^TσολΤ
Ανάλυση χρόνου εκτέλεσης
  • χρονική πολυπλοκότητα: O ( ∣ E ∣ ) O(|E|)Ο(μι),σε ∣ E ∣ |E|μι είναι ο αριθμός των πλευρών της αρχικής εικόνας. Γιατί πρέπει να διασχίσουμε κάθε άκρη δύο φορές (μία για να διαβάσουμε και μία για να γράψουμε).

Σημειογραφία μήτρας γειτνίασης

Περιγραφή αλγορίθμου
  1. Αρχικοποιήστε έναν πίνακα γειτνίασης του ίδιου μεγέθους με το αρχικό γράφημα για να αποθηκεύσετε τις άκρες του μεταφερόμενου γραφήματος.
  2. Διασχίστε την αρχική εικόνα GGσολ μήτρα γειτνίασης.
  3. Για κάθε μη μηδενικό στοιχείο στον πίνακα (δηλαδή υπάρχει μια ακμή ( u , v ) (u, v)(u,v)), αντίστοιχη θέση στον πίνακα γειτνίασης του μεταφερόμενου γραφήματος ( v , u ) (v, u)(v,u) Ορίστε σε ένα μη μηδενικό στοιχείο.
  4. Μετά την ολοκλήρωση της διέλευσης, ο νέος πίνακας γειτνίασης είναι το μεταφερόμενο γράφημα GTG^TσολΤ
Ανάλυση χρόνου εκτέλεσης
  • χρονική πολυπλοκότητα: O ( ∣ V ∣ 2 ) O(|V|^2)Ο(V2),σε ∣ V ∣ |V|V είναι ο αριθμός των κόμβων στο αρχικό γράφημα. Επειδή πρέπει να διασχίσουμε ολόκληρο τον πίνακα γειτνίασης.

Υλοποίηση γλώσσας Go (αναπαράσταση παρακείμενης συνδεδεμένης λίστας)

type Edge struct {
    dest int
}

type AdjacencyList struct {
    edges map[int][]Edge
}

func TransposeGraph(graph AdjacencyList) AdjacencyList {
    transposed := AdjacencyList{edges: make(map[int][]Edge)}
    for u, neighbors := range graph.edges {
        for _, edge := range neighbors {
            v := edge.dest
            transposed.edges[v] = append(transposed.edges[v], Edge{dest: u})
        }
    }
    return transposed
}

func main() {
    // 示例图的邻接链表表示
    graph := AdjacencyList{edges: map[int][]Edge{
        0: {{dest: 1}},
        1: {{dest: 2}},
        2: {{dest: 0}},
    }}

    // 计算转置图
    transposedGraph := TransposeGraph(graph)

    // 打印转置图的邻接链表
    for u, neighbors := range transposedGraph.edges {
        fmt.Printf("Node %d -> Nodes: ", u)
        for _, edge := range neighbors {
            fmt.Printf("%d ", edge.dest)
        }
        fmt.Println()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

Σε αυτόν τον κώδικα ορίζουμε α Edge δομή για την αναπαράσταση ακμών, και αAdjacencyList Δομή για την αναπαράσταση μιας συνδεδεμένης λίστας γειτνίασης.TransposeGraph Η συνάρτηση δέχεται αAdjacencyList τύπου παράμετρος και επιστρέφει μια αναπαράσταση λίστας συνδεδεμένης γειτονίας του μεταφερθέντος γραφήματος.υπάρχειmain συνάρτηση, δημιουργούμε ένα παράδειγμα γραφήματος, υπολογίζουμε και εκτυπώνουμε το μεταφερόμενο γράφημα του.