.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/mdcev_no_outside_good/plot_gamma_forecasting.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_mdcev_no_outside_good_plot_gamma_forecasting.py: File gamma_forecasting.py Michel Bierlaire, EPFL Fri Jul 25 2025, 16:38:12 Forecasting with a MDCEV model and the "gamma_profile" specification. .. GENERATED FROM PYTHON SOURCE LINES 7-134 .. rst-class:: sphx-glr-script-out .. code-block:: none Example: gamma profile utility Forecasting observation 0 / 2 [10 draws] ============ Comparison =================== Brute force: {1: '19.3', 2: '191', 3: '184', 4: '106'} objective 75.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '19.5', 2: '190', 3: '185', 4: '105'} objective 75.9, constraint 500, choice set {1, 2, 3, 4} Difference between optimal utility with analytical [75.9] and brute force [75.89] algorithms. Solution with brute force: 1: 19.3, 2: 191, 3: 184, 4: 106 Solution with analytical: 1: 19.5, 2: 190, 3: 185, 4: 105 ============ Comparison =================== Brute force: {1: '96.5', 2: '184', 3: '148', 4: '71.4'} objective 48.1, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '95.6', 2: '184', 3: '148', 4: '71.9'} objective 48.1, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '98.8', 2: '224', 3: '128', 4: '48.6'} objective 55.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '97.5', 2: '227', 3: '126', 4: '49.4'} objective 55.2, constraint 500, choice set {1, 2, 3, 4} Difference between optimal utility with analytical [55.22] and brute force [55.22] algorithms. Solution with brute force: 1: 98.8, 2: 224, 3: 128, 4: 48.6 Solution with analytical: 1: 97.5, 2: 227, 3: 126, 4: 49.4 ============ Comparison =================== Brute force: {1: '36.5', 2: '160', 3: '271', 4: '32.7'} objective 70.3, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '36.5', 2: '160', 3: '271', 4: '32.7'} objective 70.3, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '69.3', 2: '227', 3: '169', 4: '35'} objective 65, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '69.3', 2: '227', 3: '169', 4: '35'} objective 65, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '43.4', 2: '262', 3: '150', 4: '44.3'} objective 54.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '43', 2: '264', 3: '148', 4: '45'} objective 54.9, constraint 500, choice set {1, 2, 3, 4} Difference between optimal utility with analytical [54.86] and brute force [54.86] algorithms. Solution with brute force: 1: 43.4, 2: 262, 3: 150, 4: 44.3 Solution with analytical: 1: 43, 2: 264, 3: 148, 4: 45 ============ Comparison =================== Brute force: {1: '38.6', 2: '190', 3: '208', 4: '63.7'} objective 52.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '38.6', 2: '189', 3: '209', 4: '63.7'} objective 52.2, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '49.2', 2: '247', 3: '143', 4: '61.2'} objective 47.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '49.1', 2: '248', 3: '141', 4: '61.6'} objective 47.2, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '42.5', 2: '197', 3: '197', 4: '63.6'} objective 56.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '42.4', 2: '195', 3: '198', 4: '63.7'} objective 56.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '48.4', 2: '256', 3: '163', 4: '32.7'} objective 68.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '48.5', 2: '257', 3: '162', 4: '32.7'} objective 68.2, constraint 500, choice set {1, 2, 3, 4} Forecasting observation 1 / 2 [10 draws] ============ Comparison =================== Brute force: {1: '41.4', 2: '196', 3: '226', 4: '37.2'} objective 66.5, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '41.6', 2: '194', 3: '227', 4: '37.1'} objective 66.5, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '58.4', 2: '138', 3: '260', 4: '44'} objective 63, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '59.2', 2: '136', 3: '261', 4: '43.8'} objective 63, constraint 500, choice set {1, 2, 3, 4} Difference between optimal utility with analytical [62.98] and brute force [62.98] algorithms. Solution with brute force: 1: 58.4, 2: 138, 3: 260, 4: 44 Solution with analytical: 1: 59.2, 2: 136, 3: 261, 4: 43.8 ============ Comparison =================== Brute force: {1: '51.4', 2: '189', 3: '204', 4: '55.8'} objective 75.6, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '51', 2: '187', 3: '206', 4: '56.3'} objective 75.6, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '33.5', 2: '233', 3: '213', 4: '21'} objective 90, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '33.5', 2: '232', 3: '214', 4: '20.9'} objective 90, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '46', 2: '237', 3: '181', 4: '36'} objective 59.4, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '46', 2: '237', 3: '181', 4: '36'} objective 59.4, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '53.9', 2: '249', 3: '168', 4: '29.7'} objective 79.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '54', 2: '249', 3: '167', 4: '29.7'} objective 79.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '55.7', 2: '129', 3: '281', 4: '33.9'} objective 65, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '55.7', 2: '129', 3: '281', 4: '33.9'} objective 65, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '75.9', 2: '182', 3: '180', 4: '61.8'} objective 59.4, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '75.1', 2: '182', 3: '181', 4: '62.4'} objective 59.4, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '54.6', 2: '204', 3: '192', 4: '49.1'} objective 103, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '54.6', 2: '203', 3: '193', 4: '49'} objective 103, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '63.6', 2: '224', 3: '187', 4: '24.7'} objective 77.1, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '63.7', 2: '224', 3: '188', 4: '24.7'} objective 77.1, constraint 500, choice set {1, 2, 3, 4} Forecasting observation 0 / 2 [2000 draws] Forecasting observation 1 / 2 [2000 draws] Execution time for 2000 draws with brute force algorithm: 12.3 seconds Forecasting observation 0 / 2 [2000 draws] Forecasting observation 1 / 2 [2000 draws] Execution time for 2000 draws with analytical algorithm: 0.608 seconds 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 51.518231 211.054094 187.229841 50.197834 std 23.130843 53.947558 53.337971 21.550578 min 8.728227 43.901284 44.890577 8.076306 25% 36.143132 175.047718 153.027933 36.446719 50% 47.029913 206.956391 182.614542 46.386606 75% 60.692928 242.079979 215.805571 59.587119 max 234.492435 408.033021 419.227802 366.715204 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 51.379089 210.774331 187.507669 50.338911 std 22.941211 54.448191 53.867760 21.476516 min 8.728471 43.905352 44.893016 8.076337 25% 36.194367 173.900701 152.041808 36.585668 50% 47.048983 206.302898 183.120942 46.715967 75% 60.471824 242.938136 217.143337 59.804237 max 234.449458 408.017802 419.227170 366.717718 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 53.343868 195.614404 213.815285 37.226442 std 22.464387 50.835646 52.409488 16.870743 min 10.628288 47.110956 52.865721 9.782055 25% 38.782480 161.272774 177.984059 26.807845 50% 48.828279 191.583525 209.828357 33.587426 75% 62.290773 225.470817 245.341326 43.262908 max 247.160308 408.160130 426.049392 177.230517 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 53.363183 195.091525 214.290462 37.254830 std 22.388807 51.122401 52.624925 16.869329 min 10.626606 47.111895 52.871675 9.781980 25% 38.782628 159.984587 178.026109 26.777725 50% 48.899298 190.640290 211.003794 33.561971 75% 62.348376 225.067649 246.438383 43.377101 max 247.026101 408.156280 426.049082 176.091517 | .. code-block:: Python import sys import time import numpy as np import pandas as pd from IPython.core.display_functions import display import biogeme.biogeme_logging as blog from biogeme.database import Database from biogeme.results_processing import EstimationResults from gamma_specification import the_gamma_profile from process_data import database logger = blog.get_screen_logger(level=blog.INFO) logger.info('Example: gamma profile utility') result_file = 'saved_results/gamma_profile.yaml' try: results = EstimationResults.from_yaml_file(filename=result_file) except FileNotFoundError as e: print(e) print(f'File {result_file} is missing.') sys.exit() the_gamma_profile.estimation_results = results # % # We apply the model only on the first two rows of the database. two_rows_of_database: Database = database.extract_rows([0, 1]) # % budget_in_hours = 500 # % # # Validation # % # As the implementation is still experimental, we compare the result obtained by the bruteforce algorithm and # the analytical algorithm for a few draws. # Note that minor discrepancies between the outcome of the two algorithms are likely to occur, due to numerical # imprecision, inevitable in finite arithmetic. # However, if there are major differences, it should be reported. # % number_of_draws = 10 # % # We generate the draws epsilons = [ np.random.gumbel( loc=0, scale=1, size=(number_of_draws, the_gamma_profile.number_of_alternatives) ) for _ in range(two_rows_of_database.num_rows()) ] # % # We first compare the results obtained from the brute force and the analytical algorithms, for each draw. the_gamma_profile.validate_forecast( database=two_rows_of_database, total_budget=budget_in_hours, epsilons=epsilons ) # % # # Forecasting # We use a larger number of draws to obtain the forecast. # % number_of_draws = 2000 # % # We generate the draws epsilons = [ np.random.gumbel( loc=0, scale=1, size=(number_of_draws, the_gamma_profile.number_of_alternatives) ) for _ in range(two_rows_of_database.num_rows()) ] # % # First, the brute force algorithm. start_time = time.time() optimal_consumptions_brute_force: list[pd.DataFrame] = the_gamma_profile.forecast( database=two_rows_of_database, total_budget=budget_in_hours, epsilons=epsilons, brute_force=True, ) end_time = time.time() # % print( f'Execution time for {number_of_draws} draws with brute force algorithm: {end_time-start_time:.3g} seconds' ) # % # Then, the analytical algorithm. start_time = time.time() optimal_consumptions_analytical: list[pd.DataFrame] = the_gamma_profile.forecast( database=two_rows_of_database, total_budget=budget_in_hours, epsilons=epsilons, brute_force=False, ) end_time = time.time() # % print( f'Execution time for {number_of_draws} draws with analytical algorithm: {end_time-start_time:.3g} seconds' ) # % # Results for the first observation, brute force method display(optimal_consumptions_brute_force[0].describe()) # % # Results for the first observation, analytical method display(optimal_consumptions_analytical[0].describe()) # % # Results for the second observation, brute force method display(optimal_consumptions_brute_force[1].describe()) # % # Results for the second observation, analytical method display(optimal_consumptions_analytical[1].describe()) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 14.301 seconds) .. _sphx_glr_download_auto_examples_mdcev_no_outside_good_plot_gamma_forecasting.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_gamma_forecasting.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_gamma_forecasting.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_gamma_forecasting.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_