add penalty to useless actions

This commit is contained in:
NukeBird 2025-03-13 18:16:28 +03:00
parent 19ea8d1eaa
commit 6bb018d24b
2 changed files with 99 additions and 13 deletions

View file

@ -231,6 +231,7 @@ namespace s2ga
auto state = initial_state; auto state = initial_state;
int valid_actions = 0; int valid_actions = 0;
int useless_actions = 0;
int d = 99999; int d = 99999;
@ -248,7 +249,15 @@ namespace s2ga
continue; continue;
} }
state = actions[aid].apply(state); auto new_state = actions[aid].apply(state);
if(state == new_state)
{
useless_actions++;
}
state = new_state;
d = final_goal.distance(state); d = final_goal.distance(state);
cost += actions[aid].cost; cost += actions[aid].cost;
valid_actions++; valid_actions++;
@ -265,7 +274,12 @@ namespace s2ga
return; return;
} }
g.fitness = 9999.0f * d * float(valid_actions) + cost; constexpr float DISTANCE_WEIGHT = 100.0f;
constexpr float USELESS_ACTION_WEIGHT = DISTANCE_WEIGHT * 0.5f;
constexpr float COST_WEIGHT = 1.0f;
g.fitness = DISTANCE_WEIGHT * d +
USELESS_ACTION_WEIGHT * useless_actions + COST_WEIGHT * cost;
//std::cout << std::format("{}({})", g.fitness, cost) << std::endl; //std::cout << std::format("{}({})", g.fitness, cost) << std::endl;
} }
@ -405,10 +419,15 @@ namespace s2ga
return result; return result;
} }
void mutate(genotype& g) void mutate(genotype& g, int max_m = 3)
{ {
int index = rng.random(0, MaxDepth - 1); int mutations = rng.random(1, max_m);
g.action_ids[index] = rng.random(-1, int(actions.size() - 1));
for(int i = 0; i < mutations; ++i)
{
int index = rng.random(0, MaxDepth - 1);
g.action_ids[index] = rng.random(-1, int(actions.size() - 1));
}
} }
public: public:
action_list<E> plan(int population_size, int max_attempts) action_list<E> plan(int population_size, int max_attempts)
@ -417,7 +436,6 @@ namespace s2ga
int attempts = 0; int attempts = 0;
float last_f = 9999999.0f; float last_f = 9999999.0f;
while(attempts < max_attempts) while(attempts < max_attempts)

View file

@ -118,8 +118,8 @@ TEST_CASE("(dummy)", "[test]")
BENCHMARK("GOAPERS") BENCHMARK("GOAPERS")
{ {
goal<State> goal; goal<State> goal;
goal.negative_goals = bm<State>(HUNGRY); goal.negative_goals = bm<State>(HUNGRY, IS_WET);
goal.positive_goals = bm<State>(HAS_HOUSE); goal.positive_goals = bm<State>(HAS_HOUSE, HAS_CLOTHES);
genetic_goap<State> goap; genetic_goap<State> goap;
goap.set_initial_state(bm<State>(HUNGRY, IS_WET, IS_RAINING)); goap.set_initial_state(bm<State>(HUNGRY, IS_WET, IS_RAINING));
@ -128,20 +128,22 @@ TEST_CASE("(dummy)", "[test]")
for(int i = 0; i < 32; ++i) for(int i = 0; i < 32; ++i)
{ {
auto plan = goap.plan(100, 5); auto plan = goap.plan(100, 4);
(void)plan; (void)plan;
} }
}; };
goal<State> goal; goal<State> goal;
goal.negative_goals = bm<State>(HUNGRY); goal.negative_goals = bm<State>(HUNGRY, IS_WET);
goal.positive_goals = bm<State>(HAS_HOUSE); goal.positive_goals = bm<State>(HAS_HOUSE, HAS_CLOTHES);
genetic_goap<State> goap; genetic_goap<State> goap;
goap.set_initial_state(bm<State>(HUNGRY, IS_WET, IS_RAINING)); goap.set_initial_state(bm<State>(HUNGRY, IS_WET, IS_RAINING));
goap.set_possible_actions(actions); goap.set_possible_actions(actions);
goap.set_goal(goal); goap.set_goal(goal);
auto plan = goap.plan(100, 5); auto plan = goap.plan(100, 4);
std::cout << "\n" << std::endl;
float cost = 0.0f; float cost = 0.0f;
for(auto& i: plan) for(auto& i: plan)
@ -152,10 +154,76 @@ TEST_CASE("(dummy)", "[test]")
std::cout << std::format("[Total Cost: {}]", cost) << std::endl; std::cout << std::format("[Total Cost: {}]", cost) << std::endl;
if(plan.size() == 0) if(plan.empty())
{ {
std::cout << "SAD" << std::endl; std::cout << "SAD" << std::endl;
} }
/*
[WAIT OUT RAIN, 5]
Effects:
-IS_RAINING
Preconditions:
+IS_RAINING
[COLLECT WOOD, 2]
Effects:
+HAS_WOOD
Preconditions:
-IS_RAINING
[CRAFT TOOLS, 5]
Effects:
-HAS_WOOD
+HAS_TOOLS
Preconditions:
+HAS_WOOD
[COLLECT WOOD, 2]
Effects:
+HAS_WOOD
Preconditions:
-IS_RAINING
[HUNT ANIMAL, 6]
Effects:
+HAS_ANIMAL_SKIN
+HAS_RAW_FOOD
Preconditions:
+HAS_TOOLS
-IS_RAINING
[PROCESS ANIMAL SKIN, 6]
Effects:
+HAS_FABRIC
-HAS_ANIMAL_SKIN
Preconditions:
+HAS_ANIMAL_SKIN
[BUILD HOUSE, 8]
Effects:
+HAS_HOUSE
-HAS_WOOD
-IS_WET
Preconditions:
-HAS_HOUSE
+HAS_WOOD
+HAS_TOOLS
[MAKE CLOTHES, 4]
Effects:
+HAS_CLOTHES
-HAS_FABRIC
Preconditions:
+HAS_FABRIC
-IS_WET
[COOK, 0.25]
Effects:
+HAS_FOOD
-HAS_RAW_FOOD
Preconditions:
+HAS_RAW_FOOD
[EAT, 0.1]
Effects:
-HUNGRY
-HAS_FOOD
Preconditions:
+HAS_FOOD
[Total Cost: 38.35]
*/
} }
TEST_CASE("lehmer64 rng", "[test]") TEST_CASE("lehmer64 rng", "[test]")