Last active
July 6, 2018 06:38
-
-
Save dantaeyoung/79e483c6c0a6671b7cbf9ed156520cf0 to your computer and use it in GitHub Desktop.
process to generate all possible studio combinations and to rank them by trying to make the lowest ranking the highest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random, sys, itertools, math, statistics | |
PEOPLES_CHOICES = [ | |
['K','D','C','N','A','E','H','I','L','M'], | |
['I','H','J','E','C','F','D','N','K','A'], | |
['N','M','D','L','A','K','J','D','G','I'], | |
['D','N','K','L','M','J','G','I','H','F'], | |
['D','K','N','F','B','G','J','E','C','I'], | |
['D','N','K','I','H','A','E','C','F','M'] | |
] | |
# generate all possible studio space combos -- for example, a K studio can only exist with an L studio | |
# (order doesn't matter) | |
def gencombos(): | |
s1 = ["A"] | |
s2 = ["KL", "BC", "GH"] | |
s3 = ["D"] | |
s4 = ["IJ", "MN", "EF"] | |
combos = [] | |
for this1 in s1: | |
for this2 in s2: | |
for this3 in s3: | |
for this4 in s4: | |
combos.append(this1 + this2 + this3 + this4) | |
return combos | |
GENCOMBOS = gencombos() | |
# compare two strings as sets (order doesn't matter) | |
def setcmp(a, b): | |
return set(a) == set(b) | |
def is_studiocombo_valid(cs): | |
if(sum([setcmp(cs, thisg) for thisg in GENCOMBOS]) == 0): | |
# chromosome isn't a valid studio possibility because this studio combo doesn't match any of the possible studio combos | |
return false | |
# calculate a studio layout score based on each person's choice | |
def studiocombo_rank_function(cs): | |
peoples_rank = [] | |
for i, thisc in enumerate(cs): | |
if thisc in PEOPLES_CHOICES[i]: | |
rank = PEOPLES_CHOICES[i].index(thisc) | |
else: | |
rank = 20 # if the choice isn't part of someone's top 10 choices, set it as their 20th choice (aka really bad) | |
peoples_rank.append(rank) | |
# each rank adds 10**rank to the score.. so if you get your second choice, you get 10**2 points | |
# this way the GA is incentivized to minimize the worst rank as much as possible | |
# because someone having their 5th choice is literally 10 times worse than someone having their 4th choice | |
total_rank_base_10 = 0 | |
for pr in peoples_rank: | |
total_rank_base_10 += 10**pr | |
return total_rank_base_10 | |
def pretty_print_combo(combo): | |
peoples_rank = [] | |
for i, thisc in enumerate(combo): | |
if thisc in PEOPLES_CHOICES[i]: | |
rank = PEOPLES_CHOICES[i].index(thisc) | |
else: | |
rank = 20 # if the choice isn't part of someone's top 10 choices, set it as their 20th choice | |
peoples_rank.append(rank) | |
for i, r in enumerate(zip(combo, peoples_rank)): | |
print("the " + ordinal(i + 1) + " person gets " + str(r[0]) + ", which is their " + ordinal(r[1] + 1) + " choice") | |
#from https://codereview.stackexchange.com/questions/41298/producing-ordinal-numbers | |
def ordinal(num): | |
SUFFIXES = {1: 'st', 2: 'nd', 3: 'rd'} | |
# I'm checking for 10-20 because those are the digits that | |
# don't follow the normal counting scheme. | |
if 10 <= num % 100 <= 20: | |
suffix = 'th' | |
else: | |
# the second parameter is a default. | |
suffix = SUFFIXES.get(num % 10, 'th') | |
return str(num) + suffix | |
######## | |
if __name__ == '__main__': | |
# generate all the possible studio distributions | |
allgencombos = list(itertools.chain.from_iterable( | |
[[''.join(p) for p in itertools.permutations(thisgc)] for thisgc in GENCOMBOS] | |
)) | |
# calculate all of their scores based on each person's choice | |
allgencombos_and_scores = [(studiocombo_rank_function(agc), agc) for agc in allgencombos] | |
# sort them by scores, ascending | |
sorted_combos = sorted(allgencombos_and_scores, key=lambda x: x[0]) | |
# print the top 20 best scores | |
for i, sc in enumerate(sorted_combos[:20]): | |
print("========== " + ordinal(i + 1) + " best: ==== " + sc[1]) | |
pretty_print_combo(sc[1]) | |
print(" total score (smaller is better): " + str(sc[0])) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment