Commit e7a02e9a authored by Kento HASEGAWA's avatar Kento HASEGAWA

Add support for saving the best solution

parent 105e3566
......@@ -89,6 +89,16 @@ class Host(object):
else:
return {'status': 'error'}
def save_solution(self, problem_key):
problem = self.get_problem(problem_key)
if problem is not None:
problem.save_best_solution()
return {'status': 'saved'}
else:
return {'status': 'failed'}
def get_request_status(self, request_id):
if request_id in self.request:
return self.request[request_id].get_status()
......@@ -122,6 +132,9 @@ class Host(object):
elif cmd == 'problem/solution':
self.store_solution(params)
return {'status': 'received'}
elif cmd == 'problem/save':
problem_key = params['problem']
return self.save_solution(problem_key)
elif cmd == 'request/status':
request_id = float(params['request_id'])
return self.get_request_status(request_id)
......
......@@ -60,16 +60,16 @@ body{
display: inline-block;
}
#client-control-pane tr.solution-detail-row,
#client-control-pane tr.solution-detail-row td{
#solution-list-container tr.solution-detail-row,
#solution-list-container tr.solution-detail-row td{
cursor: pointer;
}
#client-control-pane tr.solution-detail-row:hover{
#solution-list-container tr.solution-detail-row:hover{
background-color: rgba(200, 100, 100, .15);
}
#client-control-pane tr.solution-detail-row.submit-answer{
#solution-list-container tr.solution-detail-row.submit-solution{
background-color: rgba(100, 200, 100, .3);
}
......
......@@ -26,6 +26,10 @@ class StatusView {
_this.container.find('.start-button').click(()=>{
_this.start_solver();
});
_this.container.find('.save-button').click(()=>{
_this.save_solution();
});
_this.container.find('.solution-detail-row td').click((e) => {
var solution_id = $(e.target).parent("tr").data("solution-id");
......@@ -83,6 +87,23 @@ class StatusView {
alert(d);
});
}
// 保存
save_solution(){
var _this = this;
$.ajax({
type: "POST",
dataType: "json",
url: "/api/problem/save",
data: JSON.stringify({
"problem": _this.problem_key
}),
contentType: 'application/json'
}).done((d) => {
_this.show_problem();
});
}
get_request_status(request_id, timeout){
var _this = this;
......
......@@ -22,11 +22,11 @@
</thead>
<tbody>
{% for k, v in problem.get_solutions().items() %}
{#% if (qdata.best_json == k) and (v.answer != "") %#}
<!-- <tr class="answer-detail-row submit-answer" data-json="{#{k}#}" data-qname="{#{qname}#}"> -->
{#% else %#}
{% if k == problem.best_solution %}
<tr class="solution-detail-row submit-solution" data-solution-id="{{k}}" data-problem="{{problem.name}}">
{% else %}
<tr class="solution-detail-row" data-solution-id="{{k}}" data-problem="{{problem.name}}">
{#% endif %#}
{% endif %}
<td>{{v.timestamp_str}}</td>
<td>{{v.worker}}</td>
<td>
......
......@@ -18,6 +18,7 @@ class Problem(object):
self.status = 'Ready'
self.solutions = dict()
self.solution_path = solution_path
self.best_solution = None
self._load_problem(problem_path)
......@@ -105,6 +106,33 @@ class Problem(object):
# Save solution
solution.save(self.solution_path)
def save_best_solution(self):
best_score = None
for k, v in self.solutions.items():
if v.is_valid_solution():
_score = v.score
if (best_score is None) or (_score < best_score[1]):
best_score = (k, _score)
if best_score is not None:
solution_name = self.name
outpath = f'{self.solution_path}/submit'
if not os.path.exists(outpath):
os.mkdir(outpath)
best_solution_key = best_score[0]
with open(f'{outpath}/{solution_name}.txt', 'w') as fp:
fp.write(self.solutions[best_solution_key].solution)
with open(f'{outpath}/{solution_name}.json', 'w') as fp:
json.dump(self.solutions[best_solution_key].get_dict(), fp, indent=4)
self.best_solution = best_solution_key
def get_solutions(self):
return self.solutions
......@@ -124,26 +152,21 @@ class Solution(object):
self.worker = data['worker']
self.elapsed_time = data['elapsed_time']
self.solution = data['solution']
self.status = data['status']
self.size = (None, None)
self.map = None
self.block = dict()
self.timestamp = time.time()
self._id = str(uuid.uuid4())
def get_id(self):
return self._id
def get_dict(self):
return {
'id': self._id,
'timestamp': self.timestamp,
'request_id': self.request_id,
'worker': self.worker,
'elapsed_time': self.elapsed_time,
'problem': self.problem,
'solution': self.solution
}
def get_d3json(self):
self._parse_solution()
def _parse_solution(self):
if self.status != 'done':
return
board_size = [0, 0]
block_num = 0
......@@ -155,9 +178,11 @@ class Solution(object):
bmap = list()
bposition = dict()
state = 0
while li < len(_lines):
_l = _lines[li].strip()
if 'SIZE' in _l:
if (state == 0) and ('SIZE' in _l):
board_size_str = _l.strip().split()[1]
board_solution_size = [int(v) for v in board_size_str.split('X')]
bw = board_solution_size[0]
......@@ -166,7 +191,8 @@ class Solution(object):
li += 1
_l = _lines[li].strip()
bmap.append([int(v.strip()) for v in _l.split(',')])
if 'BLOCK' in _l:
state = 1
if (state == 1) and ('BLOCK' in _l):
p = r'BLOCK#([0-9]+) +@\(([0-9]+), *([0-9]+)\)'
m = re.match(p, _l.strip())
bi = int(m.group(1))
......@@ -177,16 +203,55 @@ class Solution(object):
'x': bx,
'y': by,
}
state = 2
li += 1
self.size = (bw, bh)
self.map = bmap
self.block = bposition
@property
def score(self):
if (len(self.size) == 2) and (self.size[0] is not None) and (self.size[1] is not None):
return self.size[0] * self.size[1]
else:
return None
def is_valid_solution(self):
return self.status == 'done'
def get_id(self):
return self._id
def get_dict(self):
return {
'w': bw,
'h': bh,
'map': bmap,
'block': bposition
'id': self._id,
'timestamp': self.timestamp,
'request_id': self.request_id,
'worker': self.worker,
'elapsed_time': self.elapsed_time,
'problem': self.problem,
'solution': self.solution
}
def get_d3json(self):
if self.state == 'done':
return {
'w': self.size[0],
'h': self.size[1],
'map': self.map,
'block': self.block
}
else:
return {
'w': 0,
'h': 0,
'map': [[]],
'block': dict()
}
def save(self, basedir):
outdir = f"{basedir}/{self.problem}"
if not os.path.exists(outdir):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment