diff --git a/SimoxUtility/CMakeLists.txt b/SimoxUtility/CMakeLists.txt
index 364bf7a366e1c05395694dfec8b03cca84f9821f..95bf0823199ea31f5c79e36f8cc97c7eaa80a12d 100644
--- a/SimoxUtility/CMakeLists.txt
+++ b/SimoxUtility/CMakeLists.txt
@@ -220,6 +220,7 @@ SET(INCLUDES
     meta/enum/EnumNames.hpp
     meta/key_type.h
 
+    random/choice.h
 
     simox/SimoxPath.h
 
diff --git a/SimoxUtility/random.h b/SimoxUtility/random.h
new file mode 100644
index 0000000000000000000000000000000000000000..19a8006aa76d85a0ee1db71f1180a299d9e96f90
--- /dev/null
+++ b/SimoxUtility/random.h
@@ -0,0 +1,5 @@
+#pragma once
+
+// This file is generated!
+
+#include "random/choice.h"
diff --git a/SimoxUtility/random/choice.h b/SimoxUtility/random/choice.h
new file mode 100644
index 0000000000000000000000000000000000000000..51c86440ec06e7638f552d257ec25a813a04ca21
--- /dev/null
+++ b/SimoxUtility/random/choice.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <random>
+#include <stdexcept>
+#include <vector>
+
+#include <SimoxUtility/error/SimoxError.h>
+
+
+namespace simox::random
+{
+    /**
+     * Return a random element from the non-empty vector items.
+     *
+     * @throw `std::out_of_range` if items is empty.
+     */
+    template <class T, class RandomEngineT>
+    const T&
+    choice(const std::vector<T>& items, RandomEngineT& gen)
+    {
+        if (items.empty())
+        {
+            throw error::SimoxError("Cannot choose an item from an empty vector.");
+        }
+
+        std::uniform_int_distribution<size_t> distrib(0, items.size() - 1);
+        std::size_t index = distrib(gen);
+        return items.at(index);
+    }
+
+    template <class T>
+    const T&
+    choice(const std::vector<T>& items)
+    {
+        std::default_random_engine gen{std::random_device{}()};
+        return choice(items, gen);
+    }
+
+} // namespace simox::random