WEIGHTS_CACHE_FILE = 'weights.cache' def load_weights_cache(patterns_file) return nil unless File.exist?(WEIGHTS_CACHE_FILE) cached = Marshal.load(File.binread(WEIGHTS_CACHE_FILE)) cached[:mtime] == File.mtime(patterns_file) ? cached[:weights] : nil rescue nil end def save_weights_cache(weights, patterns_file) File.binwrite(WEIGHTS_CACHE_FILE, Marshal.dump({ mtime: File.mtime(patterns_file), weights: weights })) end def train_hopfield(vectors) n = vectors[0].length weights = Array.new(n) { Array.new(n, 0.0) } vectors.each do |v| n.times do |i| n.times do |j| weights[i][j] += v[i] * v[j] unless i == j end end end weights end def step_hopfield(weights, vector) n = vector.length Array.new(n) do |i| sum = 0.0 n.times { |j| sum += weights[i][j] * vector[j] } sum >= 0 ? 1 : -1 end end MAX_HOPFIELD_ITER = 200 def recall_hopfield(weights, input_vec) current = input_vec.dup next_vec = step_hopfield(weights, current) iter = 1 while !vectors_equal?(current, next_vec) && iter < MAX_HOPFIELD_ITER current = next_vec next_vec = step_hopfield(weights, current) iter += 1 end next_vec end