関数meshgrid上の2点間の正確 'N'ノードとの最短経路:計算Iは、グリッド上で次の3次元表面を定義した
%pylab inline
def muller_potential(x, y, use_numpy=False):
"""Muller potential
Parameters
----------
x : {float, np.ndarray, or theano symbolic variable}
X coordinate. If you supply an array, x and y need to be the same shape,
and the potential will be calculated at each (x,y pair)
y : {float, np.ndarray, or theano symbolic variable}
Y coordinate. If you supply an array, x and y need to be the same shape,
and the potential will be calculated at each (x,y pair)
Returns
-------
potential : {float, np.ndarray, or theano symbolic variable}
Potential energy. Will be the same shape as the inputs, x and y.
Reference
---------
Code adapted from https://cims.nyu.edu/~eve2/ztsMueller.m
"""
aa = [-1, -1, -6.5, 0.7]
bb = [0, 0, 11, 0.6]
cc = [-10, -10, -6.5, 0.7]
AA = [-200, -100, -170, 15]
XX = [1, 0, -0.5, -1]
YY = [0, 0.5, 1.5, 1]
# use symbolic algebra if you supply symbolic quantities
exp = np.exp
value = 0
for j in range(0, 4):
if use_numpy:
value += AA[j] * numpy.exp(aa[j] * (x - XX[j])**2 + bb[j] * (x - XX[j]) * (y - YY[j]) + cc[j] * (y - YY[j])**2)
else: # use sympy
value += AA[j] * sympy.exp(aa[j] * (x - XX[j])**2 + bb[j] * (x - XX[j]) * (y - YY[j]) + cc[j] * (y - YY[j])**2)
return value
次のプロットが得られた:
minx=-1.5
maxx=1.2
miny=-0.2
maxy=2
ax=None
grid_width = max(maxx-minx, maxy-miny)/50.0
xx, yy = np.mgrid[minx : maxx : grid_width, miny : maxy : grid_width]
V = muller_potential(xx, yy, use_numpy=True)
V = ma.masked_array(V, V>200)
contourf(V, 40)
colorbar();
グリッド上の2点間の最短経路を定義するために、次のコードを記述しました。メッシュグリッドの2つの隣接ポイント間で使用したメトリックは、(V[e]-V[cc])**2
で与えられ、cc
の現在のセルとe
の隣接セルの1つです。ネイバーは、完全な接続性で定義されます。対角を含むすべての直接ネイバーです。次の結果与えた
def dijkstra(V):
mask = V.mask
visit_mask = mask.copy() # mask visited cells
m = numpy.ones_like(V) * numpy.inf
connectivity = [(i,j) for i in [-1, 0, 1] for j in [-1, 0, 1] if (not (i == j == 0))]
cc = unravel_index(V.argmin(), m.shape) # current_cell
m[cc] = 0
P = {} # dictionary of predecessors
#while (~visit_mask).sum() > 0:
for _ in range(V.size):
#print cc
neighbors = [tuple(e) for e in asarray(cc) - connectivity
if e[0] > 0 and e[1] > 0 and e[0] < V.shape[0] and e[1] < V.shape[1]]
neighbors = [ e for e in neighbors if not visit_mask[e] ]
tentative_distance = [(V[e]-V[cc])**2 for e in neighbors]
for i,e in enumerate(neighbors):
d = tentative_distance[i] + m[cc]
if d < m[e]:
m[e] = d
P[e] = cc
visit_mask[cc] = True
m_mask = ma.masked_array(m, visit_mask)
cc = unravel_index(m_mask.argmin(), m.shape)
return m, P
def shortestPath(start, end, P):
Path = []
step = end
while 1:
Path.append(step)
if step == start: break
step = P[step]
Path.reverse()
return asarray(Path)
D, P = dijkstra(V)
path = shortestPath(unravel_index(V.argmin(), V.shape), (40,4), P)
:私はそれを計算することが可能かどうかを知りたい
print path.shape[0]
112
:
contourf(V, 40)
plot(path[:,1], path[:,0], 'r.-')
にパスの長さを112でありますstart
とend
の間の最短経路正確な長さはn
であり、n
は関数に与えられた引数です。
備考:私がしたいと
[NP-complete](https://en.wikipedia)の[旅行購入者の問題](https://en.wikipedia.org/wiki/Travelling_salesman_problem)のバリエーションについてお尋ねします。 org/wiki/NP-completeness)を参照してください。したがって、多項式時間のためにそれを解くアルゴリズムはありません。私はさまざまな[同様の問題の解決策](https://en.wikipedia.org/wiki/Travelling_salesman_problem#Computing_a_solution)が面白いと思います。 –
@Vadim Shkaberda:はい、同様の問題です。提案されているさまざまなソリューションを見ていきます。しかし、私は、トラベルセールスマン問題(TSP)との1つの違いは、すべてのノードを訪問するのではなく、$ n $ノードだけを訪問したいということです。 – bougui
各ステップの 'start/end'からの最大距離に強い制約を追加することはできません。つまり、各ステップで指定できる領域を宣言し、ステップの制限を超えないようにします。訪問したいノードの数が 'start/end'の間の直接距離に比べてそれほど大きくない場合、成功することができます。そして、明らかに 'visit_mask'を捨てるべきです。 –