Quiz 2

Week 7: Graphs & Adjacency Matrices

2039 words
10 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 7: Graphs & Adjacency Matrices > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Week 6 (Dictionaries) **Cross-links:** BSCS1002-Python (Week 9 — Graphs), BSCS2002-PDSA (Week 7 — Graph Algorithms) ## 1. Motivation: Representing Relationships Lists and dictionaries store **individual items**.

Week 7: Graphs & Adjacency Matrices

BSCS1001 — IIT Madras BS Degree Prerequisite: Week 6 (Dictionaries) Cross-links: BSCS1002-Python (Week 9 — Graphs), BSCS2002-PDSA (Week 7 — Graph Algorithms)

1. Motivation: Representing Relationships

Lists and dictionaries store individual items. But what if we need to store relationships between items?
ProblemWhat We Need To Represent
Student mentoringWho can mentor whom (based on marks)
Train routesWhich stations are connected by direct trains
Social networksWho is friends with whom
Word relationshipsWhich words follow which in a paragraph
For all these, we need a graph — a structure that explicitly stores connections.
Real-world analogy: A list is like a shopping list (items). A dictionary is like a phonebook (names → numbers). A graph is like a map (cities connected by roads).

2. What is a Graph?

A graph consists of:
  • Vertices (or nodes): The entities
  • Edges (or links): The connections between entities (Diagram)

Key Terminology

TermDefinitionExample
Vertex (node)An entityA student, a station, a word
Edge (link)A connection between two verticesAlice can mentor Bob
Directed graphEdges have directionA→B means A mentors B
Undirected graphEdges have no directionA—B means A and B are friends
Weighted graphEdges have valuesDistance between stations
AdjacentTwo vertices connected by an edgeAlice and Bob are adjacent

Directed vs Undirected Graphs

pseudo
Undirected:  A — B  (A and B are connected)
Directed:    A → B  (A connects TO B, but not necessarily B to A)
In this course:
  • Mentoring graph: Directed (A mentors B ≠ B mentors A)
  • Friendship graph: Undirected (A is friend of B = B is friend of A)
  • Train route graph: Directed (route from A to B may differ from B to A)

3. Matrix Representation

A matrix (also called adjacency matrix) represents a graph as a 2D table.

Structure

For a graph with N vertices:
sql
M[i][j] = 1  →  There is an edge from vertex i to vertex j
M[i][j] = 0  →  There is NO edge from vertex i to vertex j

Example: 4 Students

(Diagram) Adjacency Matrix:
From \ ToAliceBobCharlieDiana
Alice0110
Bob0001
Charlie0001
Diana0000
pseudo
Matrix M:
    A B C D
A  [0,1,1,0]
B  [0,0,0,1]
C  [0,0,0,1]
D  [0,0,0,0]

Properties of Adjacency Matrix

PropertyMeaning
Diagonal (M[i][i])Usually 0 (no self-loop)
Row sumOutgoing edges from i
Column sumIncoming edges to j
Symmetric?Yes for undirected graphs (M[i][j]=M[j][i])
SizeN × N for N vertices

4. Creating Matrices with Dictionaries

In this course, matrices are implemented using nested dictionaries (dictionary of dictionaries).

Creating a Matrix

pseudo
Procedure CreateMatrix(rows, cols)
    mat = {}
    i = 0
    while (i < rows) {
        mat[i] = {}
        j = 0
        while (j < cols) {
            mat[i][j] = 0
            j = j + 1
        }
        i = i + 1
    }
    return(mat)
End CreateMatrix

Accessing Matrix Elements

sql
mat = CreateMatrix(3, 3)
mat[0][1] = 1    // Set edge from row 0 to column 1
value = mat[0][1]    // Read value

Mapping Station Names to Indices

When vertices have names (not just numbers), we need a station-to-index mapping:
pseudo
// Collect all unique stations
stations = {}
foreach t in keys(trains) {
    stations[trains[t][start]] = True
    stations[trains[t][end]] = True
}
// Map stations to indices
n = length(keys(stations))
stnindex = {}
i = 0
foreach s in keys(stations) {
    stnindex[s] = i
    i = i + 1
}
// Create matrix
direct = CreateMatrix(n, n)
// Populate matrix
foreach t in keys(trains) {
    i = stnindex[trains[t][start]]
    j = stnindex[trains[t][end]]
    direct[i][j] = 1
}

5. Processing Matrices

Iterating Row by Row

pseudo
foreach r in rows(mymatrix) {
    foreach c in columns(mymatrix) {
        // Process mymatrix[r][c]
    }
}

Row-Wise vs Column-Wise Processing

(Diagram)

Counting Outgoing Edges (Row Sum)

pseudo
// How many students can Alice mentor?
outCount = 0
foreach j in columns(mathMentorGraph) {
    if (mathMentorGraph[aliceIdx][j] == 1) {
        outCount = outCount + 1
    }
}

Counting Incoming Edges (Column Sum)

pseudo
// How many students can mentor Alice?
inCount = 0
foreach i in rows(mathMentorGraph) {
    if (mathMentorGraph[i][aliceIdx] == 1) {
        inCount = inCount + 1
    }
}

6. Mentoring Graph: A Complete Example

Problem

Student A can mentor student B in a subject if:
  • A's mark is higher than B's mark
  • The difference is between 10 and 20 marks (not too little, not too much)

Building the Graph

pseudo
Procedure CreateMentorGraph(marks)
    n = length(keys(marks))
    mentorGraph = CreateMatrix(n, n)
    foreach i in keys(marks) {
        foreach j in keys(marks) {
            ijMarksDiff = marks[i] - marks[j]
            if (10 ≤ ijMarksDiff AND ijMarksDiff ≤ 20) {
                mentorGraph[i][j] = 1
            }
        }
    }
    return(mentorGraph)
End CreateMentorGraph

Tracing

Dataset:
StudentMaths
Alice (0)85
Bob (1)72
Charlie (2)91
Diana (3)68
Calculations:
ijmarks[i]marks[j]Diff10≤Diff≤20?Edge i→j
AliceAlice858500
AliceBob8572131
AliceCharlie8591-6❌ (negative)0
AliceDiana8568171
BobAlice7285-130
BobBob727200
BobCharlie7291-190
BobDiana726840
CharlieAlice91856❌ (too small)0
CharlieBob9172191
CharlieCharlie919100
CharlieDiana916823❌ (too large)0
DianaAlice6885-170
DianaBob6872-40
DianaCharlie6891-230
DianaDiana686800
Result (mentorGraph):
pseudo
    A B C D
A  [0,1,0,1]
B  [0,0,0,0]
C  [1,0,0,0]
D  [0,0,0,0]
So: Alice can mentor Bob and Diana. Charlie can mentor Alice.

Mutual Mentoring (Study Groups)

pseudo
// A and B can be study partners if A mentors B in one subject
// and B mentors A in another subject
foreach i in rows(mathMentor) {
    foreach j in columns(mathMentor) {
        if (mathMentor[i][j] == 1 AND phyMentor[j][i] == 1) {
            // i and j can be study partners!
        }
    }
}

7. Similarity Graph & Cliques

Similarity Graph

Two students are similar if their marks differ by at most 10 in ALL subjects:
pseudo
Procedure CreateSimilarityGraph(marks1, marks2, marks3)
    n = length(keys(marks1))
    similarityGraph = CreateMatrix(n, n)
    foreach i in keys(marks1) {
        foreach j in keys(marks1) {
            diff1 = abs(marks1[i] - marks1[j])
            diff2 = abs(marks2[i] - marks2[j])
            diff3 = abs(marks3[i] - marks3[j])
            if (diff1 ≤ 10 AND diff2 ≤ 10 AND diff3 ≤ 10) {
                similarityGraph[i][j] = 1
            }
        }
    }
    return(similarityGraph)
End CreateSimilarityGraph

Cliques

A clique is a group of vertices where every pair is connected. In a similarity graph, a clique represents a group of students who are all similar to each other. (Diagram)

Problem

A student is "popular" if many other students can mentor them (incoming edges). We need to count unique mentors across all three subjects.

Algorithm

pseudo
mentors = {}
popularity = {}
// For each student j (potential mentee)
foreach j in columns(mathMentorGraph) {
    mentors[j] = {}
    // Check all potential mentors i
    foreach i in rows(mathMentorGraph) {
        if (mathMentorGraph[i][j] == 1) {
            mentors[j][i] = True
        }
        if (phyMentorGraph[i][j] == 1) {
            mentors[j][i] = True
        }
        if (chemMentorGraph[i][j] == 1) {
            mentors[j][i] = True
        }
    }
    popularity[j] = length(keys(mentors[j]))
}

Why Use a Dictionary?

Using a dictionary (mentors[j][i] = True) ensures we count each mentor only once, even if they can mentor in multiple subjects.

9. Graph vs Matrix Comparison

Representation Trade-offs

AspectAdjacency MatrixAdjacency List (Dictionary)
SpaceO(N²) — always N×NO(E) — only for existing edges
Check edge i→jO(1) — instantO(degree(i)) — scan list
Find all neighborsO(N) — scan rowO(degree(i)) — direct
Add edgeO(1) — set valueO(1) — append
Best forDense graphs (many edges)Sparse graphs (few edges)

When to Use Which

(Diagram)

10. Practice Questions

Basic Questions

Q1. What is a graph? What are vertices and edges?
Show Answer
A graph is a structure representing connections. Vertices (nodes) are the entities. Edges (links) are the connections between vertices. Q2. In an adjacency matrix, what does M[i][j] = 1 mean? Show Answer
M[i][j] = 1 means there is a direct edge from vertex i to vertex j. Q3. What is a symmetric matrix? When does it occur? Show Answer
A symmetric matrix has M[i][j] = M[j][i] for all i, j. This occurs in undirected graphs where connections are mutual (e.g., friendships). Q4. How do you count the number of students that a particular student can mentor? Show Answer
Sum the row for that student:
pseudo
count = 0
foreach j in columns(mentorGraph) {
    if (mentorGraph[studentIdx][j] == 1) {
        count = count + 1
    }
}

Intermediate Questions

Q5. For a graph with 5 vertices, how big is the adjacency matrix?
Show Answer
The matrix is 5 × 5 = 25 entries. For an undirected graph, only 10 unique pairs are possible (5×4/2), but the matrix still has 25 cells. Q6. Write pseudocode to create a matrix of size 4×4 and fill it with zeros. Show Answer
pseudo
mat = {}
i = 0
while (i < 4) {
    mat[i] = {}
    j = 0
    while (j < 4) {
        mat[i][j] = 0
        j = j + 1
    }
    i = i + 1
}
Q7. Explain why dictionaries (nested) are used to implement matrices in this course.
Show Answer
Nested dictionaries (dictionary of dictionaries) support random access: mat[i][j] directly returns the value. They also support dynamic sizing — we don't need to pre-allocate a fixed-size array. The outer dictionary maps row indices to rows, and each inner dictionary maps column indices to values. Q8. In the mentoring graph, why do we need to compare marks[i] - marks[j] and NOT marks[j] - marks[i]? Show Answer
marks[i] - marks[j] gives the difference from i's perspective. If the result is positive, i has higher marks than j. Since mentoring requires the mentor to have higher marks, we check marks[i] - marks[j] > 0. We also require it to be between 10 and 20.

Advanced Questions

Q9. Design an algorithm to find the student who can be mentored by the most students (most incoming edges).
Show Answer
pseudo
// Subject: Maths
mentorCount = {}
foreach j in columns(mentorGraph) {
    count = 0
    foreach i in rows(mentorGraph) {
        if (mentorGraph[i][j] == 1) {
            count = count + 1
        }
    }
    mentorCount[j] = count
}

// Find max
maxCount = 0
mostMentored = -1
foreach j in keys(mentorCount) {
    if (mentorCount[j] > maxCount) {
        maxCount = mentorCount[j]
        mostMentored = j
    }
}
Q10. Write pseudocode to convert an adjacency matrix to a list of edges (pairs of connected vertices).
Show Answer
sql
edges = []
foreach i in rows(graph) {
    foreach j in columns(graph) {
        if (graph[i][j] == 1) {
            edges = edges ++ [(i, j)]
        }
    }
}
// Returns list of (from, to) pairs
Q11. Explain why the similarity graph is undirected while the mentoring graph is directed.
Show Answer
Similarity is mutual: if Alice is similar to Bob, then Bob is automatically similar to Alice. So the edge goes both ways — undirected.
Mentoring is directional: Alice can mentor Bob if Alice's marks are higher (with appropriate difference). But Bob cannot mentor Alice unless Bob's marks are also higher. The relationship is not symmetric.
In the matrix: similarity graph is symmetric (M[i][j]=M[j][i]), mentoring graph is not. Q12. A complete graph has an edge between every pair of vertices. How many edges does a complete undirected graph with N vertices have? What does its adjacency matrix look like? Show Answer
A complete undirected graph with N vertices has N(N-1)/2 edges.
Its adjacency matrix has:
  • 0s on the diagonal (no self-loops)
  • 1s everywhere else (every pair connected)
  • Symmetric (undirected)
For N=4:
pseudo
[0, 1, 1, 1]
[1, 0, 1, 1]
[1, 1, 0, 1]
[1, 1, 1, 0]

📚 Cross-References

CourseTopicConnection
BSCS1002 (Python)Week 9 — GraphsAdjacency matrix/list in Python
BSCS2002 (PDSA)Week 7 — Graph AlgorithmsGraph representations
BSCS2002 (PDSA)Week 8 — Graph TraversalDFS, BFS

Quiz Tip: Graph questions often ask you to construct or interpret an adjacency matrix. Practice! Join Discord PreviousDictionary ApplicationsNextAdjacency Matrices
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.