2013-08-04 4 views
1

Я - трехмерная анимационная наставница с очень фундаментальным знанием Python, и я бил головой о стену, пытаясь закодировать то, что, по моему мнению, может быть ОЧЕНЬ полезным сценарием. Any помощь, включая простую точку в правильном направлении, была бы очень оценена. Заранее спасибо.Разделить группу людей пополам на основе предпочтений

Вот мой сценарий: Мой класс из 18 студентов вот-вот вступит в модуль «групповой проект». В этом году я хотел бы разделить класс пополам, чтобы проекты были более управляемыми, а также поощрять здоровое соревнование. Студенты уже заполнили опросы, в которых они аннотировали свое предпочтение работать со всеми другими учениками, задавая каждому номер между 0 и 5. Моя идея заключается в том, что я могу использовать эти опросы для математического расчета наилучшего возможного разделения в терминах предпочтения.

Теперь я сделал очень простой старт в CodeSkulptor - эмуляторе на основе python на основе браузера. В этой версии прототипа я начинаю с всего лишь 4 образцов «учеников» - A, B, C и D. Каждый студент дал свое мнение о других и чтобы все было просто, их мнение о себе все установлено на 0, (хотя это может так же легко быть любое значение, так как вы не можете нЕ работать с самим собой ..)

Вот мой psuedocode:

  1. Создать пустой набор «студентов», который будет содержать все студенты , т. е. [A, B, C, D]

  2. Создайте пустые набор «комбинаций», которые будут заполнены al л(), ((A, D) (B, C))]

  3. определить класс, содержащую информацию о предпочтениях для каждого студента, как только все возможные комбинации были определены, эта информация будет использоваться для расчета комбинации с общим высшим «Счастьем»/«Настроение» ..

  4. Создайте функцию, которая циклически проходит через все возможные комбинации, возвращая их в виде списков списков, которые добавляются к установленным комбинациям.

  5. (еще не добавлено) Создайте функцию, которая циклически перебирает все комбинации в наборе «комбинации» и вычисляет общее «счастье» на основе предпочтений, сохраненных в классе ученика.

  6. (еще не добавлено) Создайте функцию, которая печатает комбинации с наивысшим счастьем.

В этом случае он должен напечатать:

print"A,B/C,D = 7" 

print"A,C/B,D = 10" 

print"A,D/B,C = 15" 

print"Highest possible split is A,D/B,C with overall happiness of 15!" 

Я отчасти смущен, чтобы показать WIP .. но вот это:

http://www.codeskulptor.org/#user17_EEvOfHGg7AAZt1w_1.py

Или для тех, что лучше остановиться на этой странице:

people = set([]) 
combinations = set([]) 

class person: 
    def __init__(self, name, A = 3, B = 3, C = 3, D = 3): 
     self.name = name 
     self.A = A 
     self.B = B 
     self.C = C 
     self.D = D 

    def get_name(self): 
     return self.name 

    def get_A(self): 
     return self.A 

    def get_B(self): 
     return self.B 

    def get_C(self): 
     return self.C 

    def get_D(self): 
     return self.D  

# make all the possible combinations 
#def combine(people): 
#combine any 2 given people into a new group 

def combinations(iterable, r): 
    # combinations('ABCD', 2) --> AB AC AD BC BD CD 
    # combinations(range(4), 3) --> 012 013 023 123 
    pool = tuple(iterable) 
    n = len(pool) 
    if r > n: 
     return 
    indices = range(r) 
    yield tuple(pool[i] for i in indices) 
    while True: 
     for i in reversed(range(r)): 
      if indices[i] != i + n - r: 
       break 
     else: 
      return 
     indices[i] += 1 
     for j in range(i+1, r): 
      indices[j] = indices[j-1] + 1 
     yield tuple(pool[i] for i in indices) 

####[A,B,C,D] 
people.add(person("A", 0, 1, 2, 4)) 
people.add(person("B", 3, 0, 3, 4)) 
people.add(person("C", 1, 5, 0, 2)) 
people.add(person("D", 3, 3, 2, 0)) 

combinations(people,2) 

Функция комбинаций - я действительно поднял ее прямо с страницы документации itertools, но я не совсем уверен, работает она или даже если это лучший способ разделить группы. Я не могу импортировать itertools напрямую, поскольку CodeSkulptor поддерживает только несколько модулей (математика, случайность, время и т. Д.). Я попытался использовать реальный python, но он функционирует много иначе, чем я привык. Я многому научился в своих исследованиях, таких как вычисление чего-то вроде этого может занять годы для того, чтобы компьютер прошел через 24310 различных возможностей разделения. Другим вариантом было бы, чтобы код просто генерировал 100 случайных возможностей разделения на и я мог следить за самым высоким результатом каждого прохода. В общем, это был забавный сценарий, чтобы попытаться выяснить - на самом деле это слишком весело. Я не могу физически оторваться от него, хотя я и не сделал реального прогресса. Так что, пожалуйста, если кто-то может намекнуть/показать мне, куда идти отсюда, я очень благодарен за помощь.

Приветствия,

  • Эли
+0

, которую вы фактически разделив класс пополам (с группами 9), или вы раскалываете класс в группы из двух? – user2357112

+0

Половина (две группы из 9) Это было упомянуто во втором абзаце. и, no - ((A,), (B, C, D)) будет недействительным –

+0

Я предлагаю посмотреть встроенный модуль под названием itertools - очень полезный инструмент. Я думаю, вы можете найти [itertools.combinations] (http://docs.python.org/2/library/itertools.html#itertools.combinations), чтобы быть очень полезными – charmoniumQ

ответ

1

Завершено

from itertools import combinations 
import numpy as np 
import string 

    def get_maxhappiness(results): 
     max_happiness = max(results) 
     index = results.index(max_happiness) 

     #Printing the result! (There may be more than one best result, but this will only show 1) 
     print "Optimal Groups: Point value of",max_happiness,"\n",groups[index],"\n", anti_groups[index] 
     results[index] = 0 
     return results 

def calculateHappiness(points,group): 
    happiness = 0 
    for i in range(len(group)): 
     person_prefs = points[group[i]] 
     others = group[i:] + group[:i] 
     for other in others: 
      happiness += person_prefs[other] 
    return happiness 



if __name__ == "__main__": 
    people = string.letters[26:44] 
    groups = list(combinations(people,9)) 
    anti_groups = [tuple(set(people).difference(set(x))) for x in groups] 

    #Making fake results 
    survey_results = dict() 
    for person in people: 
     results = dict(zip(people,np.random.randint(0,10,size=(len(people))))) 
     results[person] = 0 
     survey_results[person] = results 

    #Printing Survey Results 
    for name,values in survey_results.items(): 
     print "Student:", name, "has preferences:", values 

    #Calculating happiness for every group 
    results = [] 
    for i in range(len(groups)): 
     results.append(calculateHappiness(survey_results,groups[i])+calculateHappiness(survey_results,anti_groups[i])) 
    #Finding the largest happiness value 
    top_n = 5 
    while top_n > 0: 
     results = get_maxhappiness(results) 
     top_n -= 1 

Урожайность:

... 

Student: N has preferences: {'A': 5, 'C': 5, 'B': 0, 'E': 0, 'D': 3, 'G': 6, 'F' 
: 8, 'I': 8, 'H': 3, 'K': 1, 'J': 4, 'M': 4, 'L': 9, 'O': 0, 'N': 0, 'Q': 3, 'P' 
: 2, 'R': 2} 
Student: Q has preferences: {'A': 9, 'C': 0, 'B': 3, 'E': 4, 'D': 3, 'G': 2, 'F' 
: 2, 'I': 7, 'H': 5, 'K': 2, 'J': 3, 'M': 0, 'L': 9, 'O': 2, 'N': 5, 'Q': 0, 'P' 
: 2, 'R': 0} 
Student: P has preferences: {'A': 2, 'C': 3, 'B': 0, 'E': 9, 'D': 3, 'G': 6, 'F' 
: 7, 'I': 1, 'H': 7, 'K': 9, 'J': 7, 'M': 4, 'L': 8, 'O': 2, 'N': 6, 'Q': 5, 'P' 
: 0, 'R': 7} 
Student: R has preferences: {'A': 5, 'C': 3, 'B': 7, 'E': 1, 'D': 5, 'G': 6, 'F' 
: 1, 'I': 6, 'H': 9, 'K': 9, 'J': 3, 'M': 6, 'L': 8, 'O': 8, 'N': 5, 'Q': 1, 'P' 
: 3, 'R': 0} 
Optimal Groups: Point value of 709 
('A', 'B', 'F', 'G', 'J', 'K', 'O', 'Q', 'R') 
('C', 'E', 'D', 'I', 'H', 'M', 'L', 'N', 'P') 
(x4) 
+0

Ницца, это очень эффективный старт. Я задавался вопросом, как использовать словари над определением класса. Хорошо знать, как это делают другие. так что это доводит меня до 4-го шага. Я попытаюсь пробиться сюда в «возможные комбинации» позже, когда у меня будет доступ к правильному питону (не кодекс) –

+0

Итак, я думаю, что код в моем сообщении теперь работает, но я бы приветствовал людей, чтобы проверить его на точность, потому что я этого не делал. – sihrc

+0

Ничего себе! Спасибо кучи: D Мне удалось запустить Python 2.7.5 и работать на моем рабочем компьютере без прав администратора, но, к сожалению, он не поставляется в комплекте с numpy. Просто работаем над тем, чтобы установить это сейчас. –

Смежные вопросы