docs: def solve(self, scenario, solver):
          """
          Decompose each cluster into separate units and try to optimize them
          separately
          :param scenario:
          :param solver: Solver that may be used to optimize partial networks
          """
          clusters = set(self.clustering.busmap.values)
          n = len(clusters)
          self.stats = {'clusters': pd.DataFrame(
              index=sorted(clusters),
              columns=["decompose", "spread", "transfer"])}
          profile = cProfile.Profile()
          for i, cluster in enumerate(sorted(clusters)):
              print('---')
              print('Decompose cluster %s (%d/%d)' % (cluster, i+1, n))
              profile.enable()
              t = time.time()
              partial_network, externals = self.construct_partial_network(
                      cluster,
                      scenario)
              profile.disable()
              self.stats['clusters'].loc[cluster, 'decompose'] = time.time() - t
              print('Decomposed in ',
                    self.stats['clusters'].loc[cluster, 'decompose'])
              t = time.time()
              profile.enable()
              self.solve_partial_network(cluster, partial_network, scenario,
                                         solver)
              profile.disable()
              self.stats['clusters'].loc[cluster, 'spread'] = time.time() - t
              print('Result distributed in ',
                    self.stats['clusters'].loc[cluster, 'spread'])
              profile.enable()
              t = time.time()
              self.transfer_results(partial_network, externals)
              profile.disable()
              self.stats['clusters'].loc[cluster, 'transfer'] = time.time() - t
              print('Results transferred in ',
                    self.stats['clusters'].loc[cluster, 'transfer'])
  
          profile.enable()
          t = time.time()
          print('---')
          fs = (mc("sum"), mc("sum"))
          for bt, ts in (
                  ('generators', {'p': fs, 'q': fs}),
                  ('storage_units', {'p': fs, 'state_of_charge': fs, 'q': fs})):
              print("Attribute sums, {}, clustered - disaggregated:" .format(bt))
              cnb = getattr(self.clustered_network, bt)
              onb = getattr(self.original_network, bt)
              print("{:>{}}: {}".format('p_nom_opt', 4 + len('state_of_charge'),
                  reduce(lambda x, f: f(x), fs[:-1], cnb['p_nom_opt'])
                      -
                      reduce(lambda x, f: f(x), fs[:-1], onb['p_nom_opt'])))
  
              print("Series sums, {}, clustered - disaggregated:" .format(bt))
              cnb = getattr(self.clustered_network, bt + '_t')
              onb = getattr(self.original_network, bt + '_t')
              for s in ts:
                  print("{:>{}}: {}".format(s, 4 + len('state_of_charge'),
                      reduce(lambda x, f: f(x), ts[s], cnb[s])
                      -
                      reduce(lambda x, f: f(x), ts[s], onb[s])))
          profile.disable()
          self.stats['check'] = time.time() - t
          print('Checks computed in ', self.stats['check'])