-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathactive_inference_simulation.c
176 lines (150 loc) · 5.51 KB
/
active_inference_simulation.c
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define NUM_AGENTS 5
#define NUM_STATES 3
#define NUM_ACTIONS 2
#define NUM_OBSERVATIONS 2
// Agent structure
typedef struct {
double beliefs[NUM_STATES];
double transition_model[NUM_STATES][NUM_ACTIONS][NUM_STATES];
double observation_model[NUM_STATES][NUM_OBSERVATIONS];
double action_prior[NUM_ACTIONS];
} Agent;
// Function prototypes
void initialize_agent(Agent *agent);
int select_action(Agent *agent);
void update_beliefs(Agent *agent, int action, int observation);
int get_observation(int true_state);
void simulate_step(Agent *agents, int *true_states);
// Main simulation loop
int main() {
srand(time(NULL));
Agent agents[NUM_AGENTS];
int true_states[NUM_AGENTS];
// Initialize agents and true states
for (int i = 0; i < NUM_AGENTS; i++) {
initialize_agent(&agents[i]);
true_states[i] = rand() % NUM_STATES;
}
// Run simulation for 100 steps
for (int step = 0; step < 100; step++) {
printf("Step %d:\n", step);
simulate_step(agents, true_states);
printf("\n");
}
return 0;
}
// Initialize agent with random beliefs and models
void initialize_agent(Agent *agent) {
// Initialize beliefs
double sum = 0;
for (int i = 0; i < NUM_STATES; i++) {
agent->beliefs[i] = (double)rand() / RAND_MAX;
sum += agent->beliefs[i];
}
for (int i = 0; i < NUM_STATES; i++) {
agent->beliefs[i] /= sum;
}
// Initialize transition model
for (int s = 0; s < NUM_STATES; s++) {
for (int a = 0; a < NUM_ACTIONS; a++) {
sum = 0;
for (int s_next = 0; s_next < NUM_STATES; s_next++) {
agent->transition_model[s][a][s_next] = (double)rand() / RAND_MAX;
sum += agent->transition_model[s][a][s_next];
}
for (int s_next = 0; s_next < NUM_STATES; s_next++) {
agent->transition_model[s][a][s_next] /= sum;
}
}
}
// Initialize observation model
for (int s = 0; s < NUM_STATES; s++) {
sum = 0;
for (int o = 0; o < NUM_OBSERVATIONS; o++) {
agent->observation_model[s][o] = (double)rand() / RAND_MAX;
sum += agent->observation_model[s][o];
}
for (int o = 0; o < NUM_OBSERVATIONS; o++) {
agent->observation_model[s][o] /= sum;
}
}
// Initialize action prior
sum = 0;
for (int a = 0; a < NUM_ACTIONS; a++) {
agent->action_prior[a] = (double)rand() / RAND_MAX;
sum += agent->action_prior[a];
}
for (int a = 0; a < NUM_ACTIONS; a++) {
agent->action_prior[a] /= sum;
}
}
// Select action based on current beliefs
int select_action(Agent *agent) {
double expected_free_energy[NUM_ACTIONS] = {0};
for (int a = 0; a < NUM_ACTIONS; a++) {
for (int s_next = 0; s_next < NUM_STATES; s_next++) {
double transition_prob = 0;
for (int s = 0; s < NUM_STATES; s++) {
transition_prob += agent->beliefs[s] * agent->transition_model[s][a][s_next];
}
double kl_divergence = 0;
for (int o = 0; o < NUM_OBSERVATIONS; o++) {
double p_o = 0;
for (int s = 0; s < NUM_STATES; s++) {
p_o += agent->observation_model[s][o] * transition_prob;
}
if (p_o > 0) {
kl_divergence += p_o * log(p_o / agent->observation_model[s_next][o]);
}
}
expected_free_energy[a] += transition_prob * (kl_divergence - log(agent->action_prior[a]));
}
}
// Select action with lowest expected free energy
int best_action = 0;
for (int a = 1; a < NUM_ACTIONS; a++) {
if (expected_free_energy[a] < expected_free_energy[best_action]) {
best_action = a;
}
}
return best_action;
}
// Update agent's beliefs based on action and observation
void update_beliefs(Agent *agent, int action, int observation) {
double new_beliefs[NUM_STATES] = {0};
for (int s_next = 0; s_next < NUM_STATES; s_next++) {
double transition_prob = 0;
for (int s = 0; s < NUM_STATES; s++) {
transition_prob += agent->beliefs[s] * agent->transition_model[s][action][s_next];
}
new_beliefs[s_next] = transition_prob * agent->observation_model[s_next][observation];
}
// Normalize new beliefs
double sum = 0;
for (int s = 0; s < NUM_STATES; s++) {
sum += new_beliefs[s];
}
for (int s = 0; s < NUM_STATES; s++) {
agent->beliefs[s] = new_beliefs[s] / sum;
}
}
// Get observation based on true state
int get_observation(int true_state) {
// Simplified observation model: 70% chance of correct observation
return (rand() % 100 < 70) ? true_state % NUM_OBSERVATIONS : (true_state + 1) % NUM_OBSERVATIONS;
}
// Simulate one step for all agents
void simulate_step(Agent *agents, int *true_states) {
for (int i = 0; i < NUM_AGENTS; i++) {
int action = select_action(&agents[i]);
int observation = get_observation(true_states[i]);
update_beliefs(&agents[i], action, observation);
// Update true state (simplified environment dynamics)
true_states[i] = (true_states[i] + action) % NUM_STATES;
printf("Agent %d: Action %d, Observation %d, True State %d\n", i, action, observation, true_states[i]);
}
}