遗传算法&神经网络:获取临时[-fpermissive]的地址

时间:2015-03-08 15:42:14

标签: c++ neural-network genetic-algorithm temporary-objects

我正致力于基因进化神经网络。我在2008年使用visual studio 2005编写了一个程序。现在我将程序转换为Eclipse(Linux)和VS 2013(Win)项目,并支持c ++ 11。运行后,两个项目都给出了同样的错误:

  

获取临时[-fpermissive]

的地址

经过大量搜索后发现,由于新的C ++标准不允许获取临时对象的地址,因此会出现此错误。因为所有对象都是使用“new”创建的(所以我猜它们应该始终可用)。我部分地想出了问题,但不知道如何解决它。如果你运行eclipse项目,它将突出显示项目中的两个错误。

由于需要完整的代码来检查所以我很难用语言来解释所以我在https://bitbucket.org/a-akram/geans.git的git上托管了eclipse项目,我让每个人都可以访问它。

主要问题是变量wp1& wp2m_vPopulatin是包含神经网络地址的向量。

CNeuralNetwork* CGeneticEngine::Evolve()
{
    CLearningEngine *l;
    double totalError =  0.0;
    for (int iter = 0;iter < CGN_MAXITER; iter++)
    {
        for (int i = 0;i < CGN_POPULATION; i++)
        {
            l = new CLearningEngine(m_vPopulation[i]);
            l->Run(m_vTrainingDataset);
            for(unsigned int p = 0; p < m_vTrainingDataset->size(); p++)
            {
                totalError = totalError + m_vPopulation[i]->getm_dTotalNetworkError();
                totalError = totalError/m_vTrainingDataset->size();
            }
            if (totalError < CGN_THRESHOLD)
                 return m_vPopulation[i];

            m_dErrors[i] = totalError;
        }
        SortFitnesses();
        NewPopulation();
    }
    return NULL;

}

void CGeneticEngine::NewPopulation()
{
    int id1, id2;
    double temp;
    std::vector <CSynapticConnection *> *wp1;
    std::vector <CSynapticConnection *> *wp2;
    for (int i=0;i<CGN_POPULATION / 2;i++)
    {
        id1 = rand() % CGN_POPULATION / 2;
        id2 = rand() % CGN_POPULATION / 2 + CGN_POPULATION / 2;

        wp1 = &m_vPopulation[id1]->getm_vListofSynaptics();
        wp2 = &m_vPopulation[id2]->getm_vListofSynaptics();

        // Cross over the weights.
        for (int j = 0; j < 2; j++)
        {
            temp = (*wp1)[j+6]->getWeight();
            (*wp1)[j+6]->setWeight((*wp2)[j+6]->getWeight() );
            (*wp2)[j+6]->setWeight(temp);
        }

        //  adding slight genetic change due to crossover randomly.
        if (rand() % 10 < 2)
        {
            for(unsigned int j = 0; j < wp1->size();j++)
                (*wp1)[j]->changeWeight((double)(rand())/(32767/2) - 1);

            for(unsigned int j = 0; j < wp2->size();j++)
                (*wp2)[j]->changeWeight((double)(rand())/(32767/2) - 1);
         }
    }
}

由于这是我在这个论坛上的第一个问题所以我可能没有说得好,所以我要求主持人暂时不要关闭它。如有必要,我会更清楚。但是随着项目文件的掌握,你们很容易找出问题和解决方案。

我将非常感谢您帮助解决问题...如果您需要任何进一步的信息,请与我们联系。

1 个答案:

答案 0 :(得分:2)

首先考虑CNeuralNetwork类的这个子集:

class CNeuralNetwork
{
  // ...
public:
  std::vector<CSynapticConnection *> getm_vListofSynaptics()
  {
    return m_vListofSynaptics;
  }

  std::vector<CSynapticConnection*> m_vListofSynaptics;
  // ...
};

这里有一个getter(getm_vListofSynaptics()),它返回一个临时值:公共数据成员m_vListofSynaptics副本

CGeneticEngine::NewPopulation()函数中,您将获取临时对象的地址,这会触发错误:

wp1 = &m_vPopulation[id1]->getm_vListofSynaptics();
wp2 = &m_vPopulation[id2]->getm_vListofSynaptics();

(有关详细信息,请参阅Why is taking the address of a temporary illegal?。)

您需要考虑/应用一些更改:

  • getters / setter对于行为的封装/隐藏属性的内部表示是有用的(?),但是m_vListofSynaptics是公共的,所以getter&#34;几乎没有购买任何东西&#34; (例如,请参阅Why use getters and setters? / Public Data members vs Getters, Setters了解情况)

  • 关于错误,你可以(这只是一个&#34;快速修复&#34;,设计似乎可以改为完全避免吸气剂):

    • 更改getter以便它返回一个指向数据成员的引用/指针(数据成员应该是私有的)

      class CNeuralNetwork
      {
      // ...
      public:
        std::vector<CSynapticConnection *> *getm_vListofSynaptics()
        {
          return &m_vListofSynaptics;
        }
      private:
        std::vector<CSynapticConnection*> m_vListofSynaptics;
      };
      
    • 直接访问m_vListofSynaptics数据成员(可能不是一个好主意):

      wp1 = &m_vPopulation[id1]->m_vListofSynaptics;
      

      (看看If a variable has getter and setter, should it be public?