JSFiddle - React, Tailwind, and code Playground

by replicateur

HTML

<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 370px; width:100%;"></div>
<label for="trigger-1">p(A)</label><input type="decimal" name="trigger-1" value="0.58" /><br>
<label for="trigger-2">p(B)</label><input type="decimal" name="trigger-2" value="0.72" /><br>
<label for="trigger-3">p(C)</label><input type="decimal" name="trigger-3" value="0.15" /><br>
<button onclick="initializeBandit()">
  Start
</button>

CSS

input {
  margin: 0.25rem;
}

JavaScript

let runner;
let totalSelections = 0;
let bandits = [];

function initializeBandit() {
  let inputs = document.querySelectorAll('input[name^="trigger"]');
  for (let i = 0; i < inputs.length; ++i) {
    const item = inputs[i];
    bandits[i] = {
      'selections': 1,
      'cumulativeRewards': 0,
      'winProbability': parseFloat(item.value),
      'ucb': 0
    };
  }
  main();
}

// Calculate UCB
function calculateUCB(cumulativeRewards, selections, totalSelections) {
  const estimatedValue = cumulativeRewards / selections;
  return estimatedValue + Math.sqrt(2 * Math.log(totalSelections) / selections);
}

// Update reward for selected bandit
function updateReward(bandit) {
  if (Math.random() < parseFloat(bandits[bandit].winProbability)) {
    bandits[bandit].cumulativeRewards++;
  }
}

// Select bandit with highest UCB
function selectBestBandit(bandits) {
  let maxUCB = 0;
  let selectedBandit = 0;
  for (let i = 0; i < bandits.length; i++) {
    let bandit = bandits[i];
    if (bandit.ucb > maxUCB) {
      maxUCB = bandit.ucb;
      selectedBandit = i;
    }
  }
  bandits[selectedBandit].selections++;
  return selectedBandit;
}

// Main function
function main() {
  console.log("main started...");
  var dataPoints = []; // dataPoints
  var initData = [];
  for (let i = 0; i < bandits.length; i++) {
    dataPoints.push([]);
    initData.push({
      type: "line",
      name: "winProbability=" + Math.round(bandits[i].winProbability * 100) / 100,
      showInLegend: true,
      dataPoints: dataPoints[i]
    });
  }

  var chart = new CanvasJS.Chart("chartContainer", {
    title: {
      text: "UCB Bandit cumulative rewards"
    },
    data: initData
  });

  var xVal = 0;
  var yVal = 100;
  var updateInterval = 100;
  var dataLength = 200;

  var updateChart = function() {
    for (let i = 0; i < bandits.length; i++) {
      yVal = bandits[i].cumulativeRewards;
      if (yVal > 5) {
        clearInterval(runner);
      }
      dataPoints[i].push({
        x:...