Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rr.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ def __init__(self, process_input_list, cpu_count, quantum):
super().__init__(process_input_list, cpu_count)
self.quantum = quantum



def run(self):
cur_time = 0
finish_processes_count = 0
Expand Down
26 changes: 13 additions & 13 deletions show.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ def init_ui(self):

# Proc_List에 프로세스 목록을 추가 및 화면 내용을 리셋하는 버튼
self.add_button = QPushButton("Add", self)
self.add_button.clicked.connect(self.add)
# self.add_button.clicked.connect(self.add)
# 수정 : 디버깅용 test를 add 버튼에 일시적으로 연결 (test 누르면 자동으로 값 입력됨)
# self.add_button.clicked.connect(self.test)
self.add_button.clicked.connect(self.test)

reset_button = QPushButton("Reset", self)
reset_button.clicked.connect(self.reset)
Expand Down Expand Up @@ -256,17 +256,17 @@ def test(self):
Process("p9", 1, 4, 9),
]
# ----------------------------
self.proc_list = [
Subject("알고리즘", 4, 8, 0, 0),
Subject("웹프", 3, 7, 1, 0),
Subject("직능훈", 2, 4, 2, 0),
# Subject("알고리즘", 4, 5, 3, 1),
Subject("C++", 4, 4, 4, 1),
# Subject("웹프", 3, 3, 5, 1),
# Subject("알고리즘", 4, 4, 6, 2),
# Subject("데베설", 3, 5, 7, 2),
# Subject("운영체제", 2, 6, 8, 2),
]
# self.proc_list = [
# Subject("알고리즘", 4, 8, 0, 0),
# Subject("웹프", 3, 7, 1, 0),
# Subject("직능훈", 2, 4, 2, 0),
# # Subject("알고리즘", 4, 5, 3, 1),
# Subject("C++", 4, 4, 4, 1),
# # Subject("웹프", 3, 3, 5, 1),
# # Subject("알고리즘", 4, 4, 6, 2),
# # Subject("데베설", 3, 5, 7, 2),
# # Subject("운영체제", 2, 6, 8, 2),
# ]

# -------------------------------
print("[self.proc_list]")
Expand Down
1 change: 0 additions & 1 deletion srtn.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ def run(self):
cpu_list = []
for cpu in self.cpus:
cpu_list.append(cpu)

cpu_list.sort(key=lambda x: x.process.remain_bt) # 오름차순으로 정렬 (+한번만해도 괜찮을듯)

max_idx = min(self.cpu_count, len(self.ready_queue)) # 인덱스 에러 안 뜨게
Expand Down
77 changes: 66 additions & 11 deletions student.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,41 @@ class Student(CPU):
def __init__(self, student_name): # student_name는 학생 이름, class_list는 학생이 듣는 수업
super().__init__(student_name)
self.subject_list = []
# [DEBUG] 이게 평균학점 0점으로 초기화해서 최대 0점일 때 체크가 잘 안되었음
# 0~ 24 시간에서 각 시간에따른 --------------------
# 이 학생의 최고 평균 학점
self.best_solo_avg_grades = [-1 for _ in range(25)]
# 이 학생의 최고의 각 과목별 공부 투자 시간
self.best_solo_subject_study_cases = defaultdict(list)
# 이 학생의 최고의 각 과목별 학점
self.best_solo_subjects_grades = defaultdict(list)
# -------------------------------------------------

# 최종적으로 제일 좋은 -------------------------------------
self.best_solo_total_study_time = 0 # 개인 공부 투자 시간
self.best_solo_subject_study_case = [] # 각 과목 공부 투자시간 순서대로
self.best_solo_subjects_grade = [] # 각 과목 학점 순서대로
self.best_solo_subject_study_case = [] # 각 과목 공부별 투자시간 순서대로
self.best_solo_subjects_grade = [] # 각 과목별 학점 순서대로
self.best_each_team_play_time = 0 # 개인의 팀플 투자시간
self.best_team_play_grade = 0 # 팀플 학점
self.best_avg_grade = 0 # 최종적인 개인 학점(개인 공부 학점과 팀플 학점의 평균)

# ------------------------------------------------------------
self.total_credits = 3 # 총 학점 21 학점같은 - 기본 운영체제 팀플 3학점을 듣기 때문에

def add_subject_list(self, subject):
"""
학생에게 과목을 추가하면서, 총학점도 같이 구함
"""
self.subject_list.append(subject)
self.total_credits += subject.credit

# max_solo_study_time 이걸로 best 시간 구하고 이걸로 구해도 똑같은 값이 나올거 같은데?
def calculate_best_case(self, best_team_play_case, max_team_play_time):
"""
최종적으로 구한 best_team_play_case와 처음에 설정해준 목표 팀플 실행 시간을 통해서
학생의 최종적인 각 과목의 실제 공부 시간, 총 공부 시간,각 과목들의 학점,
이 학생이 투자한 팀플 시간, 이 팀의 팀플 학점
이 학생의 최종 평균 학점을
계산하여 설정한다.
"""
best_each_team_play_time = best_team_play_case[0][self.id]
total_team_play_time = sum(best_team_play_case[0])
max_solo_study_time = 24 - best_each_team_play_time
Expand All @@ -47,26 +62,52 @@ def calculate_best_case(self, best_team_play_case, max_team_play_time):
print("self.best_avg_grade", self.best_avg_grade)

def get_team_play_grade(self, total_team_play_time, max_team_play_time):
"""
팀플 학점을 구한다(팀 전체가 투자한 총 팀플시간과 목표 팀플시간을 통해서)
"""
team_play_score = 100 * (total_team_play_time / max_team_play_time)
team_play_grade = self.convert_score_to_grade(team_play_score)
return team_play_grade

def get_final_student_grade(self, each_solo_study_time, total_team_play_time, max_team_play_time):
"""
개인 공부시간에 따른 학점, 팀플에서 받은 학점의 평균을 통해 개인 최종 평균 학점을 구한다.
개인 공부 학점 - 개인 공부시간(each_solo_study_time)에 따라서 구함
팀플 학점 - 팀 전체가 투자한 팀플레이 시간, 목표 팀플레이시간을 통해 구함
"""
team_play_grade = self.get_team_play_grade(total_team_play_time, max_team_play_time) * 3 # 운영체제는 3학점임
solo_study_grade = self.best_solo_avg_grades[each_solo_study_time] * (self.total_credits - 3)
return (team_play_grade + solo_study_grade) / self.total_credits

def set_best_solo_cases(self):
"""
공부시간에 따른
이 학생의 최고 평균 학점
이 학생의 최고의 각 과목별 공부 투자 시간
이 학생의 최고의 각 과목별 학점
을 구하는 함수이다.
"""
all_study_cases = self.get_all_study_cases()
if len(all_study_cases) > 1:
if len(all_study_cases) > 1: # 과목을 아무것도 할당받지 못하면 all_study_cases =
for study_time in range(25):
# 모든 과목 공부시간(BT)을 다 합쳐도 시간이 남아서 현재 study_time에 대한 경우가 없을 때
# ex) 알고리즘 7시간, 컴구조 4시간 일때 최대 공부시간은 11시간이다.
# 12, 13 ...시간인 경우는 존재하지 않는다.
# 이때 개인 평균 학점을 4.5로 설정해주고
# 각 과목의 공부 투자시간을 목표 시간과 똑같이 설정해준다.(다 공부할 수 있으므로)
# 그리고 각 과목별 학점 4.5이다.
if study_time not in all_study_cases:
# print("all_study_cases =", study_time)
self.best_solo_avg_grades[study_time] = 4.5
self.best_solo_subject_study_cases[study_time] = [subject.bt for subject in self.subject_list]
self.best_solo_subjects_grades[study_time] = [4.5 for subject in self.subject_list]
continue
# 각 공부시간에 따른 과목별 투자 시간의 경우의 수를 돌면서
# ex) 알고리즘 7시간, 컴구조 4시간 일때
# study_case는 (0, 0), (3,2), (7,4) 등이 되는데
# 이때의 각 과목별 투자시간에 따른 점수와 학점 및 평균 학점을 구한다.
# 경우의 수를 돌면서 구한 평균학점이 높으면 갱신해주어서
# 제일 높은 평균 학점을 받았을 때의 평균 학점, 과목별 투자시간, 과목별 학점을 저장한다.
for study_case in all_study_cases[study_time]:
grade_list = []
total_grade_sum = 0
Expand All @@ -76,13 +117,15 @@ def set_best_solo_cases(self):
grade_list.append(grade)
total_grade_sum += grade * self.subject_list[subject_idx].credit
avg_grade = total_grade_sum / (self.total_credits - 3)
if self.best_solo_avg_grades[study_time] <= avg_grade:
if self.best_solo_avg_grades[study_time] < avg_grade:
self.best_solo_avg_grades[study_time] = avg_grade
self.best_solo_subject_study_cases[study_time] = study_case[:]
self.best_solo_subjects_grades[study_time] = grade_list[:]
if self.best_solo_avg_grades[study_time] < avg_grade:
self.best_solo_avg_grades[study_time] = avg_grade
self.best_solo_subject_study_cases[study_time] = study_case[:]
self.best_solo_subjects_grades[study_time] = grade_list[:]

def get_all_study_cases(self):
"""
중복 순열을 통해서 0 ~ 24시간까지의 모든 과목별 공부 투자 경우의 수를 구함
"""
all_study_cases = defaultdict(list)

for study_subject_time_case in product(*[range(subject.bt + 1) for subject in self.subject_list]):
Expand All @@ -92,12 +135,24 @@ def get_all_study_cases(self):
return all_study_cases

def make_student_real_subject_list(self):
"""
학생에게 주어진 과목의 실제 공부 시간을 계산하는 함수

:desc
학생 A - 알고리즘 7시간, 컴구조 4시간
self.best_solo_subject_study_case는 학생이 best 학점을 받기 위해 주어진 과목을 공부하는 시간의 경우이다.
ex) [7, 4] or [0, 2](시간이 부족해서 컴구조 2시간 공부가 최선인 경우) 등
여기서 [0, 2] 인 경우는 주어진 과목 공부 7, 4시간이지만 실제 공부시간은 0,2시간이다.
실제 공부시간으로 스케줄링을 돌리기 위해서 주어진 과목들을 각각 복사하며
주어진 공부시간(bt, remain_bt)를 실제 최적 공부시간(best_subject_study_time)으로 변환해서
real_subject_list로 만들어준다.
"""
real_subject_list = []
for idx, best_subject_study_time in enumerate(self.best_solo_subject_study_case):
if best_subject_study_time > 0:
real_subject = copy.deepcopy(self.subject_list[idx])
real_subject.bt = best_subject_study_time
real_subject.remain_bt = real_subject.bt
real_subject.remain_bt = best_subject_study_time
real_subject_list.append(real_subject)
if self.best_each_team_play_time > 0:
real_subject_list.append(
Expand Down
103 changes: 68 additions & 35 deletions yosa.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,60 @@ def __init__(self, subject_input_list, student_count, max_team_play_time):
self.each_student_history_list = []
self.allocate_subject_to_student()

def create_students(self):
return [Student(idx) for idx in range(self.student_count)]

def allocate_subject_to_student(self):
# 과목 리스트를 돌면서
for subject in self.subjects:
# 그 과목을 할당받은 학생을 찾으면 할당해줌
for student in self.students:
if subject.student_id == student.id:
student.add_subject_list(subject)
break

def run(self):
"""
best_team_play_case_list의 한 case에는
[0] 최적의 팀플 공부시간 ex)[7,4] (0번 학생 7시간, 1번 학생 4시간)
[1] 이때의 각 학생의 학점 ex) [4.0, 3.5]
[2] 이때의 팀 최종 평균
"""
best_team_play_case = self.find_best_team_play_case()
self.team_avg_grade = best_team_play_case[2]
print("team_avg = ", self.team_avg_grade)
for student in self.students:
# 1.학생의 best인 경우 정보를 설정해줌
student.calculate_best_case(best_team_play_case, self.max_team_play_time)
# 현재 나온 학생들을 기준으로 각각 1개짜리로 돌려서
# history를 모은 each_student_history_list를 만들어서 돌린다.
# 2. 학생의 실제 공부 시간 계산
student_real_subject_list = student.make_student_real_subject_list()
# 3. 이 정보를 가지고 스케줄링을 돌림
if random.choice([True, False]):
scheduler = SPN(student_real_subject_list, 1)
else:
scheduler = RR(student_real_subject_list, 1, random.randrange(1, 4))
scheduler.run()
# 학생이 4명이면 4개의 히스토리를 저장함
self.each_student_history_list.append(scheduler.history)

def find_best_team_play_case(self):
"""
1. 각 학생들의 각 개인 공부시간에 따른
best_case(평균 학점, 과목별 투자시간, 과목별 학점)를 구해서 각 학생들에게 저장해놓는다.
2. 각 학생들의 모든 팀플 투자 하는 경우의 수를 구한다.
3. 팀플 투자 경우의 수에 따른
각 학생의 팀플 투자시간과 따른 개인공부시간(24 - each_team_play_time)을 통해서
최종 학점을 구한다.
4. 각 학생의 최종 학점을 통해 팀 전체의 평균 학점을 구한다.
5. 기존에 구한 최고 평균학점과 비교하며 팀 전체의 평균 학점이 제일 높은 경우들을 찾는다
6. 팀 전체의 평균 학점이 제일 높은 경우중에
팀원들의 팀플 투자시간이 합이 제일 적고 표준편차가 제일 작은 경우를 구해서
최종적으로 반환해준다.
"""
# @<1> 각 학생들의 각 개인 공부시간에 따른
# best_case(평균 학점, 과목별 투자시간, 과목별 학점)를 구한다.
for student in self.students:
student.set_best_solo_cases()
# print(student.best_solo_avg_grades)
Expand All @@ -28,65 +81,45 @@ def find_best_team_play_case(self):
# final_grade = []
# team_play_time_case = ex) [0,0,0,0] or [0,4,5,7] or [24,24,24,24]
# [1, 7, 2, 4] 팀플에 학생1은 1시간, 학생2는 7시간, 학생3는 2시간, 학생4는 4시간 투자
# @<2>각 학생들의 모든 팀플 투자 하는 경우의 수를 구한다.
for team_play_time_case in product(*[range(25) for each_student_case in range(self.student_count)]):
# 목표 팀플시간이 20시간인데 40시간을 투자할 수는 없다.
if sum(team_play_time_case) <= self.max_team_play_time:
final_student_grade_list = []
final_average_team_grade = 0

# @<3>각 학생의 팀플 투자시간과 따른 개인공부시간(24 - each_team_play_time)을 통해서
# 최종 학점을 구한다.
for student_idx, each_team_play_time in enumerate(team_play_time_case):
final_student_grade_list.append(
self.students[student_idx].get_final_student_grade(
24 - each_team_play_time, sum(team_play_time_case), self.max_team_play_time
)
)
# final_grade.append(final_student_grade_list)
# @<4> 각 학생의 최종 학점을 통해 팀 전체의 평균 학점을 구한다.
final_average_team_grade = sum(final_student_grade_list) / len(final_student_grade_list)
# 이거 원래 > 이렇게 되어야 함
# @<5>팀 전체의 평균 학점이 제일 높은 경우들을 찾는다
if final_average_team_grade >= best_average_team_grade:
if final_average_team_grade > best_average_team_grade:
best_average_team_grade = final_average_team_grade
best_team_play_case_list = []
"""
best_team_play_case_list의 한 case에는
[0] 최적의 팀플 공부시간 ex)[7,4] (0번 학생 7시간, 1번 학생 4시간)
[1] 이때의 각 학생의 학점 ex) [4.0, 3.5]
[2] 이때의 팀 최종 평균
"""
best_team_play_case_list.append(
(team_play_time_case[:], final_student_grade_list[:], final_average_team_grade)
)
# print("final_grade by 1", sorted(final_grade, key=lambda x: x[0], reverse=True)[:20])
# print("final_grade by 2", sorted(final_grade, key=lambda x: x[1], reverse=True)[:20])
# print("best_average_team_grade", best_average_team_grade)
# print("best_team_play_case_grade_list", best_team_play_case_grade_list)
print("==========================================================================")
print("MAX_TEAM_PLAY_TIME", self.max_team_play_time)
print("best_team_play_case_list", best_team_play_case_list)
# best는 합이 제일 적고 표준편차가 제일 작은 경우
# @ <6>팀 전체의 평균 학점이 제일 높은 경우중에
# 팀원들의 팀플 투자시간이 합이 제일 적고 표준편차가 제일 작은 경우를 구해서
# 최종적으로 반환해준다.
best_team_play_case = sorted(best_team_play_case_list, key=lambda x: (sum(x[0]), std(x[0])))[0]
print("best_team_play_case", best_team_play_case)

return best_team_play_case

def create_students(self):
return [Student(idx) for idx in range(self.student_count)]

# best_team_play_case 의 학생들의 평균 학점하고, 팀 전체 평균 학점이 같은지 확인
def run(self):
best_team_play_case = self.find_best_team_play_case()
self.team_avg_grade = best_team_play_case[2]
print("team_avg = ", self.team_avg_grade)
for student in self.students:
student.calculate_best_case(best_team_play_case, self.max_team_play_time)
# 현재 나온 학생들을 기준으로 각각 1개짜리로 돌려서
# history를 모은 each_student_history_list를 만들어서 돌린다.
student_real_subject_list = student.make_student_real_subject_list()
if random.choice([True, False]):
scheduler = SPN(student_real_subject_list, 1)
else:
scheduler = RR(student_real_subject_list, 1, random.randrange(1, 4))
scheduler.run()
self.each_student_history_list.append(scheduler.history)

def allocate_subject_to_student(self):
# 과목 리스트를 돌면서
for subject in self.subjects:
# 그 과목을 할당받은 학생을 찾으면 할당해줌
for student in self.students:
if subject.student_id == student.id:
student.add_subject_list(subject)
break