fix gnarly bug in hill-climbing resulting in hill-falling

try_swap occasionally made very bad swaps that increased the overall cost.
If asked to swap neighboring patches, the calculations were completely wrong.
pull/1/head
Lex Neva 2016-01-18 22:16:23 -05:00
rodzic e2fd415664
commit 67125cdc0b
1 zmienionych plików z 30 dodań i 11 usunięć

Wyświetl plik

@ -253,21 +253,35 @@ class PatchList:
return self.patches[i] return self.patches[i]
def cost(self, a, b): def cost(self, a, b):
if (a==None or b==None): if (a is None or b is None):
rc = 0.0 rc = 0.0
else: else:
rc = (a.stitches[-1] - b.stitches[0]).length() rc = (a.stitches[-1] - b.stitches[0]).length()
#dbg.write("cost(%s, %s) = %5.1f\n" % (a, b, rc)) #dbg.write("cost(%s, %s) = %5.1f\n" % (a, b, rc))
return rc return rc
def total_cost(self):
total = 0
for i in xrange(1, len(self.patches)):
total += self.cost(self.get(i-1), self.get(i))
return total
def try_swap(self, i, j): def try_swap(self, i, j):
# i,j are indices; # i,j are indices;
#dbg.write("swap(%d, %d)\n" % (i,j)) #dbg.write("swap(%d, %d)\n" % (i,j))
oldCost = ( i, j = sorted((i, j))
self.cost(self.get(i-1), self.get(i)) neighbors = abs(i - j) == 1
+self.cost(self.get(i), self.get(i+1)) if neighbors:
+self.cost(self.get(j-1), self.get(j)) oldCost = sum((self.cost(self.get(i-1), self.get(i)),
+self.cost(self.get(j), self.get(j+1))) self.cost(self.get(i), self.get(j)),
self.cost(self.get(j), self.get(j+1))))
else:
oldCost = sum((self.cost(self.get(i-1), self.get(i)),
self.cost(self.get(i), self.get(i+1)),
self.cost(self.get(j-1), self.get(j)),
self.cost(self.get(j), self.get(j+1))))
npi = self.get(j) npi = self.get(j)
npj = self.get(i) npj = self.get(i)
rpi = npi.reverse() rpi = npi.reverse()
@ -280,11 +294,16 @@ class PatchList:
] ]
def costOf(np): def costOf(np):
(npi,npj) = np (npi,npj) = np
return (
self.cost(self.get(i-1), npi) if abs(i - j) == 1:
+self.cost(npi, self.get(i+1)) return sum((self.cost(self.get(i-1), npi),
+self.cost(self.get(j-1), npj) self.cost(npi, npj),
+self.cost(npj, self.get(j+1))) self.cost(npj, self.get(j+1))))
else:
return sum((self.cost(self.get(i-1), npi),
self.cost(npi, self.get(i+1)),
self.cost(self.get(j-1), npj),
self.cost(npj, self.get(j+1))))
costs = map(lambda o: (costOf(o), o), options) costs = map(lambda o: (costOf(o), o), options)
costs.sort() costs.sort()
(cost,option) = costs[0] (cost,option) = costs[0]