Advertisement
Guest User

Untitled

a guest
Nov 30th, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.04 KB | None | 0 0
  1. (defpackage #:snippets/stable-matching
  2. (:use #:cl)
  3. (:shadowing-import-from
  4. #:fset #:empty-map #:reduce #:with #:set #:union #:image #:empty-set
  5. #:lookup #:includef #:excludef #:find-if #:notevery))
  6.  
  7. (in-package #:snippets/stable-matching)
  8.  
  9. (defstruct (person (:constructor make-person (name preference-list)))
  10. name
  11. preference-list)
  12.  
  13. (defparameter *men*
  14. (set (make-person 'bob '(alice carol eve))
  15. (make-person 'dave '(carol alice eve))
  16. (make-person 'frank '(alice eve carol))))
  17.  
  18. (defparameter *women*
  19. (set (make-person 'alice '(bob dave frank))
  20. (make-person 'carol '(bob dave frank))
  21. (make-person 'eve '(bob frank dave))))
  22.  
  23. ;; Find a matching such that for each pair, both the man and the woman
  24. ;; stick together because there's no better option available. In this
  25. ;; algorithm, the men (proposers) are at an advantage.
  26. ;;
  27. ;; For the example inputs, the stable matching found by the algorithm
  28. ;; is: ((bob alice) (eve frank) (dave carol)). Both alice and bob
  29. ;; prefer each other to every other alternative. Frank can't go with
  30. ;; alice, so sticks with eve, which can't go with bob. Dave prefers
  31. ;; carol, and carol can't go with bob so sticks with him.
  32.  
  33. (defun find-stable-matching (&optional (men *men*) (women *women*))
  34. (let ((persons (reduce (lambda (map person)
  35. (with map (person-name person) person))
  36. (union men women)
  37. :initial-value (empty-map)))
  38. (free-men (image #'person-name men))
  39. (free-women (image #'person-name women))
  40. (women (image #'person-name women))
  41. (proposals (empty-set))
  42. (engagements (empty-set)))
  43. (labels ((preference-list (x)
  44. (person-preference-list (lookup persons x)))
  45. (prefers? (chooser choice1 choice2)
  46. (< (position choice1 (preference-list chooser))
  47. (position choice2 (preference-list chooser))))
  48. (propose (m w)
  49. (includef proposals (cons m w)))
  50. (proposed? (m w)
  51. (lookup proposals (cons m w)))
  52. (engage (m w)
  53. (excludef free-men m)
  54. (excludef free-women w)
  55. (includef engagements (set m w)))
  56. (release (m w)
  57. (excludef engagements (set m w))
  58. (includef free-men m)
  59. (includef free-women w))
  60. (fiance (w)
  61. (find-if (lambda (x) (not (eq x w)))
  62. (find-if (lambda (e) (lookup e w)) engagements))))
  63. (loop for m = (find-if (lambda (m) (notevery (lambda (w) (proposed? m w)) women)) free-men)
  64. while m
  65. do (let ((w (find-if (lambda (w) (not (proposed? m w))) (preference-list m))))
  66. (propose m w)
  67. (cond ((lookup free-women w)
  68. (engage m w))
  69. ((prefers? w m (fiance w))
  70. (release (fiance w) w)
  71. (engage m w)))))
  72. engagements)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement