interval_graph.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """
  2. Generators for interval graph.
  3. """
  4. from collections.abc import Sequence
  5. import networkx as nx
  6. __all__ = ["interval_graph"]
  7. def interval_graph(intervals):
  8. """Generates an interval graph for a list of intervals given.
  9. In graph theory, an interval graph is an undirected graph formed from a set
  10. of closed intervals on the real line, with a vertex for each interval
  11. and an edge between vertices whose intervals intersect.
  12. It is the intersection graph of the intervals.
  13. More information can be found at:
  14. https://en.wikipedia.org/wiki/Interval_graph
  15. Parameters
  16. ----------
  17. intervals : a sequence of intervals, say (l, r) where l is the left end,
  18. and r is the right end of the closed interval.
  19. Returns
  20. -------
  21. G : networkx graph
  22. Examples
  23. --------
  24. >>> intervals = [(-2, 3), [1, 4], (2, 3), (4, 6)]
  25. >>> G = nx.interval_graph(intervals)
  26. >>> sorted(G.edges)
  27. [((-2, 3), (1, 4)), ((-2, 3), (2, 3)), ((1, 4), (2, 3)), ((1, 4), (4, 6))]
  28. Raises
  29. ------
  30. :exc:`TypeError`
  31. if `intervals` contains None or an element which is not
  32. collections.abc.Sequence or not a length of 2.
  33. :exc:`ValueError`
  34. if `intervals` contains an interval such that min1 > max1
  35. where min1,max1 = interval
  36. """
  37. intervals = list(intervals)
  38. for interval in intervals:
  39. if not (isinstance(interval, Sequence) and len(interval) == 2):
  40. raise TypeError(
  41. "Each interval must have length 2, and be a "
  42. "collections.abc.Sequence such as tuple or list."
  43. )
  44. if interval[0] > interval[1]:
  45. raise ValueError(
  46. f"Interval must have lower value first. " f"Got {interval}"
  47. )
  48. graph = nx.Graph()
  49. tupled_intervals = [tuple(interval) for interval in intervals]
  50. graph.add_nodes_from(tupled_intervals)
  51. while tupled_intervals:
  52. min1, max1 = interval1 = tupled_intervals.pop()
  53. for interval2 in tupled_intervals:
  54. min2, max2 = interval2
  55. if max1 >= min2 and max2 >= min1:
  56. graph.add_edge(interval1, interval2)
  57. return graph