Commit f8368902 authored by Quentin Verout's avatar Quentin Verout
Browse files

Delete distances.py

parent d91fa1b6
Loading
Loading
Loading
Loading

distances.py

deleted100755 → 0
+0 −149
Original line number Diff line number Diff line
#!/usr/bin/env python3

import sys
import time
import random
import Levenshtein as leven
import jaro

class Robustness:
	def __init__(self, filename):
		"""
		filename is the name of the file where passwords are stored
		"""
		self.l = list()
		with open(filename) as inbuff:
			for word in inbuff:
				word = word.strip()
				self.l.append(word)
		self.distance = leven.distance
		self.k = len(self.l)
		self.algo = self.random_permutation

	def swap(self, i, j):
		self.l[i], self.l[j] = self.l[j], self.l[i]

	def random_permutation(self):
		"""
		generator for a random permutation of the list self.l using
		Fisher-Yates algorithm
		"""
		d = len(self.l)
		for i in range(d):
			r = random.randint(i, d-1)
			self.swap(i, r)
			yield self.l[i]

	def closest_word(self):
		"""
		excursion by choosing the closest word to w_n
		"""
		d = len(self.l)
		i0 = random.randint(0, d-1)
		w0 = self.l[i0]
		self.swap(0, i0)
		yield w0

		for i in range(1, d):
			before = time.time()
			lowest_distance = self.distance(w0, self.l[i])
			lowest_index = i
			for j in range(i+1, d):
				dist = self.distance(w0, self.l[j])
				if dist < lowest_distance:
					lowest_distance = dist
					lowest_index = j
			self.swap(i, lowest_index)
			after = time.time()
			print("Found the %dth closest word in %d seconds" % (i, after-before))
			yield self.l[i]

	def closest_word_among(self, m=10):
		"""
		generates a permutation where w_0 is randomly choosen and w_n+1
		is the closest neighbor of w_n among m randomly choosen words.
		Uses the Fisher-Yates algorithm to browse the list.
		"""
		# select the first word w0
		d = len(self.l)
		i0 = random.randint(0, d-1)
		w0 = self.l[i0]
		self.swap(0, i0)
		yield w0
		# select all the remaining ones
		for i in range(1, d):
			# pick the closest one among m random ones
			before = time.time()
			i_n = random.randint(i, d-1)
			w_n = self.l[i_n]
			lowest_distance = self.distance(w0, w_n)
			lowest_index = i_n
			for j in range(m-1):
				i_n = random.randint(1, d-1)
				w_n = self.l[i_n]
				dist = self.distance(w0, w_n)
				if dist < lowest_distance:
					lowest_distance = dist
					lowest_index = i_n
			self.swap(i, lowest_index)
			after = time.time()
			print("Found the %dth closest word in " %i, after-before, "seconds")
			yield self.l[i]

	def cost_rate(self):
		"""
		runs an excursion and return its cost rate.
		Parameters are fixed using object members (l, k, algo, distance)
		"""
		dist = dict()
		c = 0
		k = self.k
		ratio = len(self.l) / self.k
		perm = self.algo()
		w0 = next(perm)
		for w in perm:
			c += self.distance(w0, w)
			w0 = w
			if k == 0:
				break
			k -= 1
		return int(c * ratio)

	def min_cost(self, n=1):
		"""
		runs n excursions and returns the lowest cost rate found among them.
		"""
		before = time.time()
		min_c = self.cost_rate()
		after = time.time()
		print(after-before)
		for i in range(n-1):
			before = time.time()
			min_c = min(min_c, self.cost_rate())
			after = time.time()
			print(after-before)
		return min_c

	def all_distances(self):
		"""
		computes and stores all the distances between every couple of words
		"""
		ad = dict()
		for i, w in enumerate(self.l):
			before = time.time()
			for v in self.l[i:]:
				if w not in ad:
					ad[w] = dict()
				ad[w][v] = self.distance(w, v)
			after = time.time()
			print(w, after-before)

if __name__ == '__main__':
	before = time.time()
	R = Robustness(sys.argv[1])
	after = time.time()
	print("File loaded in %d seconds" % (after-before))
	R.algo = R.closest_word_among
	# R.k = int(len(R.l)/10**7)
	print(R.k)
	print(R.min_cost(n=10))