diff --git a/examples/quantum_annealing/price_optimization/QUBO-Pricing.ipynb b/examples/quantum_annealing/price_optimization/QUBO-Pricing.ipynb
new file mode 100644
index 000000000..cfd35fd0a
--- /dev/null
+++ b/examples/quantum_annealing/price_optimization/QUBO-Pricing.ipynb
@@ -0,0 +1,2855 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "2c5219f3",
+ "metadata": {},
+ "source": [
+ "# Using quantum annealing on Amazon Braket for price optimization\n",
+ "\n",
+ "Combinatorial Optimization is one of the most important fields in optimization. Practical applications can be found in virtually every industry. Prominent examples include supply chain optimization in transport and logistics, portfolio management in finance, and the optimization of clinical trials in healthcare, among many others. It is also one of the most active research topics in operation research and computer science. However, many practical combinatorial optimization problems are NP-hard and require massive computation costs to find solution of good quality. \n",
+ "\n",
+ "In this notebook, we demonstrate how a quantum annealer on Amazon Braket can be used for price optimization taking into consideration the trade-off between maximizing revenue and minimizing risk. We show how to formulate this problem as a quadratic unconstrained binary optimization problem (QUBO) and use the D-Wave Advantage quantum annealer on Amazon Braket to find close-to-optimal solutions. Overall, this notebook demonstrates that customers can easily leverage quantum computing through Amazon Braket to solve difficult combinatorial optimization challenges in their daily decision-making process."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10f29dc7",
+ "metadata": {},
+ "source": [
+ "# Table of contents\n",
+ "### 1. Demand model\n",
+ " 1. Create demand dataset\n",
+ " 2. Fit demand model through linear regression\n",
+ "### 2. Price optimization with QUBO\n",
+ " 1. Construct revenue objective\n",
+ " 2. Add penalty for prediction uncertainty\n",
+ " 3. Add equality constraints\n",
+ "### 3. Solve QUBO with Amazon Braket\n",
+ " 1. Evaluate results\n",
+ "### 4. Trade-off between revenue expectation and prediction uncertainty\n",
+ "### 5. Conclusion\n",
+ "### 6. Literature review\n",
+ "-----------------"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aed8d388",
+ "metadata": {},
+ "source": [
+ "We start by importing Amazon braket SDK and Dwave SDK to be used for quantum annealing in this use case. In addition, we import sklearn to fit the demand estimation model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "1f31ea86",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: sklearn in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (0.0)\n",
+ "Requirement already satisfied: scikit-learn in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from sklearn) (1.0.1)\n",
+ "Requirement already satisfied: scipy>=1.1.0 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from scikit-learn->sklearn) (1.5.2)\n",
+ "Requirement already satisfied: numpy>=1.14.6 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from scikit-learn->sklearn) (1.19.2)\n",
+ "Requirement already satisfied: threadpoolctl>=2.0.0 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from scikit-learn->sklearn) (3.0.0)\n",
+ "Requirement already satisfied: joblib>=0.11 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from scikit-learn->sklearn) (1.1.0)\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install sklearn"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "6718da7a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from braket.aws import AwsDevice\n",
+ "from braket.ocean_plugin import BraketSampler, BraketDWaveSampler\n",
+ "from pyqubo import Binary\n",
+ "# magic word for producing visualizations in notebook\n",
+ "%matplotlib inline\n",
+ "import time\n",
+ "import reprlib\n",
+ "from collections import defaultdict\n",
+ "from itertools import combinations\n",
+ "import math\n",
+ "import networkx as nx\n",
+ "import dwave_networkx as dnx\n",
+ "import minorminer\n",
+ "import dimod\n",
+ "from dimod.binary_quadratic_model import BinaryQuadraticModel\n",
+ "from dwave.system.composites import EmbeddingComposite\n",
+ "import numpy as np\n",
+ "from sklearn.linear_model import LinearRegression\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "from qubo_dynamic_pricing import optimize\n",
+ "\n",
+ "np.random.seed(0)\n",
+ "repr_compact = reprlib.Repr()\n",
+ "repr_compact.maxother=200"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "61be0cc9",
+ "metadata": {},
+ "source": [
+ "__NOTE__: Enter your S3 bucket and key below. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "ce15ec79",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Enter the S3 bucket you created during onboarding in the code below\n",
+ "my_bucket = \"amazon-braket-Your-Bucket-Name\" # the name of the bucket\n",
+ "my_prefix = \"Your-Folder-Name\" # the name of the folder in the bucket\n",
+ "s3_folder = (my_bucket, my_prefix)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "c2fc5e7e",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Device: Device('name': Advantage_system4.1, 'arn': arn:aws:braket:::device/qpu/d-wave/Advantage_system4)\n"
+ ]
+ }
+ ],
+ "source": [
+ "# session and device\n",
+ "device = AwsDevice(\"arn:aws:braket:::device/qpu/d-wave/Advantage_system4\")\n",
+ "print('Device:', device)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "173be395",
+ "metadata": {},
+ "source": [
+ "# 1. Demand model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5c05da56",
+ "metadata": {},
+ "source": [
+ "The usual goal of price optimization is to maximize the revenue in the next certain period with respect to the corresponding prices, where the revenue can usually be represented by a function of demand and price: \n",
+ "\n",
+ "$$\\max_{{\\mathbf{p}}} R(\\mathbf{p}) = \\sum_{t=T}^{T+n-1}d_tp_t$$\n",
+ "\n",
+ "where $p_t$ and $d_t$ are the price and demand at day $t$.\n",
+ "\n",
+ "In order to do price optimization, we need to create a demand model to estimate demand by a function of price: $d_t=f(\\mathbf{p}_t)$, where $\\mathbf{p}$ is a vector of latest prices. In such a way, the revenue objective can be transformed as a function solely depending on price to do optimization $R=\\sum_{t=T}^{T+n-1}f(\\mathbf{p_t})p_t$."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e7de211f",
+ "metadata": {},
+ "source": [
+ "## 1.1 Create training dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "21fe8119",
+ "metadata": {},
+ "source": [
+ "For simplicity, we create a dummy dataset on historical demand and price observations so that a demand estimation model can be trained. \n",
+ "\n",
+ "Here we assume the true demand at day $d_t$ follows a linear model of the latest $n$ days' prices $p_i, i\\in [t-n+1, t-n+2, \\ldots, t]$ plus a noise following normal distribution $\\varepsilon\\sim N(0,\\sigma) $.\n",
+ "\n",
+ "Thus the demand at day $t$ would be\n",
+ "$$d_t = \\sum_{i=t-n+1}^{t}a_{i+n-1-t}p_{i} + b + \\varepsilon $$\n",
+ "where $a_j, j\\in [0, 1, \\ldots, n-1]$ is the elasiticity between the price at day $j+t-n+1$ and demand at day $t$, and\n",
+ "$b$ is a constant.\n",
+ "\n",
+ "We use these assumptions to create our dummy training dataset."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "438e6d85",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "dataset x first 10 samples:\n",
+ "[[ 8 10 10 8 8 10 8]\n",
+ " [10 10 8 8 10 8 13]\n",
+ " [10 8 8 10 8 13 19]\n",
+ " [ 8 8 10 8 13 19 8]\n",
+ " [ 8 10 8 13 19 8 10]\n",
+ " [10 8 13 19 8 10 8]\n",
+ " [ 8 13 19 8 10 8 8]\n",
+ " [13 19 8 10 8 8 16]\n",
+ " [19 8 10 8 8 16 5]\n",
+ " [ 8 10 8 8 16 5 5]]\n",
+ "dataset y first 10 samples:\n",
+ "[176.60983362005817, 166.3135122384355, 122.40886555130055, 139.82753849065216, 136.5494478345374, 139.08672451958816, 171.1141344886614, 149.02456906069798, 153.67576697932017, 185.92865845385478]\n"
+ ]
+ }
+ ],
+ "source": [
+ "a0=[-0.3, -0.5, -1.0, -2.0, -3.0, -3.3, -3.5] # elasticities in linear demand model\n",
+ "b0=300 # constants in the linear demand model \n",
+ "sigma=10. # the standard deviation of the noise\n",
+ "price_levels=[5, 8, 10, 12, 13, 16, 19] # predefined possible prices for each day\n",
+ "probabilities=[0.3, 0.3, 0.2, 0.05, 0.05, 0.05, 0.05] # the probabilities of taking a price choice at a day\n",
+ "n_samples=1000 # the number of sample we want to create\n",
+ "\n",
+ "def create_data_point(p, a, b, sigma):\n",
+ " \"\"\"\n",
+ " estimate the demand\n",
+ " :param p: np.array, (T,)\n",
+ " :param a: np.array, (T,)\n",
+ " :param b: float, the constants\n",
+ " :return: v\n",
+ " \"\"\"\n",
+ " v = np.dot(p,a) + b + np.random.normal(loc=0.0, scale=sigma)\n",
+ " return v\n",
+ "\n",
+ "def create_dataset(a, b, N, price_levels, probabilities, sigma):\n",
+ " \"\"\"\n",
+ " create a dataset for training the demand model\n",
+ " :param a: np.array, (T,)\n",
+ " :param b: float\n",
+ " :param N: int number of samples\n",
+ " :param price_levels: list, price levels\n",
+ " :param probabilities: list, probabilities distribution of the prices\n",
+ " :return:\n",
+ " \"\"\"\n",
+ " t = len(a)\n",
+ " prices = np.random.choice(price_levels, N+t-1, p=probabilities)\n",
+ " data_x = []\n",
+ " data_y = []\n",
+ " for i in range(N):\n",
+ " p = prices[i:i+t]\n",
+ " v = create_data_point(p, a, b, sigma)\n",
+ " data_x.append(\n",
+ " np.expand_dims(p, axis=0)\n",
+ " )\n",
+ " data_y.append(v)\n",
+ "\n",
+ " data_x = np.concatenate(data_x,axis=0)\n",
+ " return data_x, data_y\n",
+ "\n",
+ "data_x, data_y = create_dataset(a0, b0, n_samples, price_levels, probabilities, sigma)\n",
+ "\n",
+ "print(\"dataset x first 10 samples:\")\n",
+ "print(data_x[:10])\n",
+ "print(\"dataset y first 10 samples:\")\n",
+ "print(data_y[:10])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8f68105b",
+ "metadata": {},
+ "source": [
+ "## 1.2. Fit the demand model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "31302cb4",
+ "metadata": {},
+ "source": [
+ "We use `sklearn` to fit a linear demand model to the training set. This fitted linear demand model will be used for the following price optimization problem."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "08cdb86d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "fitted elasticities: [-0.3779074420638822, -0.5723441150118157, -0.8832936349398142, -2.044653528191526, -2.9861902495686956, -3.2337479564086022, -3.6095730899274248]\n",
+ "fitted constant: 301.2623906306577\n"
+ ]
+ }
+ ],
+ "source": [
+ "def linear_regression(data_x, data_y):\n",
+ " reg = LinearRegression().fit(data_x, data_y)\n",
+ " a = reg.coef_\n",
+ " b = reg.intercept_\n",
+ " return a, b\n",
+ "\n",
+ "\n",
+ "a, b = linear_regression(data_x, data_y)\n",
+ "a = [i for i in a]\n",
+ "b = b\n",
+ "\n",
+ "print(f'fitted elasticities: {a}')\n",
+ "print(f'fitted constant: {b}')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "694b5278",
+ "metadata": {},
+ "source": [
+ "# 2. Price optimization with QUBO"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c67da567",
+ "metadata": {},
+ "source": [
+ "In this notebook, we leverage a general-purpose mathematical framework: Quadratic Unconstrained Binary Optimization (QUBO), which has been recently proposed as an effective framework that is able to generalize across a large variety of combinatorial optimization use cases in industries [2, 3]. We take this price optimization as an example and showcase how to formulate it into QUBO framework considering prediction uncertainties as well as equality constraints."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2f6135bd",
+ "metadata": {},
+ "source": [
+ "The formal definition of QUBO is expressed as an optimization problem, Minimize:\n",
+ "$$H=x^TQx$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "277ac4cc",
+ "metadata": {},
+ "source": [
+ "where $x$ is a vector of binary variables representing the decision variables of the combinatorial optimization. $Q$ is a squared matrix of constants inherently encoding the context and constraints of the optimization problems. $Q$ is commonly assumed to be symmetric or upper triangular without loss of generality. The goal is to find the optimal values of the binary decision variables $x$ that minimize the objective $H$.\n",
+ "\n",
+ "As shown above, the format of QUBO is strikingly simple, providing a general-purpose framework for a large class of combinatorial optimization problems. Below we show how to transform the objective function together with the constraints into this QUBO format. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b4ce1392",
+ "metadata": {},
+ "source": [
+ "## 2.1 Construct objective function"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4e5a61db",
+ "metadata": {},
+ "source": [
+ "Assuming tomorrow is day $T$, then the goal of our price optimization is to find the optimal prices $p_t, t\\in[T, T+1, \\ldots, T+n-1]$ in the next $n$ days in order to maximize the revenue in next $n$ days. Based on the demand model we showed above where the demand at a day is correlated with the latest $n$ days' price, we can construct objective function as below:\n",
+ "\n",
+ "$$\\max_{{\\mathbf{p}}}R(\\mathbf{p})=\\sum_{t=T}^{T+n-1}d_tp_t$$\n",
+ "\n",
+ "where $d_t$ is represented by our fitted model above: $d_t = \\sum_{i=t-n+1}^{t}a_{i+n-1-t}p_{i} + b $\n",
+ "\n",
+ "Therefore, we need at least the most recent n days historical prices. Here we randomly choose a historical range of $n$ days' prices as the most recent price data. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "8ab0bc6b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[10, 8, 8, 5, 5, 8, 8]"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "p_data = data_x[np.random.randint(0,n_samples)].tolist()\n",
+ "\n",
+ "p_data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8ced72f4",
+ "metadata": {},
+ "source": [
+ "Now, let's construct the objective function, i.e. the total revenue $R$, for the next $n$ days.\n",
+ "\n",
+ "First, we need to define the price variable $p_t$. According to certain business requirements, the possible prices are usually defined to be a set of discrete price values (e.g. \\\\$5.99, \\\\$9.99, \\\\$14.99). This means the price at each day only has a set of fixed available $m$ options $c_k, k \\in [0, 1, \\ldots, m-1]$, we can represent the price $p_t$ at day $t$ as: $$p_t=\\sum_{k=0}^{m-1}c_{k}x_{t,k}, \\textrm{ subject to } \\sum_{k=0}^{m-1}x_{t,k}=1$$ \n",
+ "\n",
+ "where $x_{t,k}$ is a binary variable with $1$ meaning the price at day $t$ takes option $c_k$, and $0$ meaning otherwise. Therefore, we can use binary variables $x_{t,k}$ to represent the price variables $p_t$."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "a668a23a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[10,\n",
+ " 8,\n",
+ " 8,\n",
+ " 5,\n",
+ " 5,\n",
+ " 8,\n",
+ " 8,\n",
+ " (Binary(X_006)*Num(19.000000)+Binary(X_005)*Num(16.000000)+Binary(X_004)*Num(13.000000)+Binary(X_003)*Num(12.000000)+Binary(X_002)*Num(10.000000)+Binary(X_000)*Num(5.000000)+Binary(X_001)*Num(8.000000)),\n",
+ " (Binary(X_013)*Num(19.000000)+Binary(X_012)*Num(16.000000)+Binary(X_011)*Num(13.000000)+Binary(X_010)*Num(12.000000)+Binary(X_009)*Num(10.000000)+Binary(X_007)*Num(5.000000)+Binary(X_008)*Num(8.000000)),\n",
+ " (Binary(X_020)*Num(19.000000)+Binary(X_019)*Num(16.000000)+Binary(X_018)*Num(13.000000)+Binary(X_017)*Num(12.000000)+Binary(X_016)*Num(10.000000)+Binary(X_014)*Num(5.000000)+Binary(X_015)*Num(8.000000)),\n",
+ " (Binary(X_027)*Num(19.000000)+Binary(X_026)*Num(16.000000)+Binary(X_025)*Num(13.000000)+Binary(X_024)*Num(12.000000)+Binary(X_023)*Num(10.000000)+Binary(X_021)*Num(5.000000)+Binary(X_022)*Num(8.000000)),\n",
+ " (Binary(X_034)*Num(19.000000)+Binary(X_033)*Num(16.000000)+Binary(X_032)*Num(13.000000)+Binary(X_031)*Num(12.000000)+Binary(X_030)*Num(10.000000)+Binary(X_028)*Num(5.000000)+Binary(X_029)*Num(8.000000)),\n",
+ " (Binary(X_041)*Num(19.000000)+Binary(X_040)*Num(16.000000)+Binary(X_039)*Num(13.000000)+Binary(X_038)*Num(12.000000)+Binary(X_037)*Num(10.000000)+Binary(X_035)*Num(5.000000)+Binary(X_036)*Num(8.000000)),\n",
+ " (Binary(X_048)*Num(19.000000)+Binary(X_047)*Num(16.000000)+Binary(X_046)*Num(13.000000)+Binary(X_045)*Num(12.000000)+Binary(X_044)*Num(10.000000)+Binary(X_042)*Num(5.000000)+Binary(X_043)*Num(8.000000))]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# here, we use a list to represent the sequence of prices from day T-n to day T+n-1.\n",
+ "\n",
+ "t = len(a) # next number of days to optimize\n",
+ "n_level = len(price_levels) # number of price options\n",
+ "\n",
+ "x = []\n",
+ "p = []\n",
+ "\n",
+ "# get p\n",
+ "for i in range(t):\n",
+ " p_i = 0\n",
+ " for j in range(n_level):\n",
+ " x_ij = Binary(f\"X_{i*n_level+j:03d}\")\n",
+ " x.append(x_ij)\n",
+ " p_i += x_ij*price_levels[j]\n",
+ " p.append(p_i)\n",
+ " \n",
+ "# plus historical prices\n",
+ "all_p = p_data + p\n",
+ "\n",
+ "all_p"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "437d5378",
+ "metadata": {},
+ "source": [
+ "Next, we can input the price variables into our fitted model to estimate the demand, and then use the demand together with the price to represent the revenue $R$."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "71dde625",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Revenue:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "'(((Binary(X_048)*Num(19.000000)+Binary(X_047)*Num(16.000000)+Binary(X_046)*Num(13.000000)+Binary(X...m(12.000000)+Binary(X_009)*Num(10.000000)+Binary(X_007)*Num(5.000000)+Binary(X_008)*Num(8.000000)))'"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def get_demand(coeff, b, prices):\n",
+ " assert len(coeff) == len(prices)\n",
+ " d = b\n",
+ " for i in range(len(coeff)):\n",
+ " d += coeff[i]*prices[i]\n",
+ "\n",
+ " return d\n",
+ "\n",
+ "# get d, rev\n",
+ "def get_demands_rev(a,b,hist_p, p):\n",
+ " \"\"\" represent the next n days demands and total revenue, based on:\n",
+ " 1. the fitted coefficients a,b\n",
+ " 2. the historical price hist_p\n",
+ " 3. and the future price decisions represented by binary variable x\n",
+ " \"\"\"\n",
+ " all_p = hist_p + p\n",
+ " t = len(a)\n",
+ " d = [get_demand(\n",
+ " coeff=a,\n",
+ " b=b,\n",
+ " prices=all_p[i+1:i+1+t]\n",
+ " ) for i in range(t)]\n",
+ " rev = np.dot(d, p)\n",
+ " return d, rev\n",
+ "\n",
+ "d, rev = get_demands_rev(a,b,p_data, p)\n",
+ "\n",
+ "print('Revenue:')\n",
+ "repr_compact.repr(rev)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "88ec1a39",
+ "metadata": {},
+ "source": [
+ "## 2.2 Add penalty for prediction uncertainty"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "05742984",
+ "metadata": {},
+ "source": [
+ "In optimization, we usually desire to reduce the risk while maximizing the reward, which means we want to reduce the estimated uncertainty/variance of the predicted demands. Therefore, we add a penalty term in the objective function to represent the uncertainty of the predicted demand. The uncertainty of the predicted demand $d_t$ can be represented by its estimated variance,\n",
+ "\n",
+ "$$H=Revenue-\\beta\\sum_{t=T}^{T+n-1}var(d_t)$$\n",
+ "\n",
+ "where $\\beta$ is the regularization parameter to control the effect of risk estimation. The variance of the demand predictions can be estimated as [10]: $$var(d_t)=\\sigma^2(1+\\vec{p}_t'(\\vec{X}'\\vec{X})^{-1}\\vec{p}_t)$$\n",
+ "\n",
+ "where $\\vec{p}_t'=[1, p_{t-n+1},p_{t-n+2}, \\ldots,p_{t}]$ is the price vector to estimate demand $d_t$. $\\vec{X}$ are the observations in the training dataset used to fit the demand model, where each row is an observation in the training set.\n",
+ "\n",
+ "$$\\vec{X} = \\left[\n",
+ " \\begin{matrix}\n",
+ " 1 & p_{0,1} & p_{1,1} & \\dots & p_{n-1,1}\\\\\n",
+ " 1 & p_{0,2} & p_{1,2} & \\dots & p_{n-1,2}\\\\\n",
+ " \\vdots& \\vdots& \\vdots&& \\vdots\\\\\n",
+ " 1 & p_{0,N}& p_{1,N}& \\dots& p_{n-1,N}\n",
+ " \\end{matrix}\\right].$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "6c3d500e",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Objective with expected revenue and prediction variance:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "'((((Binary(X_048)*Num(19.000000)+Binary(X_047)*Num(16.000000)+Binary(X_046)*Num(13.000000)+Binary(...X_001)*Num(8.000000))*Num(-0.000535)+Num(0.016381))+Num(1.000000))*Num(100.000000))*Num(-1.000000))'"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "beta=1.\n",
+ "\n",
+ "def get_variance(data_x, p, sigma):\n",
+ " \"\"\"\n",
+ " :param data_x (np.array): [n_samples, n_days]\n",
+ " :param p (list): [n_days]\n",
+ " :return: variance\n",
+ " \"\"\"\n",
+ " n_samples, t = data_x.shape\n",
+ " ones = np.ones((n_samples, 1), dtype=np.float)\n",
+ " x_mat = np.concatenate([ones, data_x], axis=1) # [n_samples, n_days+1]\n",
+ " x_mat = np.linalg.inv(\n",
+ " np.dot(x_mat.T, x_mat)\n",
+ " )\n",
+ " p = np.array([1.]+p)\n",
+ " variance = (sigma**2) * (1. + p.dot(x_mat).dot(p))\n",
+ " return variance\n",
+ "\n",
+ "def get_overall_variance(data_x, hist_p, p, sigma):\n",
+ " all_p = hist_p + p\n",
+ " t = len(p)\n",
+ " var = 0\n",
+ " for i in range(t):\n",
+ " var += get_variance(data_x, all_p[i+1:i+1+t], sigma)\n",
+ "\n",
+ " return var\n",
+ "\n",
+ "objective = rev - beta * get_overall_variance(data_x, p_data, p, sigma)\n",
+ "\n",
+ "print('Objective with expected revenue and prediction variance:')\n",
+ "repr_compact.repr(objective)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "52a8d37f",
+ "metadata": {},
+ "source": [
+ "## 2.3 Add penalty for equality constraints"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0a92e9af",
+ "metadata": {},
+ "source": [
+ "Since the price can only take one value per day, exactly one of the binary variables in a day must be $1$, and the others must be $0$. Formallly, we have equality constraints:\n",
+ "$$\\sum_{k=0}^{m-1}x_{t,k}=1, \\;t\\in[T, T+1, \\cdots, T+n-1]$$\n",
+ "\n",
+ "We can easily incorporate this equality constraint into the objective function by substracting a penalty term $H_p$ with large enough coefficient $L_p$. If the solution satisfies these constraints, the penalty term will be 0, otherwise a large penalty will be imposed.\n",
+ "\n",
+ "$$H_p=L_p\\sum_{t=T}^{t=T+n-1}[(\\sum_{k=0}^{m-1}x_{t,k})-1]^{2}$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "96c8c9be",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Objective with additional equality constraints:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "'(((((((((((Binary(X_048)*Num(19.000000)+Binary(X_047)*Num(16.000000)+Binary(X_046)*Num(13.000000)+...nary(X_044)+Binary(X_042)+Binary(X_043))+Num(-1.000000))*Num(10000000000000.000000)*Num(-1.000000))'"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# add equalty constraints\n",
+ "Lp=1e13\n",
+ "\n",
+ "for i in range(t):\n",
+ " penalty_i = ((sum(x[i*n_level:(i+1)*n_level]) - 1)**2)*Lp\n",
+ " objective -= penalty_i\n",
+ " \n",
+ "print('Objective with additional equality constraints:')\n",
+ "repr_compact.repr(objective)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6fbf2237",
+ "metadata": {},
+ "source": [
+ "# 3. Solve QUBO with Braket"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9edaa67f",
+ "metadata": {},
+ "source": [
+ "Now we have transformed to the total objective function which:\n",
+ "- maximizes the revenue \n",
+ "- minimizes the prediction uncertainty \n",
+ "- incorporates equality constraints, $\\sum_{k=0}^{m-1}x_{t,k}=1, \\;t\\in[T, T+1, \\cdots, T+n-1]$ \n",
+ "\n",
+ "$$H=Revenue-\\beta\\sum_{t=T}^{T+n-1}var(d_t) - H_p $$\n",
+ "where $H_p=L_p\\sum_{t=T}^{t=T+n-1}[(\\sum_{k=0}^{m-1}x_{t,k})-1]^{2} $ is the penalty term for price equality constraints, and $L_p$ is a constant.\n",
+ "\n",
+ "We can transform this objective function to binary quadratic model, and solve it using Amazon Braket."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2547ec98",
+ "metadata": {},
+ "source": [
+ "Amazon Braket provides access to quantum annealers from D-Wave Systems Inc. which are specifically designed to solve QUBO problems. A quantum annealer is a hardware implementation of Quantum Annealing (QA) which is a generic algorithm to solve combinatorial optimization problems by taking advantage of quantum fluctuations to escape local minima in complex energy landscapes by effect of tunnelling through barriers separating local minima [5]. Through a simple Amazon Braket API call, the formatted QUBO problem can be embedded to the hardwired topology of the machine and submitted to machine. In turn, the quantum annealer performs an annealing process and obtains a result. However, because of the sparsity of the underlying chip, one typically faces a certain overhead in embedding the original QUBO problem to the D-Wave hardware, because (typically) one logical binary variable maps onto several physical qubits, in order to effectively distill the connectivity of the original QUBO problem. For more details, we refer to the Amazon Braket tutorial notebook available here (https://github.com/aws/amazon-braket-examples/blob/main/examples/quantum_annealing/Dwave_Anatomy.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "fdfe3dce",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\"BinaryQuadraticModel({X_005: -10000000002744.719, X_030: -10000000002576.855, X_036: -100000000021...', 'X_026'): 572.3665512211251, ('X_026', 'X_013'): 906.2470394334479}, 70000000000715.1, 'BINARY')\""
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "model = (-objective).compile().to_bqm()\n",
+ "\n",
+ "repr_compact.repr(model)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "54a70c81",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "49"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f149c413",
+ "metadata": {},
+ "source": [
+ "We embed and submit the QUBO task to be solved by a quantum annealer at D-wave backend. Similar to classical simulated annealing, we take several independent shots in order to increase our chances for success in finding a high-quality solution to the QUBO problem. The response contains a number of rows. Each row represents the optimization result of a single shot, including the binary decision variables $[x_T,\\cdots,x_{T+n-1}]$, and corresponding energy which is the negative value of objective function, i.e. $H$. Below we show how to submit a QUBO problem to D-Wave and provide a sample response. Here, the key figure of merit is listed in the column labelled with energy, representing the value for the objective function . We can then easily read off the best bit string found.\n",
+ "\n",
+ "Each row represents an optimized solution. The columns starting with `X_` show the value of the binary decision variables $x_{t,k}$ and the `energy` column shows the negative value of the objective function, i.e. $-H$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "b762f1e9",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " X_000 \n",
+ " X_001 \n",
+ " X_002 \n",
+ " X_003 \n",
+ " X_004 \n",
+ " X_005 \n",
+ " X_006 \n",
+ " X_007 \n",
+ " X_008 \n",
+ " X_009 \n",
+ " ... \n",
+ " X_040 \n",
+ " X_041 \n",
+ " X_042 \n",
+ " X_043 \n",
+ " X_044 \n",
+ " X_045 \n",
+ " X_046 \n",
+ " X_047 \n",
+ " X_048 \n",
+ " energy \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 76 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " ... \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " -12752.164062 \n",
+ " \n",
+ " \n",
+ " 914 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " ... \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " -12602.234375 \n",
+ " \n",
+ " \n",
+ " 1331 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " ... \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " -12597.156250 \n",
+ " \n",
+ " \n",
+ " 77 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " ... \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " -12589.992188 \n",
+ " \n",
+ " \n",
+ " 78 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " ... \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 0 \n",
+ " 1 \n",
+ " -12555.671875 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
5 rows × 50 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " X_000 X_001 X_002 X_003 X_004 X_005 X_006 X_007 X_008 X_009 \\\n",
+ "76 0 0 0 0 1 0 0 0 0 0 \n",
+ "914 0 0 1 0 0 0 0 0 0 1 \n",
+ "1331 0 0 0 0 1 0 0 0 0 0 \n",
+ "77 0 0 0 0 1 0 0 0 0 0 \n",
+ "78 0 0 0 0 1 0 0 0 0 0 \n",
+ "\n",
+ " ... X_040 X_041 X_042 X_043 X_044 X_045 X_046 X_047 X_048 \\\n",
+ "76 ... 0 1 0 0 0 0 0 0 1 \n",
+ "914 ... 0 1 0 0 0 0 0 0 1 \n",
+ "1331 ... 0 0 0 0 0 0 0 0 1 \n",
+ "77 ... 0 0 0 0 0 0 0 0 1 \n",
+ "78 ... 0 0 0 0 0 0 0 0 1 \n",
+ "\n",
+ " energy \n",
+ "76 -12752.164062 \n",
+ "914 -12602.234375 \n",
+ "1331 -12597.156250 \n",
+ "77 -12589.992188 \n",
+ "78 -12555.671875 \n",
+ "\n",
+ "[5 rows x 50 columns]"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "## run dwave quantum annealing\n",
+ "num_shots = 10000\n",
+ "\n",
+ "sampler = BraketDWaveSampler(s3_folder,'arn:aws:braket:::device/qpu/d-wave/Advantage_system4')\n",
+ "sampler = EmbeddingComposite(sampler)\n",
+ "response = sampler.sample(model, num_reads=num_shots)\n",
+ "\n",
+ "# print results\n",
+ "results_df = response.to_pandas_dataframe()\n",
+ "results_columns = results_df.columns[results_df.columns.str.startswith('X_')].tolist()\n",
+ "results_columns += ['energy']\n",
+ "\n",
+ "results_df[results_columns].sort_values('energy').head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ec86a64d",
+ "metadata": {},
+ "source": [
+ "## 3.1 Evaluate the results"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0fb4bbfb",
+ "metadata": {},
+ "source": [
+ "With the response, we can decode the binary array results into the optimal price results"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "43d94f12",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "([13, 13, 12, 5, 10, 19, 19],\n",
+ " array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,\n",
+ " 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n",
+ " 0, 0, 0, 0, 1], dtype=int8),\n",
+ " -12752.1640625)"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def decoder_price_response(response, n_days, price_options):\n",
+ " opt_price, energy = response.record.sample[response.record.energy.argmin()], response.record.energy.min()\n",
+ " prices = []\n",
+ " for i in range(n_days):\n",
+ " price_i = opt_price[i*len(price_options): (i+1)*len(price_options)]\n",
+ " assert price_i.sum()==1\n",
+ " prices.append(price_options[price_i.argmax()])\n",
+ " return prices, opt_price, energy\n",
+ "\n",
+ "opt_decoded_prices, opt_prices, energy =decoder_price_response(response, len(a), price_levels)\n",
+ "\n",
+ "opt_decoded_prices, opt_prices, energy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "43a86a5e",
+ "metadata": {},
+ "source": [
+ "The optimized price path and corresponding demand curve are plotted below, respectively. The optimal price level is higher than the past 7 days, which results in the demand decreasing."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "efa123fb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.rcParams.update({'font.size': 18})\n",
+ "plt.figure(figsize=(10,8))\n",
+ "plt.plot(range(1,8),opt_decoded_prices)\n",
+ "plt.xlabel('Day')\n",
+ "plt.ylabel('Price ($)')\n",
+ "plt.savefig('price_path.png')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6342fa6d",
+ "metadata": {},
+ "source": [
+ "Let's also calculate the total revenue, and plot the demand of each day."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "ce8ec494",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "([182.33668654152052,\n",
+ " 161.75101851993844,\n",
+ " 148.9134817833946,\n",
+ " 165.47394138330202,\n",
+ " 167.4983113772031,\n",
+ " 138.92967848592662,\n",
+ " 108.20132675236677],\n",
+ " 13457.943867415815)"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "opt_d, max_rev = get_demands_rev(a,b,p_data, opt_decoded_prices)\n",
+ "\n",
+ "opt_d, max_rev"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "0e621ea0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.rcParams.update({'font.size': 18})\n",
+ "plt.figure(figsize=(10,8))\n",
+ "plt.plot(range(1,8),opt_d)\n",
+ "plt.xlabel('Day')\n",
+ "plt.ylabel('Demand')\n",
+ "plt.savefig('demand_path.png')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fa79da19",
+ "metadata": {},
+ "source": [
+ "Finally, let's get the overall uncertainty of the demand predictions. Here we simply use the estimated demand variance to indicate the uncertainty."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "169d083b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "705.7816180128258"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "overall_variance = get_overall_variance(data_x, p_data, opt_decoded_prices, sigma)\n",
+ "\n",
+ "overall_variance"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0fb60623",
+ "metadata": {},
+ "source": [
+ "__We can also derive the standard deviation of the revenue based on the variance of demand__\n",
+ "\n",
+ "$$std(R)=\\sqrt{(\\sum_{t=T}^{T+n-1}var(\\hat{d}_t)*p_t^2) + \\sum_{t_1, t_2\\in [T,\\ldots,T+n-1] \\\\ t_1!=t_2}2p_{t_1}p_{t_2}cov(\\hat{d}_{t_1} \\hat{d}_{t_2}) }$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ea9d6a49",
+ "metadata": {},
+ "source": [
+ "where $cov(\\hat{d}_{t_1} \\hat{d}_{t_2}) = \\sigma^2(1+\\vec{p}_{t_1}'(\\vec{X}'\\vec{X})^{-1}\\vec{p}_{t_2})$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "b916ae54",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "911.7464747275401"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def get_covariance(data_x, p1, p2, sigma):\n",
+ " \"\"\"\n",
+ " :param data_x (np.array): [n_samples, n_days]\n",
+ " :param p1, p2 (list): [n_days]\n",
+ " :return: variance\n",
+ " \"\"\"\n",
+ " n_samples, t = data_x.shape\n",
+ " ones = np.ones((n_samples, 1), dtype=np.float)\n",
+ " x_mat = np.concatenate([ones, data_x], axis=1) # [n_samples, n_days+1]\n",
+ " x_mat = np.linalg.inv(\n",
+ " np.dot(x_mat.T, x_mat)\n",
+ " )\n",
+ " p1 = np.array([1.] + p1)\n",
+ " p2 = np.array([1.] + p2)\n",
+ " variance = (sigma**2) * (1. + p1.dot(x_mat).dot(p2))\n",
+ " return variance\n",
+ "\n",
+ "def get_overall_revenue_variance(data_x, hist_p, p, sigma):\n",
+ " all_p = hist_p + p\n",
+ " t = len(p)\n",
+ " var = sum([get_variance(data_x, all_p[i+1:i+1+t], sigma) * (p[i]**2) for i in range(t)])\n",
+ " \n",
+ " # add covariance\n",
+ " var += sum([\n",
+ " get_covariance(\n",
+ " data_x,\n",
+ " all_p[i + 1:i + 1 + t],\n",
+ " all_p[j + 1:j + 1 + t],\n",
+ " sigma\n",
+ " ) * 2 * p[i] * p[j] for i, j in combinations(list(range(t)), 2) \n",
+ " ])\n",
+ "\n",
+ " return var\n",
+ "\n",
+ "revenue_variance = get_overall_revenue_variance(data_x, p_data, opt_decoded_prices, sigma)\n",
+ "\n",
+ "np.sqrt(revenue_variance)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2340e8b",
+ "metadata": {},
+ "source": [
+ "We can investigate the value of the penality terms to see if any equality constraints are violated. The penalty is close to zero showing that all the constraints are satisfied. This small but non-zero value is due to floating point precision."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "8cc64429",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "-0.0018130970111087663"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "penalty = max_rev - beta*overall_variance + energy\n",
+ "\n",
+ "penalty"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f8ca8c97",
+ "metadata": {},
+ "source": [
+ "For comparison, to assess the quality of this optimized result, we also iterate (by brute-force search) through all the $7^7=823,543$ possible price solutions to obtain the energy for each one, which takes more than 5 minutes to run on a standard ml.m5.2xlarge AWS instance. We plot the distribution of the energies of all the 823,543 possible solutions as shown below, where the red line represents our optimized result obtained from the quantum annealer. We can see that although the optimized result from the quantum annealer is not the global optimum with minimum cost, it is close-to-optimal and of good quality. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "0bed907a",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0\n",
+ "1000\n",
+ "2000\n",
+ "3000\n",
+ "4000\n",
+ "5000\n",
+ "6000\n",
+ "7000\n",
+ "8000\n",
+ "9000\n",
+ "10000\n",
+ "11000\n",
+ "12000\n",
+ "13000\n",
+ "14000\n",
+ "15000\n",
+ "16000\n",
+ "17000\n",
+ "18000\n",
+ "19000\n",
+ "20000\n",
+ "21000\n",
+ "22000\n",
+ "23000\n",
+ "24000\n",
+ "25000\n",
+ "26000\n",
+ "27000\n",
+ "28000\n",
+ "29000\n",
+ "30000\n",
+ "31000\n",
+ "32000\n",
+ "33000\n",
+ "34000\n",
+ "35000\n",
+ "36000\n",
+ "37000\n",
+ "38000\n",
+ "39000\n",
+ "40000\n",
+ "41000\n",
+ "42000\n",
+ "43000\n",
+ "44000\n",
+ "45000\n",
+ "46000\n",
+ "47000\n",
+ "48000\n",
+ "49000\n",
+ "50000\n",
+ "51000\n",
+ "52000\n",
+ "53000\n",
+ "54000\n",
+ "55000\n",
+ "56000\n",
+ "57000\n",
+ "58000\n",
+ "59000\n",
+ "60000\n",
+ "61000\n",
+ "62000\n",
+ "63000\n",
+ "64000\n",
+ "65000\n",
+ "66000\n",
+ "67000\n",
+ "68000\n",
+ "69000\n",
+ "70000\n",
+ "71000\n",
+ "72000\n",
+ "73000\n",
+ "74000\n",
+ "75000\n",
+ "76000\n",
+ "77000\n",
+ "78000\n",
+ "79000\n",
+ "80000\n",
+ "81000\n",
+ "82000\n",
+ "83000\n",
+ "84000\n",
+ "85000\n",
+ "86000\n",
+ "87000\n",
+ "88000\n",
+ "89000\n",
+ "90000\n",
+ "91000\n",
+ "92000\n",
+ "93000\n",
+ "94000\n",
+ "95000\n",
+ "96000\n",
+ "97000\n",
+ "98000\n",
+ "99000\n",
+ "100000\n",
+ "101000\n",
+ "102000\n",
+ "103000\n",
+ "104000\n",
+ "105000\n",
+ "106000\n",
+ "107000\n",
+ "108000\n",
+ "109000\n",
+ "110000\n",
+ "111000\n",
+ "112000\n",
+ "113000\n",
+ "114000\n",
+ "115000\n",
+ "116000\n",
+ "117000\n",
+ "118000\n",
+ "119000\n",
+ "120000\n",
+ "121000\n",
+ "122000\n",
+ "123000\n",
+ "124000\n",
+ "125000\n",
+ "126000\n",
+ "127000\n",
+ "128000\n",
+ "129000\n",
+ "130000\n",
+ "131000\n",
+ "132000\n",
+ "133000\n",
+ "134000\n",
+ "135000\n",
+ "136000\n",
+ "137000\n",
+ "138000\n",
+ "139000\n",
+ "140000\n",
+ "141000\n",
+ "142000\n",
+ "143000\n",
+ "144000\n",
+ "145000\n",
+ "146000\n",
+ "147000\n",
+ "148000\n",
+ "149000\n",
+ "150000\n",
+ "151000\n",
+ "152000\n",
+ "153000\n",
+ "154000\n",
+ "155000\n",
+ "156000\n",
+ "157000\n",
+ "158000\n",
+ "159000\n",
+ "160000\n",
+ "161000\n",
+ "162000\n",
+ "163000\n",
+ "164000\n",
+ "165000\n",
+ "166000\n",
+ "167000\n",
+ "168000\n",
+ "169000\n",
+ "170000\n",
+ "171000\n",
+ "172000\n",
+ "173000\n",
+ "174000\n",
+ "175000\n",
+ "176000\n",
+ "177000\n",
+ "178000\n",
+ "179000\n",
+ "180000\n",
+ "181000\n",
+ "182000\n",
+ "183000\n",
+ "184000\n",
+ "185000\n",
+ "186000\n",
+ "187000\n",
+ "188000\n",
+ "189000\n",
+ "190000\n",
+ "191000\n",
+ "192000\n",
+ "193000\n",
+ "194000\n",
+ "195000\n",
+ "196000\n",
+ "197000\n",
+ "198000\n",
+ "199000\n",
+ "200000\n",
+ "201000\n",
+ "202000\n",
+ "203000\n",
+ "204000\n",
+ "205000\n",
+ "206000\n",
+ "207000\n",
+ "208000\n",
+ "209000\n",
+ "210000\n",
+ "211000\n",
+ "212000\n",
+ "213000\n",
+ "214000\n",
+ "215000\n",
+ "216000\n",
+ "217000\n",
+ "218000\n",
+ "219000\n",
+ "220000\n",
+ "221000\n",
+ "222000\n",
+ "223000\n",
+ "224000\n",
+ "225000\n",
+ "226000\n",
+ "227000\n",
+ "228000\n",
+ "229000\n",
+ "230000\n",
+ "231000\n",
+ "232000\n",
+ "233000\n",
+ "234000\n",
+ "235000\n",
+ "236000\n",
+ "237000\n",
+ "238000\n",
+ "239000\n",
+ "240000\n",
+ "241000\n",
+ "242000\n",
+ "243000\n",
+ "244000\n",
+ "245000\n",
+ "246000\n",
+ "247000\n",
+ "248000\n",
+ "249000\n",
+ "250000\n",
+ "251000\n",
+ "252000\n",
+ "253000\n",
+ "254000\n",
+ "255000\n",
+ "256000\n",
+ "257000\n",
+ "258000\n",
+ "259000\n",
+ "260000\n",
+ "261000\n",
+ "262000\n",
+ "263000\n",
+ "264000\n",
+ "265000\n",
+ "266000\n",
+ "267000\n",
+ "268000\n",
+ "269000\n",
+ "270000\n",
+ "271000\n",
+ "272000\n",
+ "273000\n",
+ "274000\n",
+ "275000\n",
+ "276000\n",
+ "277000\n",
+ "278000\n",
+ "279000\n",
+ "280000\n",
+ "281000\n",
+ "282000\n",
+ "283000\n",
+ "284000\n",
+ "285000\n",
+ "286000\n",
+ "287000\n",
+ "288000\n",
+ "289000\n",
+ "290000\n",
+ "291000\n",
+ "292000\n",
+ "293000\n",
+ "294000\n",
+ "295000\n",
+ "296000\n",
+ "297000\n",
+ "298000\n",
+ "299000\n",
+ "300000\n",
+ "301000\n",
+ "302000\n",
+ "303000\n",
+ "304000\n",
+ "305000\n",
+ "306000\n",
+ "307000\n",
+ "308000\n",
+ "309000\n",
+ "310000\n",
+ "311000\n",
+ "312000\n",
+ "313000\n",
+ "314000\n",
+ "315000\n",
+ "316000\n",
+ "317000\n",
+ "318000\n",
+ "319000\n",
+ "320000\n",
+ "321000\n",
+ "322000\n",
+ "323000\n",
+ "324000\n",
+ "325000\n",
+ "326000\n",
+ "327000\n",
+ "328000\n",
+ "329000\n",
+ "330000\n",
+ "331000\n",
+ "332000\n",
+ "333000\n",
+ "334000\n",
+ "335000\n",
+ "336000\n",
+ "337000\n",
+ "338000\n",
+ "339000\n",
+ "340000\n",
+ "341000\n",
+ "342000\n",
+ "343000\n",
+ "344000\n",
+ "345000\n",
+ "346000\n",
+ "347000\n",
+ "348000\n",
+ "349000\n",
+ "350000\n",
+ "351000\n",
+ "352000\n",
+ "353000\n",
+ "354000\n",
+ "355000\n",
+ "356000\n",
+ "357000\n",
+ "358000\n",
+ "359000\n",
+ "360000\n",
+ "361000\n",
+ "362000\n",
+ "363000\n",
+ "364000\n",
+ "365000\n",
+ "366000\n",
+ "367000\n",
+ "368000\n",
+ "369000\n",
+ "370000\n",
+ "371000\n",
+ "372000\n",
+ "373000\n",
+ "374000\n",
+ "375000\n",
+ "376000\n",
+ "377000\n",
+ "378000\n",
+ "379000\n",
+ "380000\n",
+ "381000\n",
+ "382000\n",
+ "383000\n",
+ "384000\n",
+ "385000\n",
+ "386000\n",
+ "387000\n",
+ "388000\n",
+ "389000\n",
+ "390000\n",
+ "391000\n",
+ "392000\n",
+ "393000\n",
+ "394000\n",
+ "395000\n",
+ "396000\n",
+ "397000\n",
+ "398000\n",
+ "399000\n",
+ "400000\n",
+ "401000\n",
+ "402000\n",
+ "403000\n",
+ "404000\n",
+ "405000\n",
+ "406000\n",
+ "407000\n",
+ "408000\n",
+ "409000\n",
+ "410000\n",
+ "411000\n",
+ "412000\n",
+ "413000\n",
+ "414000\n",
+ "415000\n",
+ "416000\n",
+ "417000\n",
+ "418000\n",
+ "419000\n",
+ "420000\n",
+ "421000\n",
+ "422000\n",
+ "423000\n",
+ "424000\n",
+ "425000\n",
+ "426000\n",
+ "427000\n",
+ "428000\n",
+ "429000\n",
+ "430000\n",
+ "431000\n",
+ "432000\n",
+ "433000\n",
+ "434000\n",
+ "435000\n",
+ "436000\n",
+ "437000\n",
+ "438000\n",
+ "439000\n",
+ "440000\n",
+ "441000\n",
+ "442000\n",
+ "443000\n",
+ "444000\n",
+ "445000\n",
+ "446000\n",
+ "447000\n",
+ "448000\n",
+ "449000\n",
+ "450000\n",
+ "451000\n",
+ "452000\n",
+ "453000\n",
+ "454000\n",
+ "455000\n",
+ "456000\n",
+ "457000\n",
+ "458000\n",
+ "459000\n",
+ "460000\n",
+ "461000\n",
+ "462000\n",
+ "463000\n",
+ "464000\n",
+ "465000\n",
+ "466000\n",
+ "467000\n",
+ "468000\n",
+ "469000\n",
+ "470000\n",
+ "471000\n",
+ "472000\n",
+ "473000\n",
+ "474000\n",
+ "475000\n",
+ "476000\n",
+ "477000\n",
+ "478000\n",
+ "479000\n",
+ "480000\n",
+ "481000\n",
+ "482000\n",
+ "483000\n",
+ "484000\n",
+ "485000\n",
+ "486000\n",
+ "487000\n",
+ "488000\n",
+ "489000\n",
+ "490000\n",
+ "491000\n",
+ "492000\n",
+ "493000\n",
+ "494000\n",
+ "495000\n",
+ "496000\n",
+ "497000\n",
+ "498000\n",
+ "499000\n",
+ "500000\n",
+ "501000\n",
+ "502000\n",
+ "503000\n",
+ "504000\n",
+ "505000\n",
+ "506000\n",
+ "507000\n",
+ "508000\n",
+ "509000\n",
+ "510000\n",
+ "511000\n",
+ "512000\n",
+ "513000\n",
+ "514000\n",
+ "515000\n",
+ "516000\n",
+ "517000\n",
+ "518000\n",
+ "519000\n",
+ "520000\n",
+ "521000\n",
+ "522000\n",
+ "523000\n",
+ "524000\n",
+ "525000\n",
+ "526000\n",
+ "527000\n",
+ "528000\n",
+ "529000\n",
+ "530000\n",
+ "531000\n",
+ "532000\n",
+ "533000\n",
+ "534000\n",
+ "535000\n",
+ "536000\n",
+ "537000\n",
+ "538000\n",
+ "539000\n",
+ "540000\n",
+ "541000\n",
+ "542000\n",
+ "543000\n",
+ "544000\n",
+ "545000\n",
+ "546000\n",
+ "547000\n",
+ "548000\n",
+ "549000\n",
+ "550000\n",
+ "551000\n",
+ "552000\n",
+ "553000\n",
+ "554000\n",
+ "555000\n",
+ "556000\n",
+ "557000\n",
+ "558000\n",
+ "559000\n",
+ "560000\n",
+ "561000\n",
+ "562000\n",
+ "563000\n",
+ "564000\n",
+ "565000\n",
+ "566000\n",
+ "567000\n",
+ "568000\n",
+ "569000\n",
+ "570000\n",
+ "571000\n",
+ "572000\n",
+ "573000\n",
+ "574000\n",
+ "575000\n",
+ "576000\n",
+ "577000\n",
+ "578000\n",
+ "579000\n",
+ "580000\n",
+ "581000\n",
+ "582000\n",
+ "583000\n",
+ "584000\n",
+ "585000\n",
+ "586000\n",
+ "587000\n",
+ "588000\n",
+ "589000\n",
+ "590000\n",
+ "591000\n",
+ "592000\n",
+ "593000\n",
+ "594000\n",
+ "595000\n",
+ "596000\n",
+ "597000\n",
+ "598000\n",
+ "599000\n",
+ "600000\n",
+ "601000\n",
+ "602000\n",
+ "603000\n",
+ "604000\n",
+ "605000\n",
+ "606000\n",
+ "607000\n",
+ "608000\n",
+ "609000\n",
+ "610000\n",
+ "611000\n",
+ "612000\n",
+ "613000\n",
+ "614000\n",
+ "615000\n",
+ "616000\n",
+ "617000\n",
+ "618000\n",
+ "619000\n",
+ "620000\n",
+ "621000\n",
+ "622000\n",
+ "623000\n",
+ "624000\n",
+ "625000\n",
+ "626000\n",
+ "627000\n",
+ "628000\n",
+ "629000\n",
+ "630000\n",
+ "631000\n",
+ "632000\n",
+ "633000\n",
+ "634000\n",
+ "635000\n",
+ "636000\n",
+ "637000\n",
+ "638000\n",
+ "639000\n",
+ "640000\n",
+ "641000\n",
+ "642000\n",
+ "643000\n",
+ "644000\n",
+ "645000\n",
+ "646000\n",
+ "647000\n",
+ "648000\n",
+ "649000\n",
+ "650000\n",
+ "651000\n",
+ "652000\n",
+ "653000\n",
+ "654000\n",
+ "655000\n",
+ "656000\n",
+ "657000\n",
+ "658000\n",
+ "659000\n",
+ "660000\n",
+ "661000\n",
+ "662000\n",
+ "663000\n",
+ "664000\n",
+ "665000\n",
+ "666000\n",
+ "667000\n",
+ "668000\n",
+ "669000\n",
+ "670000\n",
+ "671000\n",
+ "672000\n",
+ "673000\n",
+ "674000\n",
+ "675000\n",
+ "676000\n",
+ "677000\n",
+ "678000\n",
+ "679000\n",
+ "680000\n",
+ "681000\n",
+ "682000\n",
+ "683000\n",
+ "684000\n",
+ "685000\n",
+ "686000\n",
+ "687000\n",
+ "688000\n",
+ "689000\n",
+ "690000\n",
+ "691000\n",
+ "692000\n",
+ "693000\n",
+ "694000\n",
+ "695000\n",
+ "696000\n",
+ "697000\n",
+ "698000\n",
+ "699000\n",
+ "700000\n",
+ "701000\n",
+ "702000\n",
+ "703000\n",
+ "704000\n",
+ "705000\n",
+ "706000\n",
+ "707000\n",
+ "708000\n",
+ "709000\n",
+ "710000\n",
+ "711000\n",
+ "712000\n",
+ "713000\n",
+ "714000\n",
+ "715000\n",
+ "716000\n",
+ "717000\n",
+ "718000\n",
+ "719000\n",
+ "720000\n",
+ "721000\n",
+ "722000\n",
+ "723000\n",
+ "724000\n",
+ "725000\n",
+ "726000\n",
+ "727000\n",
+ "728000\n",
+ "729000\n",
+ "730000\n",
+ "731000\n",
+ "732000\n",
+ "733000\n",
+ "734000\n",
+ "735000\n",
+ "736000\n",
+ "737000\n",
+ "738000\n",
+ "739000\n",
+ "740000\n",
+ "741000\n",
+ "742000\n",
+ "743000\n",
+ "744000\n",
+ "745000\n",
+ "746000\n",
+ "747000\n",
+ "748000\n",
+ "749000\n",
+ "750000\n",
+ "751000\n",
+ "752000\n",
+ "753000\n",
+ "754000\n",
+ "755000\n",
+ "756000\n",
+ "757000\n",
+ "758000\n",
+ "759000\n",
+ "760000\n",
+ "761000\n",
+ "762000\n",
+ "763000\n",
+ "764000\n",
+ "765000\n",
+ "766000\n",
+ "767000\n",
+ "768000\n",
+ "769000\n",
+ "770000\n",
+ "771000\n",
+ "772000\n",
+ "773000\n",
+ "774000\n",
+ "775000\n",
+ "776000\n",
+ "777000\n",
+ "778000\n",
+ "779000\n",
+ "780000\n",
+ "781000\n",
+ "782000\n",
+ "783000\n",
+ "784000\n",
+ "785000\n",
+ "786000\n",
+ "787000\n",
+ "788000\n",
+ "789000\n",
+ "790000\n",
+ "791000\n",
+ "792000\n",
+ "793000\n",
+ "794000\n",
+ "795000\n",
+ "796000\n",
+ "797000\n",
+ "798000\n",
+ "799000\n",
+ "800000\n",
+ "801000\n",
+ "802000\n",
+ "803000\n",
+ "804000\n",
+ "805000\n",
+ "806000\n",
+ "807000\n",
+ "808000\n",
+ "809000\n",
+ "810000\n",
+ "811000\n",
+ "812000\n",
+ "813000\n",
+ "814000\n",
+ "815000\n",
+ "816000\n",
+ "817000\n",
+ "818000\n",
+ "819000\n",
+ "820000\n",
+ "821000\n",
+ "822000\n",
+ "823000\n"
+ ]
+ }
+ ],
+ "source": [
+ "all_rev=[]\n",
+ "all_var=[]\n",
+ "all_energy=[]\n",
+ "i=0\n",
+ "\n",
+ "for p_t1 in price_levels:\n",
+ " for p_t2 in price_levels:\n",
+ " for p_t3 in price_levels:\n",
+ " for p_t4 in price_levels:\n",
+ " for p_t5 in price_levels:\n",
+ " for p_t6 in price_levels:\n",
+ " for p_t7 in price_levels:\n",
+ " if i%1000==0:\n",
+ " print(i)\n",
+ " \n",
+ " _, sample_rev = get_demands_rev(a,b,p_data, [p_t1,p_t2,p_t3,p_t4,p_t5,p_t6,p_t7])\n",
+ " sample_overall_variance = get_overall_variance(data_x, p_data, [p_t1,p_t2,p_t3,p_t4,p_t5,p_t6,p_t7], sigma)\n",
+ " all_rev.append(sample_rev)\n",
+ " all_var.append(sample_overall_variance)\n",
+ " all_energy.append(-(sample_rev-beta*sample_overall_variance))\n",
+ " i+=1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "c218c92f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.rcParams.update({'font.size': 18})\n",
+ "plt.figure(figsize=(10,8))\n",
+ "plt.vlines(energy,0,125000, 'r')\n",
+ "plt.hist(all_energy,20)\n",
+ "plt.xlabel('Energy distribution of all possible solutions')\n",
+ "plt.ylabel('Frequency')\n",
+ "plt.savefig('result_quality.png')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f5089d50",
+ "metadata": {},
+ "source": [
+ "# 4. Trade-off between expected revenue and prediction uncertainty."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "85862da0",
+ "metadata": {},
+ "source": [
+ "Let's first wrap the above price optimization into a single optimize function for convenience."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "36b838f3",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(13362.364731002446,\n",
+ " 706.7208258596746,\n",
+ " -12655.6484375,\n",
+ " [185.94625963144793,\n",
+ " 154.15604720656478,\n",
+ " 167.46543979322945,\n",
+ " 155.9292482281557,\n",
+ " 160.514740479689,\n",
+ " 130.2613846464788,\n",
+ " 98.73268259663321],\n",
+ " [12, 16, 5, 12, 10, 19, 19],\n",
+ " 931.8876101527734)"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Ld=1e6\n",
+ "\n",
+ "max_revenue, prediction_variance, energy, opt_demand, opt_prices, rev_std = optimize(\n",
+ " a = a,\n",
+ " b = b,\n",
+ " data_x = data_x,\n",
+ " selected_hist_prices = p_data,\n",
+ " price_levels = price_levels,\n",
+ " Lp = Lp,\n",
+ " Ld = Ld,\n",
+ " sigma = sigma ,\n",
+ " beta=beta,\n",
+ " vol_bound=None,\n",
+ " s3_folder=s3_folder\n",
+ ")\n",
+ "\n",
+ "max_revenue, prediction_variance, energy, opt_demand, opt_prices, rev_std"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5b8efe22",
+ "metadata": {},
+ "source": [
+ "In order to investigate the trade-off between the expected revenue and prediction uncertainties, we vary the hyperparameter $\\beta$ within a large range of $[1e2,1e9]$ and run multiple experiments on D-Wave with different $\\beta$ values. The scatter plot is shown below, where each dot represents the optimized result of an experiment with x-axis representing its expected revenue and y-axis representing the estimated standard deviation of revenue $std(R)$."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1e11af8f",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Caution: Running the following cell will run a substantial amount of tasks for various senarios taking about 30 minutes. Only uncomment it if you are happy to wait.\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "a047a433",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13142.782268581876\n",
+ "prediction_variance:703.5502036738326\n",
+ "energy:57212.2421875\n",
+ "opt_demand:[182.33668654152052, 179.79888396957557, 165.08222156543758, 155.1378810016535, 155.08534332330055, 154.92897272299166, 125.8542042377626]\n",
+ "opt_prices:[13, 8, 12, 12, 10, 10, 19]\n",
+ "rev_std: 840.9865848076566\n",
+ "penalty_term: 0.004088698617124464\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:13198.22244328534\n",
+ "prediction_variance:702.9415585415351\n",
+ "energy:689743.3359375\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 163.96372331139906, 159.28485931053694, 157.1272228349854, 151.58799858923842, 122.5817558425566]\n",
+ "opt_prices:[10, 10, 13, 10, 10, 12, 19]\n",
+ "rev_std: 841.0012457923974\n",
+ "penalty_term: -0.0001607497688382864\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:11976.233040996605\n",
+ "prediction_variance:702.6893930180825\n",
+ "energy:7014917.6953125\n",
+ "opt_demand:[185.94625963144793, 183.03263192598416, 182.506704174716, 195.38453798497142, 183.33048747152048, 185.3349129647881, 166.23041487017076]\n",
+ "opt_prices:[12, 8, 8, 5, 12, 8, 13]\n",
+ "rev_std: 660.4930504735115\n",
+ "penalty_term: -0.0018273275345563889\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:11515.07074768842\n",
+ "prediction_variance:701.8849560662594\n",
+ "energy:70176980.5390625\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 175.45359909257996, 172.05817408282888, 161.81126623019608, 177.53224727623964]\n",
+ "opt_prices:[10, 10, 8, 10, 10, 12, 5]\n",
+ "rev_std: 650.464648418367\n",
+ "penalty_term: 0.0031842440366744995\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:11984.699124804318\n",
+ "prediction_variance:701.8939938693518\n",
+ "energy:701882009.171875\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 181.2599384939985, 167.73933749904532, 170.9267509071122, 167.20280803722733, 167.21305214231802]\n",
+ "opt_prices:[10, 8, 10, 12, 8, 10, 10]\n",
+ "rev_std: 680.4924545774593\n",
+ "penalty_term: 0.0016480684280395508\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:12282.115767083424\n",
+ "prediction_variance:702.0784098201561\n",
+ "energy:7020771816.0859375\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 188.47908467385338, 181.42597959171735, 165.3187618694297, 153.8766096308499, 151.67049930792007]\n",
+ "opt_prices:[10, 8, 8, 10, 13, 12, 10]\n",
+ "rev_std: 710.5669426766799\n",
+ "penalty_term: 0.00014400482177734375\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:12241.871304610453\n",
+ "prediction_variance:702.0141973826334\n",
+ "energy:70201407496.40625\n",
+ "opt_demand:[200.38455199115765, 188.74847757176371, 180.7648230803187, 173.07541023614584, 157.0236615837889, 163.60369589432054, 155.23088433792412]\n",
+ "opt_prices:[8, 10, 10, 10, 13, 8, 12]\n",
+ "rev_std: 710.5717716766972\n",
+ "penalty_term: 0.01422119140625\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:11607.35132521147\n",
+ "prediction_variance:702.3039204704776\n",
+ "energy:702303908863.1328\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 174.04079231414366, 168.49098776608298, 153.37400087115492, 152.91714169793863, 172.6526861306151]\n",
+ "opt_prices:[10, 8, 12, 10, 13, 10, 5]\n",
+ "rev_std: 680.5670317172533\n",
+ "penalty_term: 0.006591796875\n",
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13308.789275999401\n",
+ "prediction_variance:704.4245606588714\n",
+ "energy:57133.6640625\n",
+ "opt_demand:[182.33668654152052, 165.36059160986585, 148.53765664987577, 136.3497989570427, 147.90593718441198, 142.00373104850712, 116.90801724449558]\n",
+ "opt_prices:[13, 12, 13, 13, 8, 13, 19]\n",
+ "rev_std: 911.440627188109\n",
+ "penalty_term: -0.0027273877494735643\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:12670.478721092995\n",
+ "prediction_variance:702.6378450712685\n",
+ "energy:689967.3671875\n",
+ "opt_demand:[185.94625963144793, 183.03263192598416, 175.28755799486112, 178.08832280237198, 164.04729001322988, 169.05328720329032, 144.51495749636558]\n",
+ "opt_prices:[12, 8, 10, 8, 13, 8, 16]\n",
+ "rev_std: 750.6271669208057\n",
+ "penalty_term: 0.0008373245364055037\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:11817.559866927473\n",
+ "prediction_variance:702.2867319690542\n",
+ "energy:7011049.7578125\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 170.43121922421625, 165.25723980967433, 153.9973837115136, 161.32538230601057, 170.39435938827893]\n",
+ "opt_prices:[10, 8, 13, 10, 12, 8, 8]\n",
+ "rev_std: 690.5524395782304\n",
+ "penalty_term: -0.0020111147314310074\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:11730.90327753302\n",
+ "prediction_variance:702.6054633102096\n",
+ "energy:70248815.4296875\n",
+ "opt_demand:[200.38455199115765, 188.74847757176371, 173.54567690046386, 159.38876814347378, 173.4603698912537, 164.9736996303592, 174.76781254228632]\n",
+ "opt_prices:[8, 10, 12, 12, 5, 12, 8]\n",
+ "rev_std: 670.5375896992824\n",
+ "penalty_term: 0.0019440650939941406\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:11366.13708846887\n",
+ "prediction_variance:701.9254561595391\n",
+ "energy:701914090.0234375\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 180.01317281328105, 179.79944100232086, 172.43680332363402, 176.95460047618036, 182.095155462867]\n",
+ "opt_prices:[8, 8, 12, 8, 10, 8, 8]\n",
+ "rev_std: 620.4867422821079\n",
+ "penalty_term: 0.0009868144989013672\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:12059.244435137061\n",
+ "prediction_variance:702.1589543897425\n",
+ "energy:7021577484.65625\n",
+ "opt_demand:[185.94625963144793, 175.81348574612934, 168.82006208204393, 172.1159423032346, 170.78670222662907, 162.54965144292677, 168.27043290883302]\n",
+ "opt_prices:[12, 10, 10, 8, 10, 12, 8]\n",
+ "rev_std: 700.4770822738305\n",
+ "penalty_term: 0.0032606124877929688\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:12586.848019820494\n",
+ "prediction_variance:702.2588263689306\n",
+ "energy:70225870050.04688\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 174.04079231414366, 168.49098776608298, 171.42186632079205, 158.2571622101994, 149.0058087898134]\n",
+ "opt_prices:[10, 8, 12, 10, 8, 13, 13]\n",
+ "rev_std: 740.5999324626732\n",
+ "penalty_term: 0.0018310546875\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:11513.084463226094\n",
+ "prediction_variance:701.9673403893491\n",
+ "energy:701967328876.2656\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 182.67274527243484, 185.74481617550094, 199.51815427164263, 181.35358580720091]\n",
+ "opt_prices:[10, 10, 8, 8, 8, 5, 13]\n",
+ "rev_std: 620.4493819300103\n",
+ "penalty_term: 0.0009765625\n",
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13220.837666382635\n",
+ "prediction_variance:703.2708579595874\n",
+ "energy:57106.2421875\n",
+ "opt_demand:[193.16540581130278, 175.06183547909168, 168.32494666836413, 155.79457650077055, 148.30984443463637, 129.07720313226912, 111.91898840597983]\n",
+ "opt_prices:[10, 12, 10, 12, 12, 16, 16]\n",
+ "rev_std: 881.2620851851485\n",
+ "penalty_term: -0.005942076095379889\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:12295.011741408678\n",
+ "prediction_variance:702.0143363129322\n",
+ "energy:689719.3203125\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 168.23445291272512, 165.5906781700117, 170.27717809076842, 157.5013473260716]\n",
+ "opt_prices:[10, 10, 8, 12, 10, 8, 13]\n",
+ "rev_std: 710.5194469295551\n",
+ "penalty_term: -0.004259023466147482\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:12137.958959707696\n",
+ "prediction_variance:701.7035451887735\n",
+ "energy:7004897.5\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 187.2323189931359, 179.04779073528323, 171.94168790995423, 167.85238085357116, 158.86664740383665]\n",
+ "opt_prices:[8, 8, 10, 10, 10, 10, 12]\n",
+ "rev_std: 680.5356666395476\n",
+ "penalty_term: 0.0070719728246331215\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:12662.168821110694\n",
+ "prediction_variance:702.0474353071147\n",
+ "energy:70192081.359375\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 175.45359909257996, 164.83902790297404, 155.34377031737887, 142.68328205768287]\n",
+ "opt_prices:[10, 10, 8, 10, 12, 12, 13]\n",
+ "rev_std: 750.6086003087909\n",
+ "penalty_term: -0.002515360713005066\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:11584.987162273512\n",
+ "prediction_variance:701.6265137028367\n",
+ "energy:701614928.7265625\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 194.45146517299077, 185.5152866481004, 185.1332145889465, 178.4091838227714, 173.82476135270855]\n",
+ "opt_prices:[8, 8, 8, 10, 8, 10, 10]\n",
+ "rev_std: 620.5051819276027\n",
+ "penalty_term: 0.010887980461120605\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:11875.017901773796\n",
+ "prediction_variance:702.7108889577102\n",
+ "energy:7027097014.5546875\n",
+ "opt_demand:[185.94625963144793, 183.03263192598416, 193.33542344449825, 194.25706258441494, 189.80696053085563, 174.5395063537641, 166.61244313370094]\n",
+ "opt_prices:[12, 8, 5, 8, 10, 12, 10]\n",
+ "rev_std: 650.489008200234\n",
+ "penalty_term: -0.004512786865234375\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:11823.25581739232\n",
+ "prediction_variance:701.7629736877091\n",
+ "energy:70176285545.53125\n",
+ "opt_demand:[200.38455199115765, 188.74847757176371, 187.98396926017358, 179.54290614896303, 173.82476135270855, 162.95595446021971, 167.45934289058516]\n",
+ "opt_prices:[8, 10, 8, 10, 10, 12, 8]\n",
+ "rev_std: 660.5028248731621\n",
+ "penalty_term: 0.0161590576171875\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:12167.489725816766\n",
+ "prediction_variance:702.2176753704937\n",
+ "energy:702217663203.0078\n",
+ "opt_demand:[185.94625963144793, 175.81348574612934, 168.82006208204393, 164.89679612337972, 157.10006013395704, 164.54806739068187, 163.92459099909212]\n",
+ "opt_prices:[12, 10, 10, 10, 12, 8, 10]\n",
+ "rev_std: 720.5240801141839\n",
+ "penalty_term: 0.00390625\n",
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13094.765089274155\n",
+ "prediction_variance:703.662012789634\n",
+ "energy:57271.4375\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 164.6248798227977, 169.57607639345792, 134.05317976481524, 115.02912750674054]\n",
+ "opt_prices:[10, 10, 8, 13, 8, 19, 16]\n",
+ "rev_std: 841.1476642973098\n",
+ "penalty_term: 0.0013103107485221699\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:12603.56403338578\n",
+ "prediction_variance:702.1242685672336\n",
+ "energy:689520.6953125\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 168.23445291272512, 165.5906781700117, 152.2293126411313, 144.94218063395599]\n",
+ "opt_prices:[10, 10, 8, 12, 10, 13, 12]\n",
+ "rev_std: 750.6158788184107\n",
+ "penalty_term: -0.0092213477473706\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:12157.321498711704\n",
+ "prediction_variance:702.2691817581286\n",
+ "energy:7010534.4921875\n",
+ "opt_demand:[185.94625963144793, 175.81348574612934, 176.0392082618988, 178.58343821605177, 183.97822890562134, 169.4968813221996, 165.5565065415866]\n",
+ "opt_prices:[12, 10, 8, 8, 8, 13, 10]\n",
+ "rev_std: 690.4600457482996\n",
+ "penalty_term: -0.003895075060427189\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:12774.905484494411\n",
+ "prediction_variance:702.2596528682677\n",
+ "energy:70213190.3828125\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 167.57329640132647, 169.7377534468004, 166.5809089973713, 166.8241787964222, 144.85057171647898]\n",
+ "opt_prices:[10, 10, 12, 8, 10, 10, 16]\n",
+ "rev_std: 760.6239136631048\n",
+ "penalty_term: 0.001470223069190979\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:11667.308525800716\n",
+ "prediction_variance:702.412810625621\n",
+ "energy:702401143.3203125\n",
+ "opt_demand:[185.94625963144793, 168.59433956627447, 169.57171234908157, 172.6110577169144, 179.88892184923827, 178.55901332210226, 181.33220836064368]\n",
+ "opt_prices:[12, 12, 8, 8, 8, 10, 8]\n",
+ "rev_std: 660.4122866959771\n",
+ "penalty_term: 0.003217339515686035\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:10547.842565002704\n",
+ "prediction_variance:701.9551138790306\n",
+ "energy:7019540590.9375\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 174.79244258118132, 168.98610317976278, 173.30493976354637, 189.45646671612218, 204.37427620035757]\n",
+ "opt_prices:[10, 10, 10, 10, 8, 5, 5]\n",
+ "rev_std: 580.4321159096354\n",
+ "penalty_term: -0.010241508483886719\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:10999.322306622127\n",
+ "prediction_variance:701.8825186390502\n",
+ "energy:70188240864.57812\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 188.47908467385338, 181.42597959171735, 176.14748113921195, 188.84486512956772, 190.4844519313412]\n",
+ "opt_prices:[10, 8, 8, 10, 10, 5, 8]\n",
+ "rev_std: 590.4418148595013\n",
+ "penalty_term: -0.00457763671875\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:11671.62338254227\n",
+ "prediction_variance:702.2254866319277\n",
+ "energy:702225474960.3047\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 187.2323189931359, 171.82864455542838, 172.69333817699186, 186.3953617168881, 173.30888753870656]\n",
+ "opt_prices:[8, 8, 10, 12, 8, 5, 13]\n",
+ "rev_std: 640.5219703820226\n",
+ "penalty_term: 0.00048828125\n",
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13236.730899961218\n",
+ "prediction_variance:703.7806798074442\n",
+ "energy:57141.3359375\n",
+ "opt_demand:[200.38455199115765, 177.91975830198146, 171.06357921109287, 156.8976933075849, 162.4700705360342, 142.27358955298732, 113.21850090358835]\n",
+ "opt_prices:[8, 13, 10, 12, 8, 16, 19]\n",
+ "rev_std: 861.2398056717766\n",
+ "penalty_term: -0.0011432832106947899\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:12112.4296039292\n",
+ "prediction_variance:702.0797161052823\n",
+ "energy:689967.2890625\n",
+ "opt_demand:[193.16540581130278, 175.06183547909168, 175.54409284821895, 176.70036477329745, 181.65550911911788, 179.7037015521259, 167.6497308850617]\n",
+ "opt_prices:[10, 12, 8, 8, 8, 10, 12]\n",
+ "rev_std: 680.4481890220659\n",
+ "penalty_term: 0.0025611468590795994\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:11792.924595157247\n",
+ "prediction_variance:702.3924264432308\n",
+ "energy:7012131.34375\n",
+ "opt_demand:[193.16540581130278, 175.06183547909168, 168.32494666836413, 155.79457650077055, 155.52899061449125, 149.98299140479602, 170.53166471995328]\n",
+ "opt_prices:[10, 12, 10, 12, 10, 12, 5]\n",
+ "rev_std: 710.6152086362777\n",
+ "penalty_term: 0.0039128502830863\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:12194.85761350477\n",
+ "prediction_variance:701.8919743058643\n",
+ "energy:70177002.578125\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 182.67274527243484, 178.52566999564607, 164.17407363940606, 160.33994092657696]\n",
+ "opt_prices:[10, 10, 8, 8, 10, 13, 10]\n",
+ "rev_std: 690.4910630253685\n",
+ "penalty_term: 0.005152076482772827\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:11242.602046086131\n",
+ "prediction_variance:702.4748933885294\n",
+ "energy:702463650.78125\n",
+ "opt_demand:[185.94625963144793, 175.81348574612934, 176.0392082618988, 189.41215748583403, 186.4603265949923, 190.03582160772567, 189.1059725889217]\n",
+ "opt_prices:[12, 10, 8, 5, 10, 8, 8]\n",
+ "rev_std: 610.3991271613321\n",
+ "penalty_term: -0.005233287811279297\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:10704.831049213793\n",
+ "prediction_variance:702.4259815510339\n",
+ "energy:7024249110.6796875\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 194.45146517299077, 203.56315209773754, 212.13067364077173, 195.82223275998587, 193.75825000940995]\n",
+ "opt_prices:[8, 8, 8, 5, 5, 12, 8]\n",
+ "rev_std: 540.5693089280617\n",
+ "penalty_term: 0.000396728515625\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:12118.204399688242\n",
+ "prediction_variance:702.0775739077151\n",
+ "energy:70207745272.57031\n",
+ "opt_demand:[200.38455199115765, 195.9676237516186, 180.01317281328105, 172.58029482246604, 158.750161230962, 157.2955778843709, 158.3468258146745]\n",
+ "opt_prices:[8, 8, 12, 10, 12, 10, 10]\n",
+ "rev_std: 700.5863093976069\n",
+ "penalty_term: 0.003204345703125\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:10350.06038481572\n",
+ "prediction_variance:702.4846362905347\n",
+ "energy:702484625940.4688\n",
+ "opt_demand:[211.2132712609399, 205.66886762084437, 203.41003592169682, 198.86839341252983, 187.03144522672824, 197.67896620376422, 196.46329619804368]\n",
+ "opt_prices:[5, 8, 8, 8, 10, 5, 8]\n",
+ "rev_std: 520.6166233702603\n",
+ "penalty_term: -0.0054931640625\n",
+ "---\n",
+ "beta_sample:100.0\n",
+ "max_revenue:13101.089112842521\n",
+ "prediction_variance:703.2120045508508\n",
+ "energy:57220.109375\n",
+ "opt_demand:[200.38455199115765, 177.91975830198146, 178.28272539094775, 170.58433540025698, 160.4716545882791, 153.83857764258306, 120.0646260572107]\n",
+ "opt_prices:[8, 13, 8, 10, 12, 12, 19]\n",
+ "rev_std: 820.959265376438\n",
+ "penalty_term: -0.001967242562386673\n",
+ "---\n",
+ "beta_sample:1000.0\n",
+ "max_revenue:12799.39306175473\n",
+ "prediction_variance:702.7497978139801\n",
+ "energy:689950.3984375\n",
+ "opt_demand:[200.38455199115765, 188.74847757176371, 173.54567690046386, 155.77919505354637, 144.9596103053531, 135.7417005960029, 130.53821386106824]\n",
+ "opt_prices:[8, 10, 12, 13, 12, 13, 13]\n",
+ "rev_std: 810.9564396486212\n",
+ "penalty_term: -0.006314725265838206\n",
+ "---\n",
+ "beta_sample:10000.0\n",
+ "max_revenue:11668.057902789285\n",
+ "prediction_variance:702.114905983479\n",
+ "energy:7009481.0\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 188.47908467385338, 199.47384504135448, 192.31622092125497, 192.94709710762896, 172.9586102534359]\n",
+ "opt_prices:[10, 8, 8, 5, 10, 8, 13]\n",
+ "rev_std: 620.5042342568443\n",
+ "penalty_term: -0.0019320007413625717\n",
+ "---\n",
+ "beta_sample:100000.0\n",
+ "max_revenue:12133.533110080407\n",
+ "prediction_variance:702.0571376283112\n",
+ "energy:70193580.234375\n",
+ "opt_demand:[193.16540581130278, 175.06183547909168, 168.32494666836413, 163.0137226806254, 169.2156327071633, 176.86116017646032, 168.26133247161616]\n",
+ "opt_prices:[10, 12, 10, 10, 8, 8, 12]\n",
+ "rev_std: 700.4772829770868\n",
+ "penalty_term: 0.004653960466384888\n",
+ "---\n",
+ "beta_sample:1000000.0\n",
+ "max_revenue:10843.245671844892\n",
+ "prediction_variance:701.7569277253392\n",
+ "energy:701746084.4921875\n",
+ "opt_demand:[193.16540581130278, 182.28098165894653, 182.0115887610362, 175.45359909257996, 179.27732026268376, 182.717054502723, 196.43961960101143]\n",
+ "opt_prices:[10, 10, 8, 10, 8, 8, 5]\n",
+ "rev_std: 590.4245277513222\n",
+ "penalty_term: 0.012520194053649902\n",
+ "---\n",
+ "beta_sample:10000000.0\n",
+ "max_revenue:11696.71176176828\n",
+ "prediction_variance:702.2911264607972\n",
+ "energy:7022899567.890625\n",
+ "opt_demand:[200.38455199115765, 188.74847757176371, 173.54567690046386, 166.60791432332866, 154.66085417457893, 173.57685606412835, 173.3708773666939]\n",
+ "opt_prices:[8, 10, 12, 10, 12, 5, 10]\n",
+ "rev_std: 670.533082027326\n",
+ "penalty_term: -0.005584716796875\n",
+ "---\n",
+ "beta_sample:100000000.0\n",
+ "max_revenue:11259.819536849312\n",
+ "prediction_variance:701.8711813398561\n",
+ "energy:70187106874.17188\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 181.2599384939985, 174.95848367890017, 177.39424681992944, 191.22305398600184, 187.4710989807441]\n",
+ "opt_prices:[10, 8, 10, 10, 8, 5, 10]\n",
+ "rev_std: 610.443345015263\n",
+ "penalty_term: 0.00579833984375\n",
+ "---\n",
+ "beta_sample:1000000000.0\n",
+ "max_revenue:12094.573836154155\n",
+ "prediction_variance:702.2972898129863\n",
+ "energy:702297277718.4141\n",
+ "opt_demand:[193.16540581130278, 189.5001278388014, 170.43121922421625, 172.4763859895292, 174.9031719840405, 165.79446227107266, 166.27428943744752]\n",
+ "opt_prices:[10, 8, 13, 8, 8, 12, 10]\n",
+ "rev_std: 690.5026388893243\n",
+ "penalty_term: 0.001708984375\n"
+ ]
+ }
+ ],
+ "source": [
+ "#beta_options=[1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9]\n",
+ "#results = {beta_option:[] for beta_option in beta_options}\n",
+ "#beta_samples = beta_options*6\n",
+ "\n",
+ "#for beta_i in beta_samples:\n",
+ "# max_revenue, prediction_variance, energy, opt_demand, opt_prices, rev_std = optimize(\n",
+ "# a = a,\n",
+ "# b = b,\n",
+ "# data_x = data_x,\n",
+ "# selected_hist_prices = p_data,\n",
+ "# price_levels = price_levels,\n",
+ "# Lp = Lp,\n",
+ "# Ld = Ld,\n",
+ "# sigma = sigma ,\n",
+ "# beta=beta_i,\n",
+ "# vol_bound=None,\n",
+ "# s3_folder=s3_folder\n",
+ "# )\n",
+ "# print('---')\n",
+ "# print(f\"beta_sample:{beta_i}\")\n",
+ "# print(f\"max_revenue:{max_revenue}\")\n",
+ "# print(f\"prediction_variance:{prediction_variance}\")\n",
+ "# print(f\"energy:{energy}\")\n",
+ "# print(f\"opt_demand:{opt_demand}\")\n",
+ "# print(f\"opt_prices:{opt_prices}\")\n",
+ "# print(f\"rev_std: {rev_std}\")\n",
+ "# print(f\"penalty_term: {max_revenue-beta_i*prediction_variance+energy}\")\n",
+ "# results[beta_i].append([energy, max_revenue, prediction_variance, rev_std])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d853f336",
+ "metadata": {},
+ "source": [
+ "We can see from the plot below that there is a Pareto front [11] where the expected revenue cannot be increased without increasing the standard deviation (i.e. uncertainties), and the other way around.\n",
+ "\n",
+ "We can see that the expected revenue can vary significantly between 10000 and 13500, while the estimated standard deviation of the revenue (i.e. uncertainty) can change in a large range $[550,900]$ as well. The figure shows that as the expected revenue increases, the estimated standard deviation of the revenue will also increase. This means that if we select a price solution for higher expected revenue, the uncertainties will increase at the same time indicating that the demand estimation model will become less confident about its predictions. This illustrates there is a trade-off between maximizing the revenue and minimizing the uncertainty. High revenue and rewards usually accompany with high uncertainties and risk. In practice, according to different business strategies and needs, we usually need to find an appropriate $\\beta$ to maximize the revenue under an acceptable level of uncertainty."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "b6db5e4c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "beta_x=[]\n",
+ "revenue_y=[]\n",
+ "variance_y=[]\n",
+ "rev_std_y=[]\n",
+ "\n",
+ "for beta_i in beta_options:\n",
+ " for result in results[beta_i]:\n",
+ " beta_x.append(beta_i)\n",
+ " revenue_y.append(result[1])\n",
+ " variance_y.append(result[2])\n",
+ " rev_std_y.append(result[3])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "719f9fce",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.rcParams.update({'font.size': 18})\n",
+ "plt.figure(figsize=(10,8))\n",
+ "plt.scatter(revenue_y, rev_std_y)\n",
+ "plt.xlabel('Revenue')\n",
+ "plt.ylabel('Revenue standard deviation')\n",
+ "plt.savefig('tradoff_sigma=10_b=300.png')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f2667f41",
+ "metadata": {},
+ "source": [
+ "# 5. Conclusion"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "febb3839",
+ "metadata": {},
+ "source": [
+ "In this notebook, we demonstrate how to leverage a quantum annealer on Amazon Braket to solve a price optimization use case. We showed how to mathematically formulate the problem within the (quantum-ready) QUBO framework, and then subsequently solve the optimization problem on a D-Wave quantum annealer. Our results are promising in terms of both close-to-optimal quality and computational efficiency. Since the QUBO formalism is a generalized framework that can embrace a variety of combinatorial optimization use cases (e.g. scheduling/planning, routing, portfolio management), the proposed solution can be arguably adapted and recycled by customers across other multiple industries. Already today our customers can get quantum-ready, and easily leverage Amazon Braket to help solve their daily combinatorial optimization challenges, and make better business and operation decisions."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9c00a940",
+ "metadata": {},
+ "source": [
+ "# 6. References:\n",
+ "1. Glover, F., Kochenberger, G. and Du, Y., 2019. Quantum Bridge Analytics I: a tutorial on formulating and using QUBO models. 4OR, 17(4), pp.335-371.\n",
+ "2. Kochenberger, G., Hao, J.K., Glover, F., Lewis, M., Lü, Z., Wang, H. and Wang, Y., 2014. The unconstrained binary quadratic programming problem: a survey. Journal of combinatorial optimization, 28(1), pp.58-81.\n",
+ "3. Anthony, M., Boros, E., Crama, Y. and Gruber, A., 2017. Quadratic reformulations of nonlinear binary optimization problems. Mathematical Programming, 162(1), pp.115-144.\n",
+ "4. Amazon Web Services. Amazon Braket – Amazon Web Services, 2021. Available at: https://aws.amazon.com/braket/ (Accessed: 15 July, 2021)\n",
+ "5. Cruz-Santos, W., Venegas-Andraca, S.E. and Lanzagorta, M., 2019. A QUBo formulation of Minimum Multicut problem instances in trees for D-Wave Quantum Annealers. Scientific reports, 9(1), pp.1-12.\n",
+ "6. Amazon Web Services. A python SDK for interacting with quantum devices via AWS, 2021. Available at: https://github.com/aws/amazon-braket-sdk-python (Accessed: 16 July, 2021) \n",
+ "7. Amazon Web Services. Amazon SageMaker – Machine Learning – Amazon Web Services, 2021. Available at: https://aws.amazon.com/sagemaker/ (Accessed: 20 July, 2021)\n",
+ "8. Ben-Tal, A. and Nemirovski, A., 2002. Robust optimization–methodology and applications. Mathematical programming, 92(3), pp.453-480.\n",
+ "9. Fabozzi, F.J., Kolm, P.N., Pachamanova, D.A. and Focardi, S.M., 2007. Robust portfolio optimization and management. John Wiley & Sons.\n",
+ "10. Hyndman, R.J. and Athanasopoulos, G., 2018. Forecasting: principles and practice. OTexts. Available at: https://otexts.com/fpp2/regression-matrices.html (Accessed: 20 July, 2021)\n",
+ "11. Wikipedia. Pareto front - Wikipedia, 2021. Available at: https://en.wikipedia.org/wiki/Pareto_front (Accessed: 21 Dec, 2021)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5a26a9dc",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "conda_braket",
+ "language": "python",
+ "name": "conda_braket"
+ },
+ "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.7.11"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/quantum_annealing/price_optimization/qubo_dynamic_pricing.py b/examples/quantum_annealing/price_optimization/qubo_dynamic_pricing.py
new file mode 100644
index 000000000..fffbc2137
--- /dev/null
+++ b/examples/quantum_annealing/price_optimization/qubo_dynamic_pricing.py
@@ -0,0 +1,288 @@
+from pyqubo import Binary
+import numpy as np
+import dimod
+from braket.ocean_plugin import BraketDWaveSampler
+from dwave.system.composites import EmbeddingComposite
+from itertools import combinations
+
+np.random.seed(0)
+
+def get_coeffient(expr, mode):
+ coeffs, consts = expr.compile().to_qubo()
+ if mode == 'linear':
+ new_coeffs = {}
+ for k, v in coeffs.items():
+ assert k[0] == k[1]
+ new_coeffs[k[0]] = v
+ elif mode == 'quadratic':
+ new_coeffs = coeffs
+ else:
+ raise TypeError(f"unknown mode: {mode}")
+
+ return new_coeffs, consts
+
+
+def get_demand(coeff, b, prices):
+ assert len(coeff) == len(prices)
+ d = b
+ for i in range(len(coeff)):
+ d += coeff[i]*prices[i]
+
+ return d
+
+
+def get_variance(data_x, p, sigma):
+ """
+ :param data_x (np.array): [n_samples, n_days]
+ :param p (list): [n_days]
+ :return: variance
+ """
+ n_samples, t = data_x.shape
+ ones = np.ones((n_samples, 1), dtype=np.float)
+ x_mat = np.concatenate([ones, data_x], axis=1) # [n_samples, n_days+1]
+ x_mat = np.linalg.inv(
+ np.dot(x_mat.T, x_mat)
+ )
+ p = np.array([1.]+p)
+ variance = (sigma**2) * (1. + p.dot(x_mat).dot(p))
+ return variance
+
+
+def get_covariance(data_x, p1, p2, sigma):
+ """
+ :param data_x (np.array): [n_samples, n_days]
+ :param p1, p2 (list): [n_days]
+ :return: variance
+ """
+ n_samples, t = data_x.shape
+ ones = np.ones((n_samples, 1), dtype=np.float)
+ x_mat = np.concatenate([ones, data_x], axis=1) # [n_samples, n_days+1]
+ x_mat = np.linalg.inv(
+ np.dot(x_mat.T, x_mat)
+ )
+ p1 = np.array([1.] + p1)
+ p2 = np.array([1.] + p2)
+ variance = (sigma**2) * (1. + p1.dot(x_mat).dot(p2))
+ return variance
+
+
+def create_program(a,b, p_data, price_levels, data_x, Lp, Ld, sigma, beta, vol_bound):
+ """
+
+ :param a (list of int): [7], coefficient
+ :param b (int):
+ :param p_data (list of int): [7], past 7 days prices
+ :param price_levels (list of int): number of price levels
+ :param data_x (np.array): [nsamples, n_days]
+ :param L (float): coeff of constraints penalty
+ :param sigma (float): standard deviation of noise
+ :param beta (float): coeff of variance
+ :return:
+ """
+ assert type(a) is list
+ #assert type(b) is int
+ assert type(p_data) is list
+ assert type(price_levels) is list
+
+ t = len(a)
+ n_level = len(price_levels)
+
+ # variables
+ x = []
+ p = []
+ d = []
+
+ # get p
+ for i in range(t):
+ p_i = 0
+ for j in range(n_level):
+ x_ij = Binary(f"X_{i*n_level+j:03d}")
+ x.append(x_ij)
+ p_i += x_ij*price_levels[j]
+ p.append(p_i)
+
+ all_p = p_data + p
+
+ # get d, rev
+ rev = 0
+ for i in range(t):
+ d_i = get_demand(
+ coeff=a,
+ b=b,
+ prices=all_p[i+1:i+1+t]
+ )
+ d.append(d_i)
+ rev += d_i * p[i]
+ # minus variance
+ rev -= beta * get_variance(data_x, all_p[i+1:i+1+t], sigma)
+ # add inequaliry constraints
+ if vol_bound:
+ _, d_const = get_coeffient(d_i, 'linear')
+ rev -= inequality_penalty(
+ demand=d_i,
+ demand_name=f'demand{i}',
+ vol_bounday=vol_bound,
+ d_const=d_const,
+ Ld=Ld
+ )
+
+ # add equalty constraints
+ for i in range(t):
+ penalty = x[i*n_level]
+ for j in range(1, n_level):
+ penalty += x[i*n_level+j]
+ penalty = ((penalty-1)**2)*Lp
+ rev -= penalty
+
+ return rev, d
+
+
+def construct_slack(n, name):
+ e = 0
+ slack = 0
+ while n >= 2**e:
+ n -= 2**e
+ slack += (2**e) * Binary(f"{name}_{e}")
+ e += 1
+
+ slack += n * Binary(f"{name}_{e}")
+ return slack
+
+
+def inequality_penalty(demand, demand_name, vol_bounday, d_const, Ld):
+ rhs = vol_bounday - d_const
+ assert rhs <= 0
+ n = -rhs
+ slack = construct_slack(n, demand_name)
+ return ((demand-vol_bounday-slack)**2)*Ld
+
+
+def optimize(
+ a,
+ b,
+ data_x,
+ selected_hist_prices,
+ price_levels,
+ Lp,
+ Ld,
+ sigma,
+ beta,
+ vol_bound,
+ s3_folder=None,
+ dwave=True
+):
+ """
+
+ :param a: list of int, coeff
+ :param b: int, const
+ :param data_x: training set of x
+ :param selected_hist_prices: list, last n days prices
+ :param price_levels: list of int, options of prices
+ :param Lp: int, coeff of price constraints penalty
+ :param Ld: int, coeff of demand constraints penalty
+ :param sigma: float, stand deviation of noise
+ :param beta: float, coeff of variance penalty
+ :param vol_bound: float, boundary of demand
+ :return:
+ """
+ obj, demands = create_program(
+ a=a,
+ b=b,
+ p_data=selected_hist_prices,
+ price_levels=price_levels,
+ data_x=data_x,
+ Lp=Lp,
+ Ld=Ld,
+ sigma=sigma,
+ beta=beta,
+ vol_bound=vol_bound
+ )
+
+ # qubo solver
+ response = dwave_solver(obj, s3_folder) if dwave else qubo_solver(obj)
+
+ # get optimal prices
+ opt_prices, _, energy = decoder_price_response(response, len(a), price_levels)
+ opt_demand, max_revenue = get_demands_rev(a, b, selected_hist_prices, opt_prices)
+ prediction_variance = get_overall_variance(data_x, selected_hist_prices, opt_prices, sigma)
+ revenue_variance = get_overall_revenue_variance(data_x, selected_hist_prices, opt_prices, sigma)
+
+ return max_revenue, prediction_variance, energy, opt_demand, opt_prices, np.sqrt(revenue_variance)
+
+
+def qubo_solver(obj):
+ model = (-obj).compile().to_bqm()
+ num_shots = 100
+
+ sampler = dimod.SimulatedAnnealingSampler()
+ response = sampler.sample(model, num_reads=num_shots)
+ return response
+
+
+def dwave_solver(obj, s3_folder):
+ model = (-obj).compile().to_bqm()
+ num_shots = 10000
+
+ device_arn = 'arn:aws:braket:::device/qpu/d-wave/Advantage_system4'
+ if s3_folder:
+ sampler = BraketDWaveSampler(s3_folder, device_arn=device_arn)
+ else:
+ sampler = BraketDWaveSampler(device_arn=device_arn)
+
+ sampler = EmbeddingComposite(sampler)
+ response = sampler.sample(model, num_reads=num_shots)
+ return response
+
+
+def decoder_price_response(response, n_days, price_options):
+ opt_price, energy = response.record.sample[response.record.energy.argmin()], response.record.energy.min()
+ prices = []
+ for i in range(n_days):
+ price_i = opt_price[i*len(price_options): (i+1)*len(price_options)]
+ assert price_i.sum()==1
+ prices.append(price_options[price_i.argmax()])
+ return prices, opt_price, energy
+
+
+def get_demands_rev(a, b, hist_p, p):
+ all_p = hist_p + p
+ t = len(a)
+ d = []
+ revenue = 0
+ for i in range(t):
+ d_i = get_demand(
+ coeff=a,
+ b=b,
+ prices=all_p[i+1:i+1+t]
+ )
+ d.append(d_i)
+ revenue += d_i * p[i]
+ return d, revenue
+
+
+def get_overall_variance(data_x, hist_p, p, sigma):
+ all_p = hist_p + p
+ t = len(p)
+ var = 0
+ for i in range(t):
+ var += get_variance(data_x, all_p[i+1:i+1+t], sigma)
+
+ return var
+
+
+def get_overall_revenue_variance(data_x, hist_p, p, sigma):
+ all_p = hist_p + p
+ t = len(p)
+ var = 0
+ for i in range(t):
+ var += get_variance(data_x, all_p[i+1:i+1+t], sigma) * (p[i]**2)
+
+ for i, j in combinations(list(range(t)), 2):
+ var += get_covariance(
+ data_x,
+ all_p[i + 1:i + 1 + t],
+ all_p[j + 1:j + 1 + t],
+ sigma
+ ) * 2 * p[i] * p[j]
+
+ return var