我正在尝试构建一个由神经网络玩的小游戏“贪吃蛇”。我创建了 2 个类,一个用于神经网络,另一个用于游戏。该游戏有一个类神经网络的实例,我使用了一个 unique_ptr 来避免使用基本指针并用它进行训练。
神经网络类有 2 个主要私有变量,它们使用 Eigen::MatrixXd 和 Eigen::VectorXd。
当所有的蛇都死了,是时候进行新一代了,所以我调用了一个创建它的函数:
std::vector<std::pair<std::unique_ptr<NeuralNetwork>, int>> paired_vector;
(分数的整数)
我像这样推回我的价值观:
for (int i{ 0 }; i < m_number_player; i++)
{
// make_pair to create a pair and std::move to move the content of each unique_ptr to the paired_vector
paired_vector.push_back(std::make_pair(std::move(m_players[i]), m_points[i]));
}
之后,我用每条蛇的点对向量进行排序:
std::sort(paired_vector.begin(), paired_vector.end(), [](const auto& a, const auto& b) { return a.second > b.second; });
问题来了:
// crossOver the bests
for (int i{ 10 }; i < m_number_player; i++)
{
int random1{ rand() % 11 };
int random2{};
do {
random2 = rand() % 11;
} while (random2 == random1);
std::vector<Eigen::MatrixXd> value_returned = crossOverWeights(paired_vector[random2].first.get()->getWeigths(), paired_vector[random1].first.get()->getWeigths());
paired_vector[i].first.get()->setWeigths(value_returned);
这部分必须在前 10 名中随机选择 2 条“蛇”。然后函数必须将 2 条最好的蛇的权重“混合”到一条坏蛇。所以我调用成员函数 setWeights() 来发送带有返回值的函数的新权重。这个函数有两个参数:
std::vector<Eigen::MatrixXd> Game::crossOverWeights(const std::vector<Eigen::MatrixXd>& second, const std::vector<Eigen::MatrixXd>& first)
我有 4 个这样的函数:crossOverWeights、crossOverBiases、mutationWeights 和 mutationBiases,它们的工作原理完全相同。
函数内部:
std::vector<Eigen::MatrixXd> Game::crossOverWeights(const std::vector<Eigen::MatrixXd>& second, const std::vector<Eigen::MatrixXd>& first)
{
std::vector<Eigen::MatrixXd> temp(second.size());
// loop through all the weights
for (int i{ 0 }; i < static_cast<int>(second.size()); i++)
{
// change the weights of the half first part
if (i <= static_cast<int>(second.size() / 2))
temp[i] = first[i];
else // stay unchanged
temp[i] = second[i];
}
return temp;
}
问题是:当我有 50 条蛇时,程序在第二代崩溃。当我有 11 条蛇时,程序可能会在第五代或类似的时候崩溃。
错误是“检测到堆损坏:正常块后...CRT 检测到应用程序在堆缓冲区结束后写入内存” 所以我想我到达了矢量或 Eigen::MatrixXd 的末尾,但这怎么可能呢?当我设置新的权重时,我会这样做:
m_weights.clear();
m_weights = new_weights;
也许有人知道问题可以帮助我? 谢谢您,请随时向我询问更多详情