Speed dating algorithm

后端 未结 9 607
深忆病人
深忆病人 2021-02-04 10:19

I work in a consulting organization and am most of the time at customer locations. Because of that I rarely meet my colleagues. To get to know each other better we are going to

9条回答
  •  盖世英雄少女心
    2021-02-04 10:30

    This one was very funny! :D

    I tried different method but the logic suggested by adi92 (card + prize) is the one that works better than any other I tried.

    It works like this:

    1. a guy arrives and examines all the tables
    2. for each table with free seats he counts how many people he has to meet yet, then choose the one with more unknown people
    3. if two tables have an equal number of unknown people then the guy will choose the one with more free seats, so that there is more probability to meet more new people

    at each turn the order of the people taking seats is random (this avoid possible infinite loops), this is a "demo" of the working algorithm in python:

    import random
    
    class Person(object):
    
        def __init__(self, name):
            self.name = name
            self.known_people = dict()
    
        def meets(self, a_guy, propagation = True):
            "self meets a_guy, and a_guy meets self"
            if a_guy not in self.known_people:
                self.known_people[a_guy] = 1
            else:
                self.known_people[a_guy] += 1
    
            if propagation: a_guy.meets(self, False)
    
        def points(self, table):
            "Calculates how many new guys self will meet at table"
            return len([p for p in table if p not in self.known_people])
    
        def chooses(self, tables, n_seats):
            "Calculate what is the best table to sit at, and return it"
            points = 0
            free_seats = 0
            ret = random.choice([t for t in tables if len(t) points or (tmp_p == points and tmp_s > free_seats):
                    ret = table
                    points = tmp_p
                    free_seats = tmp_s
    
            return ret
    
        def __str__(self):
            return self.name
        def __repr__(self):
            return self.name
    
    
    def Switcher(n_seats, people):
        """calculate how many tables and what switches you need
            assuming each table has n_seats seats"""
    
        n_people = len(people)
        n_tables = n_people/n_seats
    
        switches = []
        while not all(len(g.known_people) == n_people-1 for g in people):
            tables = [[] for t in xrange(n_tables)]
    
            random.shuffle(people) # need to change "starter"
    
            for the_guy in people:
                table = the_guy.chooses(tables, n_seats)
                tables.remove(table)
                for guy in table:
                    the_guy.meets(guy)
                table += [the_guy]
                tables += [table]
    
            switches += [tables]
    
        return switches
    
    
    
    lst_people = [Person('Hallis'),
          Person('adi92'),
          Person('ilya n.'),
          Person('m_oLogin'),
          Person('Andrea'),
          Person('1800 INFORMATION'),
          Person('starblue'),
          Person('regularfry')]    
    
    
    
    s = Switcher(4, lst_people)
    
    print "You need %d tables and %d turns" % (len(s[0]), len(s))
    turn = 1
    for tables in s:
        print 'Turn #%d' % turn
        turn += 1
        tbl = 1
        for table in tables:
            print '  Table #%d - '%tbl, table
            tbl += 1
        print '\n'
    

    This will output something like:

    You need 2 tables and 3 turns
    Turn #1
      Table #1 -  [1800 INFORMATION, Hallis, m_oLogin, Andrea]
      Table #2 -  [adi92, starblue, ilya n., regularfry]
    
    
    Turn #2
      Table #1 -  [regularfry, starblue, Hallis, m_oLogin]
      Table #2 -  [adi92, 1800 INFORMATION, Andrea, ilya n.]
    
    
    Turn #3
      Table #1 -  [m_oLogin, Hallis, adi92, ilya n.]
      Table #2 -  [Andrea, regularfry, starblue, 1800 INFORMATION]
    

    Because of the random it won't always come with the minimum number of switch, especially with larger sets of people. You should then run it a couple of times and get the result with less turns (so you do not stress all the people at the party :P ), and it is an easy thing to code :P

    PS: Yes, you can save the prize money :P

提交回复
热议问题