diff --git a/examples/studiMain.cpp b/examples/studiMain.cpp
index cdbf72c95106489db18c6fafd4f60cba5c187b72..9040968028892decce7b78dc6a8096b4e1f80f3d 100644
--- a/examples/studiMain.cpp
+++ b/examples/studiMain.cpp
@@ -5,6 +5,15 @@ void superDummy();
 void advancedDummy();
 void bubblesort();
 
+void setup1()
+{
+    cute::logMessage("1");
+}
+void setup2()
+{
+    cute::logMessage("2");
+}
+
 // Is run once at startup.
 void setup()
 {
@@ -18,8 +27,8 @@ void setup()
     cute::setProgress(69);
     cute::setPlotVisible(1);
     cute::setStatusMessage("Hallo TEC");
-    cute::registerAlgorithm(superDummy, "DummyAlgo");
-    cute::registerAlgorithm(advancedDummy, "Problem");
+    cute::registerAlgorithm(superDummy, "DummyAlgo", setup1);
+    cute::registerAlgorithm(advancedDummy, "Problem", setup2);
     cute::registerAlgorithm(bubblesort, "Bubblesort");
     cute::setProblemFile("example.csv");
     cute::setProblemSize(4);
diff --git a/include/cute.h b/include/cute.h
index 5e21906d99d7c00c3680e1f0041fcac935532a67..64151fd567d06cb8d08a53a53798da0c9882feed 100644
--- a/include/cute.h
+++ b/include/cute.h
@@ -113,7 +113,7 @@ namespace cute
     void DYNAMIC setAxisTitles(int plot, const std::string& x, const std::string& y);
     void DYNAMIC setAxisVisible(int plot, bool x, bool y);
 
-    void DYNAMIC registerAlgorithm(void (*func)(), const std::string& name);
+    void DYNAMIC registerAlgorithm(void (*func)(), const std::string& name, void (*localSetup)() = nullptr);
 
     void DYNAMIC plotPoint(const Point&          point,
                            int                   plot       = 0,
diff --git a/src/configPanel.cpp b/src/configPanel.cpp
index 98c1da57092cb1f6ea8a9ce8b6ba12e9d97c92d3..22e1f34c7a319a729b0aaab1f5fb8bc518968ed9 100644
--- a/src/configPanel.cpp
+++ b/src/configPanel.cpp
@@ -33,6 +33,9 @@ ConfigPanel::ConfigPanel(QWidget* parent) : QDockWidget{parent}
     verbosityBox->setCurrentIndex(4);
     runButton = new QPushButton("Start");
     f->layout()->addWidget(runButton);
+    setupButton = new QPushButton("Setup");
+    f->layout()->addWidget(setupButton);
+    setupButton->setVisible(false);
 
 
     fileWidget = new QWidget();
@@ -139,6 +142,12 @@ void ConfigPanel::setGenUnlocked()
     pasteBox->setDisabled(false);
 }
 
+void ConfigPanel::switchButtons(bool setup)
+{
+    runButton->setVisible(!setup);
+    setupButton->setVisible(setup);
+}
+
 void ConfigPanel::onOpenButton()
 {
     QString filter = "CSV Files (*.csv)";
diff --git a/src/configPanel.h b/src/configPanel.h
index 2ce74a3226b54ddfc4e064e65e29159d9d382875..30b568d2253c7c681ab5a007c62454bcc3f5d630 100644
--- a/src/configPanel.h
+++ b/src/configPanel.h
@@ -22,6 +22,7 @@ private:
 
 public:
     QPushButton*    runButton;      ///< Used to Start and Stop the Algorithm.
+    QPushButton*    setupButton;    ///< Used to run the localSetup function of the Algorithm.
     QPushButton*    openButton;     ///< Used to Select a File via QFileDialog.
     QLineEdit*      fileLine;       ///< Shows path and filename and allows editing it.
     QPlainTextEdit* pasteBox;       ///< Used to enter csv data via drag n drop or copy and paste.
@@ -43,6 +44,7 @@ public slots:
     void setRunning(bool running);
     void setGenLocked();
     void setGenUnlocked();
+    void switchButtons(bool setup);
 
 signals:
     void previewButtonClicked(); ///< Signal emitted, when one of the Preview Buttons was clicked.
diff --git a/src/control.cpp b/src/control.cpp
index a307fda8b77b2754827ea73430ad468fa693d234..9dc3d5906c102b370d691c7af80cade1ffe19c0f 100644
--- a/src/control.cpp
+++ b/src/control.cpp
@@ -49,6 +49,9 @@ void Control::makeConnections()
     connect(cc, &CuteControl::s_undo, this, &Control::undo);
     connect(this, &Control::endThread, cc, &CuteControl::end);
     connect(w->configPanel->runButton, &QPushButton::clicked, this, &Control::onRunButton);
+    connect(w->configPanel->setupButton, &QPushButton::clicked, this, &Control::onSetupButton);
+    connect(
+        w->configPanel->algoBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Control::onAlgoSelected);
     connect(w->configPanel, &ConfigPanel::previewButtonClicked, this, &Control::onPreviewButton);
     connect(w->configPanel, &ConfigPanel::lockButtonClicked, this, &Control::onLockButton);
     connect(w, &MainWindow::saveProblem, this, &Control::saveProblem);
@@ -91,7 +94,15 @@ int Control::run(void (*userSetup)())
         userSetup();
         w->show();
         if (autorun)
-            startThread(algorithms.front().first);
+        {
+            if (algorithms.front().localSetup != nullptr)
+            {
+                algorithms.front().localSetup();
+                lastAlgorithmRun = algorithms.front();
+                w->configPanel->switchButtons(false);
+            }
+            startThread(algorithms.front().algorithm);
+        }
         int result = a.exec();
         running    = false;
         return result;
@@ -283,9 +294,9 @@ void Control::setAxisVisible(int plot, bool x, bool y)
  * @param func The function pointer to be called by the AlgoThread.
  * @param name The name to be displayed in the ConfigPanels QCombobox algoBox.
  */
-void Control::registerAlgorithm(void (*func)(), const QString name)
+void Control::registerAlgorithm(void (*func)(), const QString name, void (*setup)())
 {
-    algorithms.emplace_back(func, name);
+    algorithms.push_back({func, setup, name});
     w->addAlgorithm(name);
 }
 
@@ -355,7 +366,7 @@ void Control::onRunButton()
     if (!thread)
     {
         int  index = w->configPanel->algoBox->currentIndex();
-        auto func  = algorithms[index].first;
+        auto func  = algorithms[index].algorithm;
         startThread(func);
     }
     else
@@ -364,6 +375,36 @@ void Control::onRunButton()
     }
 }
 
+void Control::onSetupButton()
+{
+    int  index = w->configPanel->algoBox->currentIndex();
+    auto setup = algorithms[index].localSetup;
+    if (setup != nullptr)
+    {
+        setup();
+        lastAlgorithmRun = algorithms[index];
+        w->configPanel->switchButtons(false);
+    }
+}
+
+/**
+ * @brief
+ * @param index
+ * @todo the current index changes on construction, so this gets called.
+ */
+void Control::onAlgoSelected(int index)
+{
+    auto setup = algorithms[index].localSetup;
+    if (setup != lastAlgorithmRun.localSetup && setup != nullptr)
+    {
+        w->configPanel->switchButtons(true);
+    }
+    else
+    {
+        w->configPanel->switchButtons(false);
+    }
+}
+
 /**
  * @brief Change the problem widget stack to random generation and set the given size.
  * The setProblem functions only manipulate the entries in the View.abort
diff --git a/src/control.h b/src/control.h
index 3e9027bbe20b24b3345f6ec0425e337de714aa51..c40ae689d4ed72a75689437095da26a32623678e 100644
--- a/src/control.h
+++ b/src/control.h
@@ -12,13 +12,22 @@
 class Control : public QObject
 {
     Q_OBJECT
+private:
+    struct Algorithm
+    {
+        void (*algorithm)();
+        void (*localSetup)();
+        QString name;
+    };
+
 private:
     Control() = default;
     virtual ~Control() { stopThread(); }
     MainWindow*                                          w;
-    std::vector<std::pair<void (*)(), QString>>          algorithms;
+    std::vector<Algorithm>                               algorithms;
     bool                                                 threadRunning;
     bool                                                 autorun;
+    Algorithm                                            lastAlgorithmRun = Algorithm();
     AlgoThread*                                          thread;
     void                                                 startThread(void (*func)());
     void                                                 makeConnections();
@@ -41,7 +50,7 @@ public:
     }
     static Control& get() { return getInstance(); }
     int             run(void (*setup)());
-    void            registerAlgorithm(void (*func)(), const QString name);
+    void            registerAlgorithm(void (*func)(), const QString name, void (*setup)() = nullptr);
 public slots:
     void enableAutorun(bool run) { autorun = run; }
     void stopThread();
@@ -57,6 +66,8 @@ public slots:
     void setAxisTitles(int plot, QString x, QString y);
     void setAxisVisible(int plot, bool x, bool y);
     void onRunButton();
+    void onSetupButton();
+    void onAlgoSelected(int index);
     void onPreviewButton();
     void setProblemSize(int n);
     void setProblemFile(QString path);
diff --git a/src/cute.cpp b/src/cute.cpp
index a9575bc3f923e0ca6a59af2720ad61893fc3c774..084eb1861a7e618ac4ae46a6b6663eac34cf3c3b 100644
--- a/src/cute.cpp
+++ b/src/cute.cpp
@@ -139,10 +139,10 @@ void cute::setAxisVisible(int plot, bool x, bool y)
 }
 
 
-void cute::registerAlgorithm(void (*func)(), const std::string& name)
+void cute::registerAlgorithm(void (*func)(), const std::string& name, void (*localSetup)())
 {
     timerPauseInternal();
-    Control::get().registerAlgorithm(func, name.c_str());
+    Control::get().registerAlgorithm(func, name.c_str(), localSetup);
     timerResumeInternal();
 }