void execute() {
        final String basePackageName = getClass().getPackage().getName();
        final ExecutorService executor = Executors.newCachedThreadPool();
        try {
            for (ProblemConfig problemConfig : problemConfigs) {
                System.out.println(problemConfig);
                for (SolverConfig solverConfig : problemConfig.getSolverConfigs()) {
                    final Class<?> cls = Class.forName(String.format("%s.%s.%s", basePackageName,
                            problemConfig.getPackageName(), solverConfig.getClassName()));
                    final Class<? extends ProblemSolver> solverCls = cls.asSubclass(ProblemSolver.class);
                    final ProblemSolver solver = solverCls.getConstructor().newInstance();
                    for (String datasetName : solverConfig.getDatasetNames()) {
                        final XYSeries series;
                        try {
                            series = solve(executor, solver, problemConfig.getPackageName(),
                                    solverConfig.getClassName(), datasetName);
                        } catch (RuntimeException e) {
                            if (e.getCause() instanceof TimeoutException) {
                                continue;
                            } else {
                                throw e;
                            }
                        }
                        if (Arrays.asList("small", "large", "large1", "large2").contains(datasetName)) {
                            renderGraph(solverConfig.getClassName(), series);
                        }
                    }
                }
            }
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        } finally {
            executor.shutdown();
        }
    }