code: def knn_graph_strategy(
      draw,
      num_samples,
      k_neighbors,
      min_distance=0.0,
      max_distance=100.0,
  ):
      """
      Generate a K-nearest neighbors (KNN) graph based on the given parameters.
  
      Parameters
      ----------
      draw: A function used to draw values from search strategies.
  
      num_samples (int or SearchStrategy): The number of samples in the graph.
          If a SearchStrategy is provided, a value will be drawn from it.
  
      k_neighbors (int or SearchStrategy): The number of nearest neighbors to consider for each sample.
          If a SearchStrategy is provided, a value will be drawn from it.
  
      Returns
      -------
      knn_graph : csr_matrix
          The KNN graph represented as a sparse matrix.
  
      Notes
      -----
      - The KNN graph is generated based on a symmetric distance matrix.
      - The distance matrix is computed using randomly generated upper triangle values.
      - The diagonal of the distance matrix is set to infinity to avoid selecting a point as its own neighbor.
      - The K-nearest neighbors are computed based on the distance matrix.
      - The resulting KNN graph is returned as a sparse matrix in csr format.
      - The number of samples must be greater than the number of neighbors.
      - The KNN graph is not guaranteed to be connected (i.e. there may be isolated subgraphs).
      - The KNN graph is a directed graph (i.e. the edges are not symmetric).
      - The neighbors are sorted by distance in the CSR-formatted sparse matrix,
          so the first neighbor is the closest neighbor.
      """
      # If the argument is a strategy, draw a value from it.
      if isinstance(num_samples, st.SearchStrategy):
          num_samples = draw(num_samples)
  
      if isinstance(k_neighbors, st.SearchStrategy):
          k_neighbors = draw(k_neighbors)
  
      # Generate a symmetric distance matrix
      upper_triangle = [
          draw(
              st.lists(
                  st.floats(
                      min_value=min_distance,
                      max_value=max_distance,
                      allow_nan=False,
                      allow_infinity=False,
                      allow_subnormal=False,
                  ),
                  min_size=i,
                  max_size=i,
                  unique=True,
              )
          )
          for i in range(1, num_samples + 1)
      ]
  
      distance_matrix = np.zeros((num_samples, num_samples))
      for i, row in enumerate(upper_triangle):
          distance_matrix[i, : i + 1] = row
          distance_matrix[: i + 1, i] = row
  
      np.fill_diagonal(
          distance_matrix, np.inf
      )  # To ensure we don't select a point as its own neighbor
  
      # Compute k-nearest neighbors based on the distance matrix
      sorted_indices = np.argsort(distance_matrix, axis=1)
      kneighbor_indices = sorted_indices[:, :k_neighbors]
      kneighbor_distances = np.array(
          [
              distance_matrix[i, kneighbor_indices[i]]
              for i in range(num_samples)
          ]
      )
  
      knn_graph = csr_matrix(
          (
              kneighbor_distances.flatten(),
              kneighbor_indices.flatten(),
              np.arange(
                  0,
                  (kneighbor_distances.shape[0] * k_neighbors + 1),
                  k_neighbors,
              ),
          ),
          shape=(num_samples, num_samples),
      )
      return knn_graph
  
label_desc: Use image node_id 1 for calling a global function with example usage: knn_graph_strategy(draw, num_samples, k_neighbors, min_distance, max_distance) and returns: knn_graph