-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrem_engine.py
More file actions
85 lines (75 loc) · 3.03 KB
/
rem_engine.py
File metadata and controls
85 lines (75 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import networkx as nx
import random
class MemoryGraph:
"""
A directed graph that simulates a Memory Graph for Project REM.
Implements the 'Anti-Gravity' algorithm for pathfinding.
"""
def __init__(self):
# Initialize a directed graph
self.graph = nx.DiGraph()
def add_memory(self, concept_a, concept_b, strength):
"""
Adds a directed edge between two concepts with a strength (0.0 to 1.0).
In the 'Anti-Gravity' model, Strength = Cost.
"""
# Ensure strength is within bounds
strength = max(0.0, min(1.0, float(strength)))
self.graph.add_edge(concept_a, concept_b, strength=strength)
def dream_walk(self, start_node, end_node):
"""
Finds the path of 'least resistance' (Anti-Gravity).
Higher strength edges are more 'expensive' (high gravity).
Uses Dijkstra's algorithm via networkx shortest_path.
"""
try:
# nx.shortest_path uses Dijkstra's when weight is provided
path = nx.shortest_path(self.graph, source=start_node, target=end_node, weight='strength')
return path
except nx.NetworkXNoPath:
return None
except nx.NodeNotFound as e:
print(f"Error: {e}")
return None
def populate_mock_data(memory_graph):
"""
Populates the graph with 20 random concepts and connections.
"""
concepts = [
"Coffee", "Spaceship", "Tax Law", "Puppies", "Quantum Physics",
"Ancient Rome", "Cyberpunk", "Jazz", "Mountain Climbing", "Deep Sea",
"Artificial Intelligence", "Sushi", "Orchestra", "Black Holes", "Rainforest",
"Time Travel", "Electric Sheep", "Meditation", "Gardening", "Architecture"
]
# Ensure all nodes exist
for concept in concepts:
memory_graph.graph.add_node(concept)
# Create ~40 random connections to ensure some paths exist
for _ in range(40):
a, b = random.sample(concepts, 2)
strength = round(random.uniform(0.1, 1.0), 2)
memory_graph.add_memory(a, b, strength)
if __name__ == "__main__":
# Demonstration
rem = MemoryGraph()
populate_mock_data(rem)
# Pick two random concepts for a dream walk
nodes = list(rem.graph.nodes)
if nodes:
start = random.choice(nodes)
end = random.choice(nodes)
while end == start:
end = random.choice(nodes)
print(f"--- Starting Dream Walk from '{start}' to '{end}' ---")
path = rem.dream_walk(start, end)
if path:
print("Path of least resistance found:")
total_gravity = 0
for i in range(len(path) - 1):
u, v = path[i], path[i+1]
strength = rem.graph[u][v]['strength']
total_gravity += strength
print(f" {u} --({strength})--> {v}")
print(f"Total Gravity (Cost): {total_gravity:.2f}")
else:
print(f"No path found between '{start}' and '{end}'. (The void consumes the memory)")