Skip to content

Instantly share code, notes, and snippets.

@lvh
Created April 8, 2014 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lvh/10107818 to your computer and use it in GitHub Desktop.
Save lvh/10107818 to your computer and use it in GitHub Desktop.
PyCon financial aid grant optimization with COBYLA
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "PyCon grant optimization COBYLA"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": "def expected_regret(grants, k, scores, requested):\n \"\"\"-1 * the expectance of the scores.\n\n \"\"\"\n probabilities = (grants ** k) / (requested ** k)\n return -1 * sum(scores * probabilities)",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": "from functools import partial\n\ndef budget_constraint(grants, budget):\n \"\"\"The budget minus the sum of all grants; must be >= 0.\n\n \"\"\"\n return budget - sum(grants)\n\n\ndef make_grant_constraints(requested_amounts):\n \"\"\"\n Makes all the grant constraints\n \"\"\"\n le_requested = [partial(_grant_le_requested, index=i, requested_amount=amount)\n for i, amount in enumerate(requested_amounts)]\n gt_zero = [(lambda grants, i=i: grants[i]) for i in xrange(len(requested_amounts))]\n return le_requested + gt_zero\n\n\ndef _grant_le_requested(grants, index, requested_amount):\n \"\"\"Constraint function that makes sure the grant amount with given\n index is less than or equal to the requested amount.\n\n \"\"\"\n return requested_amount - grants[index]",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": "from numpy import array, zeros\nfrom scipy.optimize import fmin_cobyla\n\ndef main():\n scores = array([1, 1, 1, 2, 3, 5, 5])\n requested = array([10, 20, 30, 30, 50, 10, 50])\n budget = 150\n\n print \"scores: {}\".format(scores)\n print \"requested: {} total: {}, budget: {}\".format(requested, sum(requested), budget)\n\n the_budget_constraint = partial(budget_constraint, budget=budget)\n the_grant_constraints = make_grant_constraints(requested)\n constraints = [the_budget_constraint] + the_grant_constraints\n\n for ik in [(1./2), 1, 2, 3, 5, 10, 100]:\n res = fmin_cobyla(expected_regret, args=(1./ik, scores, requested),\n x0=zeros(len(scores)),\n cons=constraints, consargs=(),\n disp=0)\n print \"k = 1/{}: {}, sum: {}\".format(ik, res.round(), res.sum())",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 18
},
{
"cell_type": "code",
"collapsed": false,
"input": "main()\n",
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": "scores: [1 1 1 2 3 5 5]\nrequested: [10 20 30 30 50 10 50] total: 200, budget: 150\nk = 1/0.5: [ 10. 20. 30. 30. 50. 10. 0.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/1: [ 10. -0. 0. 30. 50. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/2: [ 10. 10. 7. 27. 36. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/3: [ 10. 11. 9. 25. 35. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/5: [ 10. 11. 10. 24. 35. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/10: [ 10. 11. 11. 23. 35. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\nk = 1/100: [ 10. 11. 11. 23. 34. 10. 50.], sum: 150.0"
},
{
"output_type": "stream",
"stream": "stdout",
"text": "\n"
}
],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": "",
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment