.. 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_translated_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_translated_forecasting.py: File translated_forecasting.py Michel Bierlaire, EPFL Fri Jul 25 2025, 17:34:35 Forecasting with a MDCEV model and the "translated utility" specification. .. GENERATED FROM PYTHON SOURCE LINES 8-135 .. rst-class:: sphx-glr-script-out .. code-block:: none Example: translated utility Forecasting observation 0 / 2 [10 draws] ============ Comparison =================== Brute force: {1: '10.8', 2: '461', 3: '18.9', 4: '8.99'} objective 57, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '10.8', 2: '461', 3: '18.9', 4: '8.99'} objective 57, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '18.7', 2: '409', 3: '64.9', 4: '7.83'} objective 59.5, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '18.7', 2: '409', 3: '64.9', 4: '7.83'} objective 59.5, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '19', 2: '280', 3: '188', 4: '12.5'} objective 49.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '19', 2: '281', 3: '188', 4: '12.5'} objective 49.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '21.6', 2: '378', 3: '89.8', 4: '10.8'} objective 46.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '21.5', 2: '378', 3: '89.8', 4: '10.8'} objective 46.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '19.3', 2: '392', 3: '74.8', 4: '13.9'} objective 50.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '19.3', 2: '392', 3: '74.9', 4: '13.9'} objective 50.2, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '6.32', 2: '464', 3: '23.4', 4: '6.64'} objective 61.2, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '6.33', 2: '464', 3: '23.4', 4: '6.63'} objective 61.2, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '22.8', 2: '387', 3: '68.4', 4: '22.1'} objective 53.1, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '22.8', 2: '387', 3: '68.4', 4: '22.1'} objective 53.1, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '17.2', 2: '357', 3: '112', 4: '13.7'} objective 42.6, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '17.2', 2: '357', 3: '112', 4: '13.7'} objective 42.6, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '30.1', 2: '386', 3: '69.7', 4: '13.7'} objective 60.8, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '30.1', 2: '386', 3: '69.7', 4: '13.7'} objective 60.8, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '21.1', 2: '340', 3: '129', 4: '10.1'} objective 45.4, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '21.1', 2: '340', 3: '129', 4: '10.1'} objective 45.4, constraint 500, choice set {1, 2, 3, 4} Forecasting observation 1 / 2 [10 draws] ============ Comparison =================== Brute force: {1: '15', 2: '396', 3: '80.6', 4: '8.81'} objective 55.6, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '15', 2: '396', 3: '80.6', 4: '8.81'} objective 55.6, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '33.8', 2: '386', 3: '65.9', 4: '14.1'} objective 57.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '33.8', 2: '386', 3: '65.9', 4: '14.1'} objective 57.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '21.4', 2: '338', 3: '132', 4: '9.15'} objective 51.1, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '21.4', 2: '338', 3: '132', 4: '9.15'} objective 51.1, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '23', 2: '408', 3: '59.4', 4: '9.98'} objective 60.8, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '23', 2: '408', 3: '59.4', 4: '9.98'} objective 60.8, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '18.7', 2: '377', 3: '96.1', 4: '8.1'} objective 51.9, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '18.7', 2: '377', 3: '96.1', 4: '8.1'} objective 51.9, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '10.4', 2: '358', 3: '123', 4: '7.77'} objective 75, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '10.4', 2: '358', 3: '123', 4: '7.77'} objective 75, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '51', 2: '331', 3: '108', 4: '9.75'} objective 53, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '51', 2: '331', 3: '108', 4: '9.75'} objective 53, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '10', 2: '374', 3: '107', 4: '8.96'} objective 66.6, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '10', 2: '374', 3: '107', 4: '8.96'} objective 66.6, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '14.9', 2: '431', 3: '48', 4: '6.41'} objective 49.7, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '14.9', 2: '431', 3: '48', 4: '6.41'} objective 49.7, constraint 500, choice set {1, 2, 3, 4} ============ Comparison =================== Brute force: {1: '22.5', 2: '306', 3: '162', 4: '8.79'} objective 54.1, constraint 500, choice set {1, 2, 3, 4} Analytical: {1: '22.5', 2: '306', 3: '162', 4: '8.8'} objective 54.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: 23.7 seconds Forecasting observation 0 / 2 [2000 draws] Forecasting observation 1 / 2 [2000 draws] Execution time for 2000 draws with analytical algorithm: 7.71 seconds 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 23.856767 388.697342 74.688829 12.757062 std 20.531247 63.731952 55.735182 6.590852 min 0.000000 22.118463 0.000000 0.675360 25% 11.528252 359.322784 39.741335 8.675068 50% 18.642639 398.644268 62.150961 11.582239 75% 29.488143 432.074054 93.784235 15.143709 max 221.664145 499.324640 464.909860 82.829552 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 23.853599 388.700106 74.688515 12.757779 std 20.521467 63.731895 55.745170 6.591058 min 0.000000 22.120534 0.000000 0.677372 25% 11.534255 359.337212 39.739389 8.673727 50% 18.639718 398.642888 62.120339 11.581488 75% 29.483047 432.064261 93.784689 15.143665 max 222.336089 499.322628 464.904336 82.828284 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 28.037198 364.133335 98.278747 9.550721 std 27.100350 70.633492 62.732507 4.762774 min 0.000000 15.159529 0.000000 0.000000 25% 13.621909 327.506189 55.631287 6.542072 50% 21.266371 373.970464 86.753305 8.734572 75% 33.748347 412.836198 124.552781 11.426031 max 336.666716 500.000000 473.077968 58.253860 1 2 3 4 count 2000.000000 2000.000000 2000.000000 2000.000000 mean 28.031984 364.141193 98.275643 9.551180 std 27.074216 70.626515 62.736180 4.763061 min 0.000000 15.158661 0.000000 0.000000 25% 13.619524 327.505067 55.646424 6.546172 50% 21.269834 373.964635 86.730665 8.734749 75% 33.748929 412.837953 124.552700 11.430938 max 336.663843 500.000000 473.077960 58.254075 | .. 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 process_data import database from translated_specification import the_translated logger = blog.get_screen_logger(level=blog.INFO) logger.info('Example: translated utility') result_file = 'saved_results/translated.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_translated.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_translated.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_translated.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_translated.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_translated.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_translated.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 32.871 seconds) .. _sphx_glr_download_auto_examples_mdcev_no_outside_good_plot_translated_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_translated_forecasting.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_translated_forecasting.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_translated_forecasting.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_