{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Experiment Tracking: Coloring Multiple Runs\n\nThis example demostrates how to use opt-sugar in combination with mlflow\nfor single objective optimization experiment tracking\n\n<img src=\"https://mybinder.org/badge_logo.svg\" target=\"https://mybinder.org/v2/gh/juandados/opt-sugar/main?labpath=doc%2Fsource%2Fauto_examples%2Fplot_coloring.ipynb\">\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# sphinx_gallery_thumbnail_path = '_static/coloring_experiment.png'\nimport datetime\nfrom urllib.parse import urlparse\nfrom itertools import product\nimport logging\nimport random\n\nimport gurobipy as gp\nimport mlflow\nfrom mlflow.exceptions import MlflowException\n\n# import sys; sys.path.append('/Users/Juan.ChaconLeon/opt/opt-sugar/src')  # when running locally\nfrom opt_sugar import low_sugar\n\n# The generate_graph_data generates random graphs given a graph size and an edge probability.\nfrom utils.coloring import generate_graph_data\n\n# TODO: reformat this example similar to\n#  https://github.com/scikit-learn/scikit-learn/blob/main/examples/calibration/plot_calibration_multiclass.py\n\n# ..NOTE:: check the coloring example first to see how the model was formulated.\n\nfrom utils.coloring import ColoringModelBuilder"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Tracking an Optimization Experiment\n\nAdd description here.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "logging.getLogger(\"mlflow\").setLevel(logging.CRITICAL)  # Can be set DEBUG\n\n\n\ndef get_build(mip_focus):\n    def build(data):\n        # Create a new model\n        m = gp.Model(\"coloring\")\n        model_builder = ColoringModelBuilder(data)\n        model_builder.build_variables(m)\n        model_builder.build_constraints(m)\n        model_builder.build_objective(m)\n        # setting parameters\n        m.setParam('MIPFocus', mip_focus)\n        m.setParam('Method', 4)  # for deterministic concurrent runs\n        return m\n    return build\n\n\ndef callback(m):\n    objective = m.getObjective()\n    color_count = objective.getValue()\n    callback_result = {\"color_count\": color_count, \"MIPFocus\": m.getParamInfo('MIPFocus')[2], \"RunTime\": m.RunTime}\n    return callback_result"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## MIPFocus effect Over Runtime Case 1: Same data multiple runs\n\nAdd description here.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Let's first set the random seed for reproducible results\nrandom.seed(42)\n\ntry:\n    experiment_name = f\"coloring_experiment_1_{datetime.datetime.now().strftime('%Y_%m_%d')}\"\n    experiment_id = mlflow.create_experiment(name=experiment_name)\nexcept MlflowException:\n    experiment_id = mlflow.get_experiment_by_name(name=experiment_name).experiment_id\n\n# Generating a graph instance\ndata = generate_graph_data(node_count=15, edge_probability=0.5)\n\n# Building\nfor mip_focus, _ in product([0, 1, 2, 3], range(25)):\n    with mlflow.start_run(experiment_id=experiment_id):\n        build = get_build(mip_focus)\n        opt_model = low_sugar.Model(build)\n        result = opt_model.optimize(data=data, callback=callback)\n\n        # Note: Above is replacement for opt_model.fit(data, fit_callback) and opt_model.predict(data)\n        mlflow.log_param(\"MIPFocus\", result[\"callback_result\"][\"MIPFocus\"])\n        mlflow.log_metric(\"RunTime\", result[\"callback_result\"][\"RunTime\"])\n        mlflow.log_metric(\"color_count\", result[\"callback_result\"][\"color_count\"])\n\n        tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme\n        print(f\"tracking_url_type_store: {tracking_url_type_store}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## MIPFocus effect Over Runtime Case 1: Different input data\n\nAdd description here.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Again Let's first set the random seed for reproducible results\nrandom.seed(21)\n\ntry:\n    experiment_name = f\"coloring_experiment_2_{datetime.datetime.now().strftime('%Y_%m_%d')}\"\n    experiment_id = mlflow.create_experiment(name=experiment_name)\nexcept MlflowException:\n    experiment_id = mlflow.get_experiment_by_name(name=experiment_name).experiment_id\n\n# Building\nfor mip_focus, data_i in product([0, 1, 2, 3], range(20)):\n\n    data = generate_graph_data(node_count=15, edge_probability=0.5)\n\n    for try_i in range(3):\n\n        with mlflow.start_run(experiment_id=experiment_id):\n            build = get_build(mip_focus)\n            opt_model = low_sugar.Model(build)\n            result = opt_model.optimize(data=data, callback=callback)\n\n            # Note: Above is replacement for opt_model.fit(data, fit_callback) and opt_model.predict(data)\n            mlflow.log_param(\"MIPFocus\", result[\"callback_result\"][\"MIPFocus\"])\n            mlflow.log_metric(\"RunTime\", result[\"callback_result\"][\"RunTime\"])\n            mlflow.log_metric(\"color_count\", result[\"callback_result\"][\"color_count\"])\n\n            tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme\n            print(f\"tracking_url_type_store: {tracking_url_type_store}\")"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}