Commit 20ce9b07 authored by  tawada's avatar tawada

Update

parent 54847e96
......@@ -52,6 +52,8 @@ class MAP:
self.line[index][1][0] = x
self.line[index][1][1] = y
self.line[index][1][2] = z
self.line = self.line.astype(np.int8)
self.map = self.map.astype(np.int8)
def countV(self, value, point_list):
"""座標リストpoint_list内の座標(x,y,z)のself.mapの値(ラインのインデックス)がvalueと等しいものの個数を数えます"""
......@@ -61,6 +63,18 @@ class MAP:
c += 1
return c
def count_parallel(self, value, point):
"""Z平面上で隣接する配線数 (0~4)を返す"""
c = 0
dlist = np.array([[0,-1,0], [0,1,0], [-1,0,0], [1,0,0]])
points = point + dlist
points = self.isregular(points)
for p in points:
if self.map[tuple(p)] != 0 and self.map[tuple(p)] != value:
c += 1
return c
def delLine(self, index):
"""self.map上のラインindexを消す. 端点は消さない"""
for x,y,z in itertools.product(\
......@@ -138,15 +152,18 @@ class MAP:
f.write(self.strQ())
f.close()
def saveA(self):
def saveA(self, output=None):
"""解答をファイルとして保存する"""
filename="A-"+self.name+".txt"
if output==None:
filename="A-"+self.name+".txt"
else:
filename=output
f=open(filename, 'w')
f.write(self.strA())
f.close()
def isregular(self, points):
"""self.mapの範囲内の座標だけを返す"""
"""self.mapの範囲内のもののみ返す"""
a=np.all(points>=0,axis=1)
b=points[:,0]<self.X#0-col vector
c=points[:,1]<self.Y#1-col vector
......@@ -155,6 +172,17 @@ class MAP:
e=a*b*c*d
return points[e]
def isregular_bool(self, points):
"""self.mapの範囲内をbool行列 (範囲内ならTrue, 範囲外ならFalse) で返す"""
a=np.all(points>=0,axis=1)
b=points[:,0]<self.X#0-col vector
c=points[:,1]<self.Y#1-col vector
d=points[:,2]<self.Z#2-col vector
e=a*b*c*d
return e
def isblank(self, points):
"""座標リストのうちラインで埋まっている座標をTrue, ラインで埋まっている座標をFalseとして返す"""
l=np.array([],dtype=bool)
......@@ -215,51 +243,104 @@ class MAP:
self.line=np.append(self.line, [[start[0], end]], axis=0)
return True
def cost_neighbour(self, value, point):
points = self.neighbour(point)
points = self.isregular(points)
cost = 0
for p in points:
if value != self.map[tuple(p.astype(np.int8))] and value != 0:
cost += 1
return cost
def optLine(self, n_line):
MAX=72*72*8
MAX_COST = 9999999
dlist=np.array([[0,0,-1], [0,0,1], [0,-1,0], [0,1,0], [-1,0,0], [1,0,0]])
self.map[self.map==n_line]=0
q=[]
#コスト, 座標, ラインが引かれた方向
heapq.heappush(q, (0, self.line[i][0], [0,0,0]))
heapq.heappush(q, (0, list(self.line[n_line-1][0]), [0,0,0]))
cost_map = np.zeros((72,72,8,3,3,3)).astype(np.int32)
for i in itertools.product(range(72),range(72),range(8),range(3),range(3),range(3)):
cost_map[i] = MAX_COST
for d in dlist:
t = tuple(np.append(self.line[n_line-1][0], d).astype(np.int32))
cost_map[t] = 0
while True:
if q == []:
break
(priority, point, direction) = heapq.heappop(q)
if point == self.line[i][1]:
if list(point) == list(self.line[n_line-1][1]):
break
next_points=point+dlist
boollist=isregular(next_points)
boollist=self.isregular_bool(next_points)
for n, d in zip(next_points[boollist],dlist[boollist]):
if self.map[tuple(n)]!=0:continue
if len(isregular(next_point))==0:continue
#n 周辺の座標, d 方向 (移動前からの差分)
if self.map[tuple(n)]!=0:
continue
t = tuple(np.append(n, d))
cost_old = cost_map[t]
cost_n = self.count_parallel(n_line, n)
if np.array_equal(direction, d):
heapq.heappush((priority+1))
cost_new = priority + 1 + cost_n/3
else:
cost_new = priority + 2 + cost_n/3
if cost_new < cost_old:
t = tuple(np.append(n, d).astype(np.int8))
cost_map[t] = cost_new
heapq.heappush(q, (cost_new, list(n), list(d)))
#ここからバックトラック
index_min = [0,0,0]
cost_min = MAX_COST
for d in dlist:
t = tuple(np.append(self.line[n_line-1][1], d).astype(np.int8))
if cost_min > cost_map[t]:
cost_min = cost_map[t]
index_min = d
focus_p = self.line[n_line-1][1]
focus_d = index_min
while True:
self.map[tuple(focus_p)]=n_line
next_p = focus_p - focus_d
direction_min = focus_d
cost_min = cost_map[tuple(np.append(next_p, focus_d).astype(np.int8))]
for d in dlist:
t = tuple(np.append(next_p, d).astype(np.int8))
if cost_min > cost_map[t]:
cost_min = cost_map[t]
direction_min = d
focus_p = next_p
focus_d = direction_min
if (focus_p == self.line[n_line-1][0]).all():
break
self.map[tuple(focus_p)]=n_line
def generate(self, linenum, maxlength):
self.name="".join([self.name,"_%d_%d" % (linenum, maxlength)])
for i in range(linenum):
self.addLine(maxlength)
#for i in range(self.n_line):
# self.optLine(i)
def optimize(self):
#ライン数の10倍の回数だけ「線の引き剥がし・再配線」を繰り返す.
iteration = len(self.line)*10
for i in range(iteration):
m.optLine(np.random.randint(len(self.line))+1)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='NLGenerator')
parser.add_argument('--input', '-i', default=None, type=str,
help='Input file')
parser.add_argument('--output', '-o', default=None, type=str,
help='Output file')
args = parser.parse_args()
m=MAP(args.input)
m.delLine(10-1)
m.print()
#m.save()
#m.saveQ()
#m.saveA()
#m.show()
m.printA()
m.optimize()
m.printA()
m.saveA(args.output)
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