Quickstart
This example builds a complete Daitum model for a resource allocation problem: given a budget, allocate quantities of items to maximise total value while minimising cost. Each item has diminishing returns — the more you buy, the less value each additional unit adds — so the solver must spread the budget intelligently.
Model definition
Use daitum_model.ModelBuilder to define tables, fields, and formulas.
import daitum_model.formulas as f
from daitum_model import DataType, ModelBuilder
model = ModelBuilder()
# --- Table ---
items = model.add_data_table("Items")
items.set_key_column("Name")
name = items.add_data_field("Name", DataType.STRING)
unit_cost = items.add_data_field("Unit Cost", DataType.DECIMAL)
base_value = items.add_data_field("Base Value", DataType.DECIMAL)
quantity = items.add_data_field("Quantity", DataType.INTEGER)
min_qty = items.add_data_field("Min Qty", DataType.INTEGER)
max_qty = items.add_data_field("Max Qty", DataType.INTEGER)
# Row-level cost
row_cost = items.add_calculated_field("Row Cost", unit_cost * quantity)
# Row-level value with diminishing returns: value grows logarithmically with quantity,
# so each additional unit adds less value than the previous one.
diminish_rate = model.add_parameter("DIMINISH_RATE", DataType.DECIMAL, 20.0)
diminished_quantity = f.LOG(1.0 + diminish_rate * quantity) / f.LOG(1.0 + diminish_rate)
row_value = items.add_calculated_field("Row Value", base_value * diminished_quantity)
# --- Model-level aggregates ---
total_cost = model.add_calculation("TOTAL_COST", f.SUM(items["Row Cost"]))
total_value = model.add_calculation("TOTAL_VALUE", f.SUM(items["Row Value"]))
# --- User-editable budget ---
budget = model.add_parameter("BUDGET", DataType.DECIMAL, 10_000.0)
UI definition
Use daitum_ui.ui_builder.UiBuilder to define what the user sees. Pass field IDs
to add_field() to include columns in the table view, and
attach set_cell_style() to format numeric values. The
top-level dashboard combines a horizontal summary of model-level totals with the items
table beneath, arranged with GridLayout.
from daitum_ui.layout import FlexDirection
from daitum_ui.tabular import ViewField
from daitum_ui.ui_builder import UiBuilder
from daitum_ui.form_view import FormVariant
ui = UiBuilder()
items_view = ui.add_table_view(items)
items_view.add_field("Name")
items_view.add_field("Unit Cost").set_cell_style(display_format="$#,##0.00")
items_view.add_field("Base Value").set_cell_style(display_format="#,##0.00")
items_view.add_field("Quantity")
items_view.add_field("Min Qty")
items_view.add_field("Max Qty")
totals_view = ui.add_form_view()
totals_view.set_columns(2, "min-content")
totals_view.add_label("Budget", 0, 0).set_variant(FormVariant.HEADER)
totals_view.add_label("Total Cost", 1, 0).set_variant(FormVariant.HEADER)
totals_view.add_label("Total Value", 2, 0).set_variant(FormVariant.HEADER)
totals_view.add_number_input(budget, 0, 1).set_display_format("$#,##0.00")
totals_view.add_number_input(total_cost, 1, 1).set_display_format(
"$#,##0.00"
).add_conditional_read_only(True)
totals_view.add_number_input(total_value, 2, 1).set_display_format(
"#,##0.00"
).add_conditional_read_only(True)
dashboard_view = (
ui.add_flex_view(display_name="Dashboard").set_flex_direction(FlexDirection.ROW).set_gap("30px")
)
dashboard_view.add_child(items_view, width="740px")
dashboard_view.add_child(totals_view)
ui.add_navigation_item(dashboard_view)
ui.set_default_view(dashboard_view)
Configuration
Use daitum_configuration.ConfigurationBuilder to wire up the algorithm, decision
variables, objectives, and constraints.
For field-based decision variables (where the solver adjusts a value per row), you must
provide the source table via dv_table, and pass fields as the min/max bounds.
from daitum_configuration import (
ConfigurationBuilder,
DVType,
ModelConfiguration,
Priority,
VariableNeighbourhoodSearch,
)
model_cfg = ModelConfiguration()
(
model_cfg.add_decision_variable(quantity, dv_table=items, dv_type=DVType.RANGE)
.set_min(min_qty)
.set_max(max_qty)
)
# Two competing objectives: spend less, gain more
model_cfg.add_objective(total_cost, maximise=False, priority=Priority.LOW, name="Cost")
model_cfg.add_objective(total_value, maximise=True, priority=Priority.HIGH, name="Value")
# Hard constraint: total spend must not exceed the budget
model_cfg.add_constraint(total_cost).set_upper_bound(budget).set_name("Budget")
config = ConfigurationBuilder()
algorithm = VariableNeighbourhoodSearch(offspring_size=16, time_limit=90)
config.set_algorithm(algorithm)
config.set_model_configuration(model_cfg)
Serialise to JSON
Each artefact serialises to a dict. Write the files alongside any input data prepared
through daitum_model.data_processor.prepare_data(), then bundle them into a ZIP
for upload to the Daitum platform.
import pathlib
model_directory = pathlib.Path.cwd() / "model-files"
data_directory = pathlib.Path.cwd() / "data"
model.write_to_file(model_directory)
ui.write_to_file(model_directory)
config.write_to_file(model_directory)
from daitum_model import data_processor
data_processor.prepare_data(model, str(data_directory), str(model_directory))
import shutil
model_name = "BudgetOptimiser"
shutil.make_archive(model_name, "zip", model_directory)
Next steps
Explore the Introduction to Modelling for a broader introduction to modelling concepts.
Browse the API reference for daitum-model, daitum-ui, and daitum-configuration.