TheAlgorithms/C-Sharp · error · ArgumentException

Adjacency matrix must be symmetric!

Error message

Adjacency matrix must be symmetric!

What it means

The matrix-based Prim solver requires an undirected graph, meaning the adjacency matrix must be symmetric: adjacencyMatrix[i,j] must equal adjacencyMatrix[j,i] (within 1e-6) for every pair of nodes. ValidateMatrix, called from Solve, throws ArgumentException on the first asymmetric pair it encounters. Asymmetric weights would give different edge costs depending on traversal direction, breaking Prim's correctness.

Solutions

  1. Mirror every weight: after setting adj[i,j], set adj[j,i] to the same value, or add a symmetrization loop over i<j before calling Solve.
  2. If the source graph is directed, convert to undirected by consistently combining each directional pair (e.g. take the min) before invoking the solver.
  3. Watch float precision: values must agree within 1e-6; recompute or round both cells from the same source value if drift is the issue.
  4. Pre-scan in caller code for the first (i,j) with Math.Abs(adj[i,j]-adj[j,i]) > 1e-6 to find the offending entry.

Example fix

// before
adj[2, 5] = 7.3f;

// after
adj[2, 5] = 7.3f;
adj[5, 2] = 7.3f; // keep both cells equal
Defensive patterns

Strategy: validation

Validate before calling

static bool IsSymmetric(float[,] adj)
{
    for (int i = 0; i < adj.GetLength(0); i++)
        for (int j = i + 1; j < adj.GetLength(1); j++)
            if (Math.Abs(adj[i, j] - adj[j, i]) > 1e-6)
                return false;
    return true;
}
if (!IsSymmetric(adj)) throw new ArgumentException("adjacency matrix is not symmetric");

Type guard

static bool IsUndirectedWeightMatrix(float[,] adj) =>
    adj != null && adj.GetLength(0) == adj.GetLength(1) && IsSymmetric(adj);

Try / catch

try
{
    var mst = prim.Solve(adj);
}
catch (ArgumentException ex) when (ex.Message == "Adjacency matrix must be symmetric!")
{
    // symmetrize the matrix, then retry
}

Prevention

When it happens

Trigger: Calling PrimMatrix.Solve with a square float[,] where at least one pair adj[i,j] and adj[j,i] differs by more than 1e-6 — typically because only the upper or lower triangle was filled, or directed weights were written per direction.

Common situations: Loading a directed graph's weight matrix directly into the solver; filling only half the matrix as an optimization; generating matrices with floating-point computations that are not order-symmetric; typos in hand-written test data.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of TheAlgorithms/C-Sharp@96e2905cab (2026-09-13). Data as JSON: /api/errors/c0a30cde4a6aec8d. Report an issue: GitHub.

Appendix: source

Thrown at Algorithms/Graph/MinimumSpanningTree/PrimMatrix.cs:94

    /// </summary>
    /// <param name="adjacencyMatrix">Adjacency matric to check.</param>
    private static void ValidateMatrix(float[,] adjacencyMatrix)
    {
        // Matrix should be square
        if (adjacencyMatrix.GetLength(0) != adjacencyMatrix.GetLength(1))
        {
            throw new ArgumentException("Adjacency matrix must be square!");
        }

        // Graph needs to be undirected and connected
        for (var i = 0; i < adjacencyMatrix.GetLength(0); i++)
        {
            var connection = false;
            for (var j = 0; j < adjacencyMatrix.GetLength(0); j++)
            {
                if (Math.Abs(adjacencyMatrix[i, j] - adjacencyMatrix[j, i]) > 1e-6)
                {
                    throw new ArgumentException("Adjacency matrix must be symmetric!");
                }

                if (!connection && float.IsFinite(adjacencyMatrix[i, j]))
                {
                    connection = true;
                }
            }

            if (!connection)
            {
                throw new ArgumentException("Graph must be connected!");
            }
        }
    }

    /// <summary>
    ///     Determine which node should be added next to the MST.
    /// </summary>

View on GitHub (pinned to 96e2905cab)