VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Mathematics in Bukit Timah | Shortest Paths, Dijkstra’s Algorithm and Weighted Networks

Original eduKateSG Day 13 editorial illustration with the text Rail Corridor Bukit Timah and stylised triangular railway bridge, rails and greenery; not a site photograph.

A pencil puzzle asks a child to travel from junction A to junction F on a map. Several routes exist, but each connection has a different number written beside it. Should the student count turns, choose the route with the fewest edges or add the numbers along each possible route? The right answer depends on what the edge weights represent and which objective the problem asks the student to minimise.

This Mathematics in Bukit Timah guide uses an entirely fictional six-junction network to explain weighted graphs, shortest paths, Dijkstra’s algorithm, tentative distances, route reconstruction, ties and constraints. The setting is inspired by the neighbourhood’s rail and green-corridor geography, but no edge, junction, access route, distance or journey time is surveyed from Bukit Timah. The diagram is an abstract Mathematics model, not navigation advice.

The central result: in the defined network, the shortest total weight from A to F is 13 units. Two distinct routes achieve that total: A→C→B→E→F, with weights 2+1+7+3, and A→C→B→D→E→F, with weights 2+1+5+2+3. An algorithm can find the minimum and show why a plausible-looking route is not necessarily optimal.

Article contents

Original stylised Rail Corridor Bukit Timah editorial illustration, a local backdrop only; the six-vertex weighted graph and Dijkstra routes are fictional and not actual public access paths.

Quick answer: weighted shortest path means minimise the sum

A network, or graph, has vertices representing locations or states and edges representing permitted connections. A weighted edge has a numerical value, such as fictional distance, travel time or cost.

The weight of a complete route is the sum of its traversed edge weights. Finding a shortest path means finding a permitted start-to-destination route with the smallest total weight, where “shortest” refers to the stated measure.

Fewer edges do not guarantee a smaller weight. A three-edge route can be more costly than a five-edge route if its individual edges are large.

The invented Bukit Timah map is not a street map

Real roads, green spaces and MRT connections involve crossings, closures, operating rules and access requirements. A model with six points labelled A to F does not establish that those points correspond to real neighbourhood facilities.

This article uses place names only to motivate a classroom question. A fictional edge of weight two is not automatically two kilometres or two minutes in an actual journey.

For practical travel, use current official transport and mapping information. The mathematical exercise remains valuable because its logic transfers once a real, verified network and weight definition are supplied.

State the graph before selecting a route

Our fictional graph has vertices A, B, C, D, E and F. Edges are undirected, so each can be traversed both ways under the problem’s rules.

The weighted connections are A–B:4, A–C:2, B–C:1, B–D:5, B–E:7, C–D:8, C–E:10, D–E:2, D–F:6 and E–F:3.

All weights are nonnegative and are measured in arbitrary model units. That assumption makes Dijkstra’s algorithm applicable, while a different problem with negative edges would require extra care.

Worked example 1: compare two candidate routes

Candidate one travels A→B→D→F. Its weight is 4+5+6=15.

Candidate two travels A→C→E→F. Its weight is 2+10+3=15. Both have three edges and both total fifteen units.

Neither comparison proves that fifteen is the global minimum. A third route may be shorter. Finding a minimum requires considering the full network structure rather than only the first two routes noticed.

Fewer edges need not mean shorter weight

The route A→C→B→D→E→F has five edges with weights 2,1,5,2,3. Its sum is thirteen.

That is smaller than the three-edge routes totalling fifteen in the previous example. The number of connections travelled is therefore not an adequate substitute for the sum of weights.

This is a useful transition from Primary counting to Secondary optimisation. The learner has to identify the numerical quantity being minimised, not merely count objects.

Why nonnegative weights matter to Dijkstra

Dijkstra’s algorithm maintains the smallest currently known distance from a starting vertex to each other vertex. At each step it selects an unsettled vertex with the smallest tentative distance.

When all edge weights are nonnegative, the selected vertex’s distance can be finalised. No later route through an unsettled vertex can reduce that distance below the currently smallest value.

This is the underlying correctness idea. Using the procedure blindly on graphs with negative-weight edges can produce wrong results.

Begin at A with zero distance

Set the tentative distance to the starting vertex A equal to zero. Every other vertex initially has unknown reachability, represented by infinity.

The initial table is A=0, B=∞, C=∞, D=∞, E=∞ and F=∞. We use ∞ as a symbol for “no finite route discovered yet,” not an extremely large physical distance.

A is the first settled vertex. Examine all its outgoing undirected connections to update the tentative distances of its neighbours.

Worked example 2: relax the two edges from A

From A, the known edges go to B with weight four and to C with weight two.

Tentative distances become B=4 and C=2. The other vertices remain at infinity because no path to them has yet been considered through the settled start.

The next unsettled vertex selected is C, because two is smaller than four. This selection is based on total known distance from A, not alphabetical order.

Relaxation means testing an alternative route

If a currently selected vertex u has known distance d(u) and an edge u–v has weight w, a candidate route to v has total d(u)+w.

Compare that with v’s existing tentative distance. Keep the smaller value. This update is called relaxing the edge.

The candidate may improve the current best route, tie it or leave it unchanged. A valid algorithm does not overwrite a smaller total with a larger one merely because an edge was examined later.

Worked example 3: settle C and improve B

C’s final distance is two. It connects to B with weight one, D with weight eight and E with weight ten.

A route to B through C totals 2+1=3, improving the previous B=4. New tentative values include B=3, D=10 and E=12.

The shortest known path to B is now A→C→B, not the direct edge A→B. This is the first clear demonstration of why one apparently convenient direct connection may not be optimal.

Choosing the next vertex requires the full tentative table

After settling A and C, the smallest unsettled tentative distance is B=3. D=10 and E=12 are larger; F is still infinity.

Select B and consider its adjacent edges. The choice of B is not a guess about what is geographically closest to the destination.

Dijkstra’s priority is distance from the start, not visual proximity to the endpoint F. That distinction matters in hand calculations.

Worked example 4: settle B

At B, the final distance is three. Its edge to D weighs five, so a route to D through B totals 3+5=8. This improves D from ten to eight.

Its edge to E weighs seven, giving 3+7=10, improving E from twelve to ten. The edge back to A or C offers no shorter route to those already settled vertices.

The tentative table is now D=8, E=10 and F=∞. The next unsettled vertex is D, with the lowest tentative total eight.

The idea of a predecessor

To reconstruct a path, record which previous vertex produced a tentative distance improvement. When C improves B to three, B’s predecessor becomes C.

When B improves D to eight, D’s predecessor becomes B. When B improves E to ten, E’s predecessor is initially B.

This information is separate from the distance values. A final table of totals without predecessors can establish a minimum distance but may not identify the actual route to write.

Worked example 5: settle D

D has final distance eight. Its edge to E weighs two, giving a candidate route of 8+2=10.

E already has tentative distance ten from B, so this new route ties rather than improves it. Record D as an additional possible predecessor for E if the task is to retain every shortest route.

D connects to F with weight six, giving a first tentative F distance of 8+6=14. The next vertex selected is E, still at ten.

Ties can mean more than one shortest path

Because E can be reached with total weight ten via A→C→B→E or via A→C→B→D→E, the model already contains two equally good ways to reach E.

A basic implementation may retain only one predecessor, depending on its tie rule. That still gives a correct minimum distance but may omit alternative optimal paths.

If the question asks for all shortest routes, equality during relaxation matters. Save all valid equal predecessors or use another systematic enumeration method.

Worked example 6: settle E and improve F

E’s final distance is ten. Its edge to F has weight three. The route through E gives 10+3=13.

F’s previous tentative distance was fourteen through D. Update F to thirteen and record E as its predecessor.

F is now the smallest remaining unsettled vertex. Settling it confirms the shortest A-to-F distance of thirteen under the nonnegative-weight model.

Reconstruct the winning path backwards

Start from F, whose predecessor is E. E has possible predecessors B and D with equal total weight. B’s predecessor is C, and C’s predecessor is A.

Following E→B→C→A backwards gives forward route A→C→B→E→F. Its total is 2+1+7+3=13.

Following E→D→B→C→A gives A→C→B→D→E→F, with total 2+1+5+2+3=13. Both routes attain the minimum.

Worked example 7: verify each route independently

For route one, add 2+1=3, then +7=10, then +3=13. For route two, add 2+1=3, +5=8, +2=10, +3=13.

Both end at F and use edges present in the defined graph. Each sum equals the final shortest-distance value.

A candidate route that uses a nonexistent A–E edge is invalid regardless of its arithmetic. Every path must satisfy connectivity as well as its weight calculation.

The algorithm does not visit every physical location

When calculating shortest distances, settling a vertex is a computational operation. It does not mean a person actually travels to that location.

Dijkstra examines alternatives to determine a best route. The eventual traveller would follow the reconstructed path, not the order in which the algorithm settled nodes.

A pupil who narrates A→C→B→D→E→F as the only algorithm “journey” may confuse computational exploration with the recommended route, especially because a different tied route also exists.

Compare Dijkstra with Euler trails

An Euler trail aims to traverse every edge exactly once when the graph has the required connectivity and degree conditions. A shortest-path problem asks for a minimum-weight route between chosen endpoints.

Our six-junction graph includes several edges that need not be used to travel optimally from A to F. A shortest path deliberately omits many connections.

The Bukit Timah network graphs and Euler trails guide treats the separate edge-coverage problem. Students should identify the objective before selecting an algorithm.

Compare weighted and unweighted shortest paths

If every edge has identical positive weight, minimising total weight is equivalent to minimising the number of edges. In that special case, a breadth-first search can find shortest edge-count paths.

With unequal weights as in our example, breadth-first search by number of edges alone is insufficient. The five-edge route of weight thirteen can beat a three-edge route of weight fifteen.

The algorithm depends on the weighting assumptions. “Shortest” is meaningless until the cost metric has been defined.

Worked example 8: what happens if every edge has weight one?

Replace each fictional edge’s original weight with one, keeping the same connections. Now A→B→D→F uses three edges and has total weight three.

A→C→E→F also uses three edges and has weight three. No two-edge A-to-F connection exists in the supplied graph.

Thus the minimum edge-count distance is three, not thirteen. Changing the weight model changes the objective even though the graph’s connections remain the same.

An undirected network differs from a directed one

Our original edges can be traversed both ways. In a directed graph, one may travel from B to E without necessarily being permitted to travel from E to B.

The algorithm’s relaxation step considers only outgoing directed edges from the selected vertex. Treating every directed connection as two-way can create impossible routes.

For an educational diagram, arrows should be treated as explicit data. The drawing must state whether connections are undirected, one-way or mixed.

Worked example 9: direction can remove a return path

Imagine a separate two-vertex graph containing only directed arc A→B with weight four. From A, B is reachable at cost four.

From B, A is not reachable because no reverse arc was supplied. The route B→A cannot be inferred from the existing arrow.

This simple case shows why directional assumptions matter before any shortest-path calculation. A numerical weight does not create a connection in the opposite direction.

A closed edge removes routes, not just numbers

Suppose B–E is removed from the original six-junction graph. The path A→C→B→E→F is no longer allowed.

The alternative A→C→B→D→E→F remains available with total weight thirteen. Therefore the shortest total can remain unchanged despite one closed edge.

This result depends on the graph’s other connections. One should not claim a closure always increases the best cost strictly; it may leave an equally good path.

Worked example 10: close the D–E connection instead

If D–E is removed but B–E remains, route A→C→B→E→F still totals thirteen.

The five-edge alternative through D and E no longer exists. The minimum stays thirteen under the remaining graph.

The example illustrates how redundancy can preserve the optimum while reducing the number of optimal routes. It is an abstract property, not a report of actual Bukit Timah closures.

Closing both equal alternatives changes the problem

If both B–E and D–E are removed, our network still contains the C–E edge of weight ten and the D–F edge of weight six.

One remaining route to F is A→C→B→D→F with total 2+1+5+6=14. Another is A→C→E→F with total 2+10+3=15.

The new shortest value is fourteen. Both deletions matter because they remove the previous tied thirteen-unit routes. A reliable update recomputes the graph rather than blindly reusing old predecessors.

Worked example 11: verify the new fourteen-unit route

Under the double-edge removal, A→C→B→D→F remains valid and has weights 2,1,5,6.

Its total is fourteen. The direct A→B→D→F route has 4+5+6=15, while A→C→E→F has 2+10+3=15.

Within the modified graph, no route can use the removed B–E or D–E connections. The best remaining alternative is therefore fourteen; it can be confirmed by re-running Dijkstra.

Why a zero edge can still be handled

Dijkstra permits zero edge weights as well as positive weights. A zero-weight connection may leave two vertices with equal shortest distances from the start.

The selection order among tied tentative distances can vary, but valid nonnegative relaxation still finds correct minimum totals. An implementation should handle ties consistently when reconstructing multiple routes.

Zero cost does not mean the vertices are identical. It means the connection has zero weight under the chosen model.

Negative edges break the standard settling guarantee

If a graph contains a negative-weight directed edge, a vertex settled as apparently best might later be improved through a route that includes that negative edge.

The proof underlying standard Dijkstra no longer applies. Some other method, such as Bellman–Ford under suitable conditions, may be required.

For an undirected graph, a negative edge also creates the possibility of repeatedly traversing a negative two-way cycle and reducing total walk cost without bound. Do not apply the original nonnegative shortest-path interpretation blindly.

Worked example 12: a directed negative-edge counterexample

Consider directed edges S→A of weight two, S→B of weight five, and B→A of weight −four. Assume no other edges.

Dijkstra’s naive settling rule would finalise A at two before exploring B at five. But the valid path S→B→A totals 5−4=1, which is smaller.

The standard settled-distance guarantee fails because a negative edge appears. This is a mathematical example of why the algorithm’s assumptions must be checked, not a claim of a negative real travel time.

Edge weights should use compatible units

Suppose one edge weight is measured in minutes and another in metres. Adding them directly to find a route total produces a meaningless mixed quantity.

All weights used for one scalar shortest-path calculation need a common relevant interpretation, such as travel minutes, monetary cost or distance in metres.

If a journey has multiple objectives, such as time and comfort, a separate decision model or justified conversion is needed. No universal numeric trade-off follows from the graph alone.

Worked example 13: compare time and distance priorities

In a separate invented two-route example, Route X is four kilometres and takes twelve minutes; Route Y is five kilometres and takes ten minutes.

X is shorter in distance; Y is quicker in time. Neither universally dominates without stating which quantity matters.

Dijkstra could minimise distance with distance weights or time with time weights. The outcome can change because the edge weights now encode a different objective.

A fixed weight may not describe a real journey at every hour

Actual travel time can depend on waiting, access, crossings, conditions and schedules. A route model assigning one fixed travel-time weight per edge assumes that number adequately represents the relevant situation.

If time changes with departure time, the model may require time-dependent weights and a more careful algorithm. A path shortest at one moment may not remain shortest at another.

This article intentionally uses fixed, nonnegative imaginary weights so the standard Dijkstra reasoning can be taught without overclaiming real-world travel predictions.

A direct straight line need not be a valid network edge

Two junctions drawn near each other on paper may have no direct connection. It is not legitimate to create a new edge simply because a ruler can draw a short segment between them.

Coordinate distance measures Euclidean separation; network shortest path uses available edges and their weights. Those are different mathematical objects.

See Bukit Timah coordinate distance and perpendicular bisectors for the related geometric calculation.

Worked example 14: a nonexistent shortcut

Our fictional network has no direct edge A–F. A learner draws a straight pencil line from A to F on the page and assigns it weight five by visual inspection.

That line is not part of the edge list and cannot be used as a route. The five-unit guess has no grounding in the defined graph.

The correct candidate must be a sequence of permitted edges such as A–C, C–B, B–E and E–F. Only then can the weights be added.

The priority queue is an efficiency tool

In a larger graph, repeatedly scanning every unsettled vertex to find the smallest tentative distance can be slow. Computer implementations often use a priority queue.

A priority queue retrieves an entry with the smallest current tentative distance. This does not alter the mathematical objective; it organises which vertex the algorithm processes next.

For our six-vertex graph, a handwritten table is sufficient. The programming structure is an enrichment idea that helps explain how the same reasoning scales to much larger networks.

Recording settled and tentative values separately

A useful classroom table has columns for vertex, tentative distance, predecessor and whether the vertex is settled.

After settling C, the tentative B distance is three, but it is not yet final until B becomes the smallest unsettled choice. After settling B, D and E are updated.

Marking status avoids the misconception that any number written into the table becomes permanently final immediately. The proof of finality depends on the selection step and nonnegative weights.

Worked example 15: the complete settlement order

Under the fictional graph and one valid tie-handling procedure, vertices settle in order A(0), C(2), B(3), D(8), E(10), F(13).

The numbers in parentheses are shortest total weights from A, not edge weights from the immediately previous settled vertex. They are cumulative.

The order is useful for checking a Dijkstra table. The final route does not necessarily follow this computational order; multiple optimal A-to-F routes have already been demonstrated.

A shortest-path tree need not include all tied routes

If an implementation stores one predecessor per vertex, it yields a shortest-path tree rooted at A, with one selected route to each reachable vertex.

An equally optimal alternative may be omitted from that chosen tree. A single tree is enough to demonstrate one shortest route to each vertex, but not necessarily to enumerate every tie.

The original network may have additional edges and equal shortest choices. Do not confuse the algorithm’s stored predecessor structure with the entire underlying graph.

Dijkstra does not solve every optimisation problem

If the task requires visiting several specified stops, covering every edge, obeying limited fuel or maximising rewards while controlling distance, the objective differs from a simple single-source shortest path.

Dijkstra addresses an important subproblem under nonnegative additive edge weights, but it is not a universal route planner for every possible constraint.

Recognising the problem class is part of Mathematics. Applying the correct algorithm to the wrong objective is still a modelling error.

Checking an alleged shortest route

A valid proposed shortest route must contain only permitted edges, satisfy any direction restrictions and accumulate the correct weight. But proving it is globally shortest requires more than checking its own sum.

Dijkstra’s completed distances provide a certificate under the model’s assumptions. Alternatively, in a sufficiently small graph, systematic enumeration can verify the minimum.

A pupil who finds one route of weight thirteen but never considers shorter possibilities has shown a candidate, not yet a proof of optimality.

Worked example 16: two candidates are not enough

Suppose a student evaluates A→B→D→F as fifteen and A→C→E→F as fifteen, then concludes the shortest distance is fifteen.

The ignored route A→C→B→E→F totals thirteen, disproving the claim. One missed connection can invalidate the conclusion.

This is why a systematic process beats selecting routes by visual prominence on a busy network diagram.

Primary foundations: add weighted paths

Younger Primary learners can begin with small networks containing three or four nodes, each edge labelled with a simple positive whole number.

Ask them to trace two permitted routes and add their totals, then identify which is smaller. The reasoning introduces weighted choices without formal algorithm terminology.

A pupil who confuses a junction count with an edge weight needs that distinction repaired before more complicated examples appear.

Lower Secondary progression: organised tables and inequalities

Secondary learners can represent weights in a table, compare cumulative totals, use inequalities and learn why tentative values may improve as new routes are considered.

The early objective is clear, sequential reasoning: define the graph, check every allowed edge, update a minimum and keep track of the route.

A full implementation of Dijkstra’s algorithm is optional enrichment depending on current subject and readiness, not an assumed requirement for every Mathematics paper.

Upper-level extension: algorithms and proof of correctness

For students ready for proof, the key invariant is that each settled vertex’s distance is optimal when all edge weights are nonnegative and the smallest tentative value is chosen.

A proof examines any hypothetical shorter route to a settled vertex and considers the first not-yet-settled edge crossing the settled boundary. Nonnegative weights prevent that alternative from undercutting the selected minimum.

This formal reasoning explains the algorithm rather than merely teaching a mechanical table.

Common error 1: choose the fewest edges

A learner prefers three edges totaling fifteen to five edges totaling thirteen because three is numerically smaller than five.

The mistake is selecting edge count rather than the stated weighted sum as the objective. Ask which unit is being minimised.

The correction is to write each candidate’s edge-weight total explicitly before comparing.

Common error 2: settle a vertex before it is minimal

A pupil may settle D at tentative ten immediately after examining C, even though B has tentative three.

Dijkstra’s rule chooses the smallest unsettled tentative distance, which in that stage is B. Processing B reduces D to eight.

The pupil needs to read the whole table rather than simply move through the vertices in alphabetic or drawing order.

Common error 3: ignore equal alternatives

When D offers E a cost of ten and E already has tentative ten through B, one route remains optimal even if the stored predecessor does not change.

If the question demands all shortest paths, the equality must be recorded. Otherwise the answer may state the correct minimum but omit a valid route.

This is an output-requirement error, not necessarily a shortest-distance error.

Common error 4: use a graph with negative weights unchanged

A standard Dijkstra procedure depends on nonnegative edge weights for its settled-distance guarantee.

If a negative edge is introduced, the learner must reconsider the method. The fact that some examples happen to produce correct output under a misapplied procedure does not prove the method is reliable.

A good tutorial explains the assumption before allowing students to memorise the algorithm.

A twenty-minute home diagnostic

Minutes 1–5: Read the six-vertex edge list. Compare two fifteen-unit routes and ask whether either proves a global minimum.

Minutes 6–10: Start Dijkstra at A. Settle C=2, then improve B from four to three. Ask why B is chosen next.

Minutes 11–15: Use B to update D=8 and E=10; use D to offer a second equal predecessor for E. Explain the tie.

Minutes 16–20: Use E to update F=13 and reconstruct both thirteen-unit routes. Ask why a weight total is not automatically metres or minutes.

A seven-day practice sequence

Day one distinguishes vertices, edges and weights. Day two adds route totals. Day three finds competing routes with different edge counts.

Day four introduces tentative and settled distances. Day five practises relaxation. Day six handles ties and edge removals. Day seven uses a new graph where the student must reconstruct the shortest route and justify the method’s assumptions.

If addition of cumulative weights is unreliable, repair that prerequisite before increasing the graph size.

Five challenge questions with answers

A. What is the total weight of A→B→D→F? Answer: 4+5+6=15.

B. What is the total of A→C→B→E→F? Answer: 2+1+7+3=13.

C. When C of distance two reaches B over edge weight one, what is B’s improved tentative distance? Answer: three.

D. If D has distance eight and edge D–E weighs two, what candidate does it offer E? Answer: ten, tying E’s previously known total.

E. Can standard Dijkstra’s settling guarantee be assumed for arbitrary negative edges? Answer: no.

Frequently asked questions

Is the shortest path always the route with the fewest edges?

No. With unequal weights, a route containing more edges can have a smaller total cost.

Does Dijkstra require nonnegative weights?

Yes, the standard algorithm’s settled-distance correctness guarantee assumes nonnegative edge weights.

Can two different routes share the same shortest total?

Yes. Our fictional example has two thirteen-unit routes from A to F.

Is Dijkstra the same as an Euler-trail algorithm?

No. Dijkstra minimises weight between vertices; an Euler trail covers every edge exactly once where possible.

What is a tentative distance?

It is the best route total discovered so far to a vertex, before that vertex’s distance has been finalised.

Does a priority queue change the mathematical answer?

No. It is a data structure that helps choose the smallest tentative entry efficiently.

Are the routes actual Bukit Timah walking directions?

No. The graph, edge weights and closures are all fictional classroom models.

Can the weights represent time instead of distance?

Yes, if every edge uses a consistent, valid time-based model. Different edge-weight meanings can produce different shortest routes.

How does a parent recognise progress?

The learner can name the objective, read an edge list, relax distances systematically, respect all constraints and independently verify the reconstructed route.

The SEAB 2027 G3 syllabus directory provides current Singapore Mathematics course context. Dijkstra’s algorithm is treated here as graph-theory enrichment rather than an automatic requirement for every G3 Mathematics candidate.

For a contrasting network objective read Mathematics in Bukit Timah: Euler trails and connections, and for shortest grid route counting read Pascal’s triangle and combinations. The immutable Clementi Secondary 1 Mathematics small-group tutorial reference anchors definitions, worked methods, error diagnosis and independent checks.

The durable habit is to state what every edge weight means, choose the right route objective, follow the algorithm’s assumptions, check all valid connections and prove the selected total rather than trusting the first attractive route.

Other Mathematics in Bukit Timah articles in this four-part batch: Piecewise functions and tiered prices · Quartiles, box plots and IQR · Matrix transformations and operation order. These original lessons develop different relationships through fictional examples, official curriculum context, worked checks and clear limits on model interpretation.

Read the other three Mathematics in Bukit Timah articles in this batch: Piecewise functions and pricing thresholds · Quartiles, box plots and interquartile range · Matrix transformations and operation order. Each companion guide teaches a distinct mathematical relationship through worked examples, checks and clearly defined models.

Discover more from eduKate Singapore

Subscribe now to keep reading and get access to the full archive.

Continue reading