-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoutput_scorer_helper.py
107 lines (89 loc) · 3.88 KB
/
output_scorer_helper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
import sys
import networkx as nx
import matplotlib.pyplot as plt
####################################################
# To run:
# python3 output_scorer.py <input_folder> <output_file>
#
# input_folder - the path to the input folder
# output_file - the path to the output file
#
# Examples:
# python3 output_scorer.py ./inputs/small/12 ./outputs/small/12.out
####################################################
def score_output(input_folder, output_file):
'''
Takes an input and an output and returns the score of the output on that input if valid
Inputs:
input_folder - a string representing the path to the input folder
output_file - a string representing the path to the output file
Outputs:
(score, msg)
score - a number between 0 and 1 which represents what fraction of friendships were broken
msg - a string which stores error messages in case the output file is not valid for the given input
'''
graph = nx.read_gml(input_folder + "/graph.gml")
parameters = open(input_folder + "/parameters.txt")
num_buses = int(parameters.readline())
size_bus = int(parameters.readline())
constraints = []
for line in parameters:
line = line[1: -2]
curr_constraint = [node.replace("'","") for node in line.split(", ")]
constraints.append(curr_constraint)
output = open(output_file)
assignments = []
for line in output:
line = line[1: -2]
curr_assignment = [node.replace("'","") for node in line.split(", ")]
assignments.append(curr_assignment)
if len(assignments) != num_buses:
return -1, "Must assign students to exactly {} buses, found {} buses".format(num_buses, len(assignments))
# make sure no bus is empty or above capacity
for i in range(len(assignments)):
if len(assignments[i]) > size_bus:
return -1, "Bus {} is above capacity".format(i)
if len(assignments[i]) <= 0:
return -1, "Bus {} is empty".format(i)
bus_assignments = {}
attendance_count = 0
# make sure each student is in exactly one bus
attendance = {student:False for student in graph.nodes()}
for i in range(len(assignments)):
if not all([student in graph for student in assignments[i]]):
return -1, "Bus {} references a non-existant student: {}".format(i, assignments[i])
for student in assignments[i]:
# if a student appears more than once
if attendance[student] == True:
print(assignments[i])
return -1, "{0} appears more than once in the bus assignments".format(student)
attendance[student] = True
bus_assignments[student] = i
# make sure each student is accounted for
if not all(attendance.values()):
return -1, "Not all students have been assigned a bus"
total_edges = graph.number_of_edges()
# Remove nodes for rowdy groups which were not broken up
num_rowdy = 0
rowdy_buses = []
for i in range(len(constraints)):
busses = set()
for student in constraints[i]:
busses.add(bus_assignments[student])
if len(busses) <= 1:
num_rowdy += 1
rowdy_buses.append(busses[0])
for student in constraints[i]:
if student in graph:
graph.remove_node(student)
# score output
score = 0
for edge in graph.edges():
if bus_assignments[edge[0]] == bus_assignments[edge[1]]:
score += 1
score = score / total_edges
return score, "Valid output submitted with score: {0}, with {1} rowdy groups in buses {2}".format(score, num_rowdy, rowdy_buses)
if __name__ == '__main__':
score, msg = score_output(sys.argv[1], sys.argv[2])
print(msg)