class LayoutOptimizerString:
  def __init__(
    self,
    nodes: list[list[str]],
    edges: list[list[tuple[str, str, int]]],
  ): ...
  def swap_nodes(self, temperature: float, max_iterations: int, layer_index: int) -> int: ...
  def cooldown(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, layer_index: int) -> int: ...
  def optimize(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, passes: int) -> int: ...
  def get_nodes(self) -> list[list[str]]: ...
  def count_crossings(self) -> int: ...

class HierarchyOptimizerString:
  def __init__(
    self,
    nodes: list[list[str]],
    edges: list[list[tuple[str, str, int]]],
    hierarchy: list[list[list[int]]],
  ): ...
  def swap_nodes(self, temperature: float, max_iterations: int, layer_index: int, granularity: int | None) -> int: ...
  def cooldown(
    self, start_temp: float, end_temp: float, steps: int, max_iterations: int, layer_index: int, granularity: int | None
  ) -> int: ...
  def optimize(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, passes: int) -> int: ...
  def get_nodes(self) -> list[list[str]]: ...
  def count_crossings(self) -> int: ...

class LayoutOptimizerInt:
  def __init__(
    self,
    nodes: list[list[int]],
    edges: list[list[tuple[int, int, int]]],
  ): ...
  def swap_nodes(self, temperature: float, max_iterations: int, layer_index: int) -> int: ...
  def cooldown(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, layer_index: int) -> int: ...
  def optimize(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, passes: int) -> int: ...
  def get_nodes(self) -> list[list[int]]: ...
  def count_crossings(self) -> int: ...

class HierarchyOptimizerInt:
  def __init__(
    self,
    nodes: list[list[int]],
    edges: list[list[tuple[int, int, int]]],
    hierarchy: list[list[list[int]]],
  ): ...
  def swap_nodes(self, temperature: float, max_iterations: int, layer_index: int, granularity: int | None) -> int: ...
  def cooldown(
    self, start_temp: float, end_temp: float, steps: int, max_iterations: int, layer_index: int, granularity: int | None
  ) -> int: ...
  def optimize(self, start_temp: float, end_temp: float, steps: int, max_iterations: int, passes: int) -> int: ...
  def get_nodes(self) -> list[list[int]]: ...
  def count_crossings(self) -> int: ...

def generate_multipartite_graph(n_nodes: list[int]) -> tuple[list[list[int]], list[list[tuple[int, int, int]]]]: ...
