docs: def _initial_placement(movable_vertices, vertices_resources, machine, random):
      """For internal use. Produces a random, sequential initial placement,
      updating the resource availabilities of every core in the supplied machine.
  
      Parameters
      ----------
      movable_vertices : {vertex, ...}
          A set of the vertices to be given a random initial placement.
      vertices_resources : {vertex: {resource: value, ...}, ...}
      machine : :py:class:`rig.place_and_route.Machine`
          A machine object describing the machine into which the vertices should
          be placed.
  
          All chips hosting fixed vertices should have a chip_resource_exceptions
          entry which accounts for the allocated resources.
  
          When this function returns, the machine.chip_resource_exceptions will
          be updated to account for the resources consumed by the initial
          placement of movable vertices.
      random : :py:class`random.Random`
          The random number generator to use
  
      Returns
      -------
      {vertex: (x, y), ...}
          For all movable_vertices.
  
      Raises
      ------
      InsufficientResourceError
      InvalidConstraintError
      """
      # Initially fill chips in the system in a random order
      locations = list(machine)
      random.shuffle(locations)
      location_iter = iter(locations)
  
      # Greedily place the vertices in a random order
      movable_vertices = list(v for v in vertices_resources
                              if v in movable_vertices)
      random.shuffle(movable_vertices)
      vertex_iter = iter(movable_vertices)
  
      placement = {}
      try:
          location = next(location_iter)
      except StopIteration:
          raise InsufficientResourceError("No working chips in system.")
      while True:
          # Get a vertex to place
          try:
              vertex = next(vertex_iter)
          except StopIteration:
              # All vertices have been placed
              break
  
          # Advance through the set of available locations until we find a chip
          # where the vertex fits
          while True:
              resources_if_placed = subtract_resources(
                  machine[location], vertices_resources[vertex])
  
              if overallocated(resources_if_placed):
                  # The vertex won't fit on this chip, move onto the next chip
                  try:
                      location = next(location_iter)
                      continue
                  except StopIteration:
                      raise InsufficientResourceError(
                          "Ran out of chips while attempting to place vertex "
                          "{}".format(vertex))
              else:
                  # The vertex fits: record the resources consumed and move on to
                  # the next vertex.
                  placement[vertex] = location
                  machine[location] = resources_if_placed
                  break
  
      return placement