docs: def dispatch(self, inputs=None, outputs=None, cutoff=None, inputs_dist=None,
                   wildcard=False, no_call=False, shrink=False,
                   rm_unused_nds=False, select_output_kw=None, _wait_in=None,
                   stopper=None, executor=False, sol_name=()):
          """
          Evaluates the minimum workflow and data outputs of the dispatcher
          model from given inputs.
  
          :param inputs:
              Input data values.
          :type inputs: dict[str, T], list[str], iterable, optional
  
          :param outputs:
              Ending data nodes.
          :type outputs: list[str], iterable, optional
  
          :param cutoff:
              Depth to stop the search.
          :type cutoff: float, int, optional
  
          :param inputs_dist:
              Initial distances of input data nodes.
          :type inputs_dist: dict[str, int | float], optional
  
          :param wildcard:
              If True, when the data node is used as input and target in the
              ArciDispatch algorithm, the input value will be used as input for
              the connected functions, but not as output.
          :type wildcard: bool, optional
  
          :param no_call:
              If True data node estimation function is not used and the input
              values are not used.
          :type no_call: bool, optional
  
          :param shrink:
              If True the dispatcher is shrink before the dispatch.
  
              .. seealso:: :func:`shrink_dsp`
          :type shrink: bool, optional
  
          :param rm_unused_nds:
              If True unused function and sub-dispatcher nodes are removed from
              workflow.
          :type rm_unused_nds: bool, optional
  
          :param select_output_kw:
              Kwargs of selector function to select specific outputs.
          :type select_output_kw: dict, optional
  
          :param _wait_in:
              Override wait inputs.
          :type _wait_in: dict, optional
  
          :param stopper:
              A semaphore to abort the dispatching.
          :type stopper: multiprocess.Event, optional
  
          :param executor:
              A pool executor id to dispatch asynchronously or in parallel.
          :type executor: str, optional
  
          :param sol_name:
              Solution name.
          :type sol_name: tuple[str], optional
  
          :return:
              Dictionary of estimated data node outputs.
          :rtype: schedula.utils.sol.Solution
  
          **--------------------------------------------------------------------**
  
          **Example**:
  
          A dispatcher with a function :math:`log(b - a)` and two data `a` and `b`
          with default values:
  
          .. dispatcher:: dsp
             :opt: graph_attr={'ratio': '1'}
  
              >>> dsp = Dispatcher(name='Dispatcher')
              >>> dsp.add_data(data_id='a', default_value=0)
              'a'
              >>> dsp.add_data(data_id='b', default_value=5)
              'b'
              >>> dsp.add_data(data_id='d', default_value=1)
              'd'
              >>> from math import log
              >>> def my_log(a, b):
              ...     return log(b - a)
              >>> def my_domain(a, b):
              ...     return a < b
              >>> dsp.add_function('log(b - a)', function=my_log,
              ...                  inputs=['c', 'd'],
              ...                  outputs=['e'], input_domain=my_domain)
              'log(b - a)'
              >>> dsp.add_function('min', function=min, inputs=['a', 'b'],
              ...                  outputs=['c'])
              'min'
  
          Dispatch without inputs. The default values are used as inputs:
  
          .. dispatcher:: outputs
             :opt: graph_attr={'ratio': '1'}
             :code:
  
              >>> outputs = dsp.dispatch()
              >>> outputs
              Solution([('a', 0), ('b', 5), ('d', 1), ('c', 0), ('e', 0.0)])
  
          Dispatch until data node `c` is estimated:
  
          .. dispatcher:: outputs
             :opt: graph_attr={'ratio': '1'}
             :code:
  
              >>> outputs = dsp.dispatch(outputs=['c'])
              >>> outputs
              Solution([('a', 0), ('b', 5), ('c', 0)])
  
          Dispatch with one inputs. The default value of `a` is not used as
          inputs:
  
          .. dispatcher:: outputs
             :opt: graph_attr={'ratio': '1'}
             :code:
  
              >>> outputs = dsp.dispatch(inputs={'a': 3})
              >>> outputs
              Solution([('a', 3), ('b', 5), ('d', 1), ('c', 3)])
          """
  
          dsp = self
  
          if not no_call:
              if shrink:  # Pre shrink.
                  dsp = self.shrink_dsp(
                      inputs, outputs, cutoff, inputs_dist, wildcard
                  )
              elif outputs:
                  dsp = self.get_sub_dsp_from_workflow(
                      outputs, self.dmap, reverse=True, blockers=inputs,
                      wildcard=wildcard
                  )
  
          # Initialize.
          self.solution = sol = self.solution.__class__(
              dsp, inputs, outputs, wildcard, cutoff, inputs_dist, no_call,
              rm_unused_nds, _wait_in, full_name=sol_name
          )
  
          # Dispatch.
          sol._run(stopper=stopper, executor=executor)
  
          if select_output_kw:
              return selector(dictionary=sol, **select_output_kw)
  
          # Return the evaluated data outputs.
          return sol