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): ...@@ -89,6 +89,16 @@ class Host(object):
else: else:
return {'status': 'error'} 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): def get_request_status(self, request_id):
if request_id in self.request: if request_id in self.request:
return self.request[request_id].get_status() return self.request[request_id].get_status()
...@@ -122,6 +132,9 @@ class Host(object): ...@@ -122,6 +132,9 @@ class Host(object):
elif cmd == 'problem/solution': elif cmd == 'problem/solution':
self.store_solution(params) self.store_solution(params)
return {'status': 'received'} return {'status': 'received'}
elif cmd == 'problem/save':
problem_key = params['problem']
return self.save_solution(problem_key)
elif cmd == 'request/status': elif cmd == 'request/status':
request_id = float(params['request_id']) request_id = float(params['request_id'])
return self.get_request_status(request_id) return self.get_request_status(request_id)
......
...@@ -60,16 +60,16 @@ body{ ...@@ -60,16 +60,16 @@ body{
display: inline-block; display: inline-block;
} }
#client-control-pane tr.solution-detail-row, #solution-list-container tr.solution-detail-row,
#client-control-pane tr.solution-detail-row td{ #solution-list-container tr.solution-detail-row td{
cursor: pointer; 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); 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); background-color: rgba(100, 200, 100, .3);
} }
......
...@@ -26,6 +26,10 @@ class StatusView { ...@@ -26,6 +26,10 @@ class StatusView {
_this.container.find('.start-button').click(()=>{ _this.container.find('.start-button').click(()=>{
_this.start_solver(); _this.start_solver();
}); });
_this.container.find('.save-button').click(()=>{
_this.save_solution();
});
_this.container.find('.solution-detail-row td').click((e) => { _this.container.find('.solution-detail-row td').click((e) => {
var solution_id = $(e.target).parent("tr").data("solution-id"); var solution_id = $(e.target).parent("tr").data("solution-id");
...@@ -83,6 +87,23 @@ class StatusView { ...@@ -83,6 +87,23 @@ class StatusView {
alert(d); 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){ get_request_status(request_id, timeout){
var _this = this; var _this = this;
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
</thead> </thead>
<tbody> <tbody>
{% for k, v in problem.get_solutions().items() %} {% for k, v in problem.get_solutions().items() %}
{#% if (qdata.best_json == k) and (v.answer != "") %#} {% if k == problem.best_solution %}
<!-- <tr class="answer-detail-row submit-answer" data-json="{#{k}#}" data-qname="{#{qname}#}"> --> <tr class="solution-detail-row submit-solution" data-solution-id="{{k}}" data-problem="{{problem.name}}">
{#% else %#} {% else %}
<tr class="solution-detail-row" data-solution-id="{{k}}" data-problem="{{problem.name}}"> <tr class="solution-detail-row" data-solution-id="{{k}}" data-problem="{{problem.name}}">
{#% endif %#} {% endif %}
<td>{{v.timestamp_str}}</td> <td>{{v.timestamp_str}}</td>
<td>{{v.worker}}</td> <td>{{v.worker}}</td>
<td> <td>
......
...@@ -18,6 +18,7 @@ class Problem(object): ...@@ -18,6 +18,7 @@ class Problem(object):
self.status = 'Ready' self.status = 'Ready'
self.solutions = dict() self.solutions = dict()
self.solution_path = solution_path self.solution_path = solution_path
self.best_solution = None
self._load_problem(problem_path) self._load_problem(problem_path)
...@@ -105,6 +106,33 @@ class Problem(object): ...@@ -105,6 +106,33 @@ class Problem(object):
# Save solution # Save solution
solution.save(self.solution_path) 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): def get_solutions(self):
return self.solutions return self.solutions
...@@ -124,26 +152,21 @@ class Solution(object): ...@@ -124,26 +152,21 @@ class Solution(object):
self.worker = data['worker'] self.worker = data['worker']
self.elapsed_time = data['elapsed_time'] self.elapsed_time = data['elapsed_time']
self.solution = data['solution'] self.solution = data['solution']
self.status = data['status']
self.size = (None, None)
self.map = None
self.block = dict()
self.timestamp = time.time() self.timestamp = time.time()
self._id = str(uuid.uuid4()) self._id = str(uuid.uuid4())
def get_id(self): self._parse_solution()
return self._id
def _parse_solution(self):
def get_dict(self):
return { if self.status != 'done':
'id': self._id, return
'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):
board_size = [0, 0] board_size = [0, 0]
block_num = 0 block_num = 0
...@@ -155,9 +178,11 @@ class Solution(object): ...@@ -155,9 +178,11 @@ class Solution(object):
bmap = list() bmap = list()
bposition = dict() bposition = dict()
state = 0
while li < len(_lines): while li < len(_lines):
_l = _lines[li].strip() _l = _lines[li].strip()
if 'SIZE' in _l: if (state == 0) and ('SIZE' in _l):
board_size_str = _l.strip().split()[1] board_size_str = _l.strip().split()[1]
board_solution_size = [int(v) for v in board_size_str.split('X')] board_solution_size = [int(v) for v in board_size_str.split('X')]
bw = board_solution_size[0] bw = board_solution_size[0]
...@@ -166,7 +191,8 @@ class Solution(object): ...@@ -166,7 +191,8 @@ class Solution(object):
li += 1 li += 1
_l = _lines[li].strip() _l = _lines[li].strip()
bmap.append([int(v.strip()) for v in _l.split(',')]) 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]+)\)' p = r'BLOCK#([0-9]+) +@\(([0-9]+), *([0-9]+)\)'
m = re.match(p, _l.strip()) m = re.match(p, _l.strip())
bi = int(m.group(1)) bi = int(m.group(1))
...@@ -177,16 +203,55 @@ class Solution(object): ...@@ -177,16 +203,55 @@ class Solution(object):
'x': bx, 'x': bx,
'y': by, 'y': by,
} }
state = 2
li += 1 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 { return {
'w': bw, 'id': self._id,
'h': bh, 'timestamp': self.timestamp,
'map': bmap, 'request_id': self.request_id,
'block': bposition '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): def save(self, basedir):
outdir = f"{basedir}/{self.problem}" outdir = f"{basedir}/{self.problem}"
if not os.path.exists(outdir): 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