Răsfoiți Sursa

proof of concept using the CSP (constrain solver) module

limitations:
- does not "wrap around" the table
- scenario is hard-coded with no possbility of user input
George C. Privon 2 ani în urmă
comite
c54c9cabda
2 a modificat fișierele cu 83 adăugiri și 0 ștergeri
  1. 14 0
      README.md
  2. 69 0
      seating_chart.rkt

+ 14 - 0
README.md

@@ -0,0 +1,14 @@
+# Seating Chart
+
+From an input list of guests (and constraints), automatically generate a seating chart.
+
+Input constraints can include:
+
+[ ] Left-handed people (put them on left edges of tables)
+    - Check to make sure the number of left-handed people is equal to or smaller than the number of table edges
+[ ] People who must be seated adjacent to each other (e.g., parents and children)
+[ ] Separating people
+    - Couples (dinner party rules)
+    - People who should be separated
+
+

+ 69 - 0
seating_chart.rkt

@@ -0,0 +1,69 @@
+#lang racket/base
+
+(require racket/list)
+(require csp)
+
+(define seating-chart (make-csp))
+
+(define Npeople 6)
+
+; return a series of seat variables from [start, end)
+(define (chairs-subset start end) (make-var-names
+                "seat"
+                (range start end)))
+
+; return all chairs
+(define chairs
+  (chairs-subset 0 Npeople))
+
+(add-vars! seating-chart 
+           chairs
+           (range Npeople))
+
+; constraint for people wanting to sit next to each other
+; p1 wants to sit next to p2
+(define (person-next-to p1 p2 a b c)
+  (if (= b p1)
+      (or (= a p2)
+          (= c p2))
+      #false))
+
+; constraint for people avoiding each other
+; p1 does not want to sit next to p2
+(define (person-avoiding p1 p2 a b c)
+  (if (= b p1)
+      (and (not (= a p2))
+          (not (= c p2)))
+      #false))
+
+; Constraints------------------------------------------------------------------
+
+; # General constraints #######################################################
+; 1. people can't occupy more than one seat
+(add-pairwise-constraint! seating-chart
+                          (lambda (a b) (not (= a b)))
+                          chairs)
+
+; # Solution-specific constraints (for a given problem) ######################
+; These should be replaced with inputs, for a general user-submitted query
+
+; person 2 wants to sit in seat 1, next to person 4
+; TODO: this misses the ends (assuming the table is not just a line). person 2 in seat 0 and person 4 in seat 5 doesn't match, nor does person 2 in seat 5 and person 4 in seat 0
+(add-constraint! seating-chart
+                 (lambda (a b c) (person-next-to 2 4 a b c))
+                 (chairs-subset 0 3))
+
+; person 2 wants to sit next to person 4
+(define (adjacent-constraint person1 person2)
+  (map (add-constraint! seating-chart)))
+
+; person 2 wants to sit in seat 1, but doesn't want to sit next to person 5
+; TODO: this misses the ends (assuming the table is not just a line). person 2 in seat 0 and person 5 in seat 5 would incorrectly pass, as would person 2 in seat 5 and person 5 in seat 0
+(add-constraint! seating-chart
+                 (lambda (a b c) (person-avoiding 2 5 a b c))
+                 (chairs-subset 0 3))
+
+(printf "Size of state space: ~a.~n"
+        (state-count seating-chart))
+
+(time (solve* seating-chart 1))