Skip to content

Instantly share code, notes, and snippets.

@Engelberg
Created March 6, 2014 09:22
Show Gist options
  • Save Engelberg/9385992 to your computer and use it in GitHub Desktop.
Save Engelberg/9385992 to your computer and use it in GitHub Desktop.
Non-linear version of grants problem
(ns mark.loco.grants2
(:use loco.core loco.constraints))
; Use whatever scoring function you want for the various
; applicants, but ultimately, you want to assemble this
; information into a data structure.
(def applicants
[{:name "Alex", :score 5, :grant-request 120}
{:name "David", :score 4, :grant-request 100}
{:name "Mark", :score 3, :grant-request 80}])
(def n (count applicants))
(def budget 200)
; variable [:allocation n] is how much money to allocate to
; the applicant at the nth position of the applicants vector
(def allocation-vars
(for [i (range n)] [:allocation i]))
(def grant-constraints
; Don't give any person more than they asked for
(for [i (range n)]
($in [:allocation i] 0 (:grant-request (applicants i)))))
(def budget-constraint
; Don't spend more than the budget permits
($<= (apply $+ allocation-vars) budget))
(def all-constraints (conj grant-constraints budget-constraint))
; If you assume that the probability of someone coming
; is the allocation they received divided by the grant
; requested, squared, then the "value" of each dollar given to
; a person is their score divded by the size of their grant request.
(def grant-fractional-values
(for [i (range n)]
(/ (:score (applicants i))
(* (:grant-request (applicants i))
(:grant-request (applicants i))))))
(def scale (/ 100 (- (apply max grant-fractional-values) (apply min grant-fractional-values))))
(def grant-values (map #(long (* scale %)) grant-fractional-values))
(solution all-constraints
:maximize (apply $+ (map $*
(map $* allocation-vars allocation-vars)
grant-values)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment