基于遗传算法和粒子群算法的混合算法实现小老鼠找奶酪问题

来源:互联网 发布:服务器域名根目录 编辑:程序博客网 时间:2024/04/30 10:18

此为老师留的大作业

算法依据:http://wenku.baidu.com/view/4387f569af1ffc4ffe47acc7

算法实现

#ifndef CHEESE_H#define CHEESE_H#include <QGraphicsPixmapItem>#include <QGraphicsItem>#include <QPixmap>#include <QPainter>class Cheese : public QGraphicsPixmapItem{//    Q_OBJECTpublic:    Cheese();    void setSize(int size);    void paint(QPainter *painter,                   const QStyleOptionGraphicsItem *option, QWidget *widget);private:    QPixmap pixmap;    };
#ifndef MAINWINDOWS_H#define MAINWINDOWS_H#include <QMainWindow>#include <QLabel>#include <QMenu>#include <QMenuBar>#include <QToolBar>#include <QStatusBar>#include <QMessageBox>#include <QSlider>#include <QtGui>#include <QFileDialog>#include <QGraphicsScene>#include <QGraphicsView>#include <QHBoxLayout>#include <QVBoxLayout>#include <QPushButton>#include <math.h>#include "mouse.h"#include "cheese.h"#include "particle.h"#include "MixAlogrithm.h"struct CheesePoint{    int X;    int Y;};class MainWindows : public QMainWindow{    Q_OBJECTpublic:    explicit MainWindows(QWidget *parent = 0);private:    QGraphicsView *view;    QGraphicsScene *scene;    CheesePoint* cheesePos;    Cheese *cheeses;    Mouse *mouses;    double *cheeses_size;    QLabel *label1;    QLabel *label2;    QLabel *label3;    QLabel *label4;    QPushButton *initPushButton;    QPushButton *nextPushButton;    QHBoxLayout *uplayout;    QVBoxLayout *mainlayout;    int steps;    MixAlogrithm* mymix;signals:    public slots:    void OPSCheeses();    void InitProcess();    double getDensity(int,int);    void showDensity();};#endif // MAINWINDOWS_H

#ifndef MIXALOGRITHM_H#define MIXALOGRITHM_H#include <math.h>#include <QtGlobal>#include "particle.h"class MixAlogrithm{public:    MixAlogrithm(int dim, int num);    void Initialize();    int SetXup(double* xup);  //设置微粒坐标上界    int SetXdown(double* dXdown); //设置微粒坐标下界    //设置微粒最大速度,以数组为参数    int SetVmax(double* dVMax);    //设置微粒最大速度,以上下界百分比为参数    int SetVmax(double dPer);    //设置权重    void SetW(double w);    //设置C1,C2    void SetC1(double c);    void SetC2(double c);    void SetFit(double dFit,int i,int sel);    void SetFitBest(double dFit,int i);    double GetFit(int i);    //微粒飞翔,产生新一代微粒    void ParticleFly();    //查找最优粒子    void FindBestParticle();    //设置所选粒子的坐标,可以初始化一个已知的粒子,避免太多的随机性    void SetX(int i, double* dX);    //返回所选粒子的坐标    double* GetX(int i, int sel);    //返回最佳粒子的X和最佳适合度    double* GetBest();    //交叉遗传    void Cross();    //变异    void Vary();    //变异选择    void VarySelect();    //遗传选择    void GeneSelect();private:    MyParticle* particles; //微粒群数组    MyParticle* sonparticles; //子代微粒群    MyParticle* varyparticles; //变异粒子群    int PNum; //微粒个数    int GBestIndex; //最好微粒索引    double W; //惯性权重    double C1; //加速度系数1    double C2; //加速度系数2    double* Xup; //微粒坐标上界数组    double* Xdown; //微粒坐标下界数组    double* Vmax; //微粒最大速度数组    double* FitBak;};#endif // MIXALOGRITHM_H

/******************************************************************************** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).** Contact: http://www.qt-project.org/legal**** This file is part of the examples of the Qt Toolkit.**** $QT_BEGIN_LICENSE:BSD$** You may use this file under the terms of the BSD license as follows:**** "Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions are** met:**   * Redistributions of source code must retain the above copyright**     notice, this list of conditions and the following disclaimer.**   * Redistributions in binary form must reproduce the above copyright**     notice, this list of conditions and the following disclaimer in**     the documentation and/or other materials provided with the**     distribution.**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names**     of its contributors may be used to endorse or promote products derived**     from this software without specific prior written permission.****** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."**** $QT_END_LICENSE$******************************************************************************/#ifndef MOUSE_H#define MOUSE_H#include <QGraphicsItem>//! [0]class Mouse : public QGraphicsItem{public:    Mouse();    QRectF boundingRect() const;    QPainterPath shape() const;    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,               QWidget *widget);protected:    void advance(int step);private:    qreal angle;    qreal speed;    qreal mouseEyeDirection;    QColor color;};//! [0]#endif

#ifndef PARTICLE_H#define PARTICLE_Hclass MyParticle{public:    MyParticle();    MyParticle(int d);    void InitParticle(int d);    int GetDim();    void SetDim(int);    int IsValid();    double GetFitness();    void SetFit(double fit);    void SetFitBest(double fit);public:    double *X; //微粒的坐标数组    double *V; //微粒的速度数组    double *XBest; //微粒的最好位置数组    double Fit; //微粒适合度    double FitBest; //微粒最好位置适合度    int Dim; //微粒的维数    int iValid;  //需要先设定粒子的维数,这个粒子类才好用};#endif // PARTICLE_H

#include "cheese.h"Cheese::Cheese(){    pixmap.load(":/images/cheese.jpg");    setPixmap(pixmap);}void Cheese::setSize(int size){    pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);    setPixmap(pixmap);}void Cheese::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,           QWidget *widget){    //pixmap = this->pixmap();    QRect rect = pixmap.rect();    painter->drawPixmap(rect,pixmap);}

/******************************************************************************** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).** Contact: http://www.qt-project.org/legal**** This file is part of the examples of the Qt Toolkit.**** $QT_BEGIN_LICENSE:BSD$** You may use this file under the terms of the BSD license as follows:**** "Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions are** met:**   * Redistributions of source code must retain the above copyright**     notice, this list of conditions and the following disclaimer.**   * Redistributions in binary form must reproduce the above copyright**     notice, this list of conditions and the following disclaimer in**     the documentation and/or other materials provided with the**     distribution.**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names**     of its contributors may be used to endorse or promote products derived**     from this software without specific prior written permission.****** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."**** $QT_END_LICENSE$******************************************************************************/#include <QtWidgets>#include "mainwindows.h"//! [0]int main(int argc, char **argv){    QApplication app(argc, argv);    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));    MainWindows mainWindow;    mainWindow.show();    QTimer timer;    QObject::connect(&timer, SIGNAL(timeout()), &mainWindow, SLOT(OPSCheeses()));    timer.start(100000/33);    return app.exec();}//! [6]

#include "mainwindows.h"static const int MouseCount = 10;static const int CheeseCount = 2;double xup[2] = {600.0,600.0};double xdown[2] = {-600.0,-600.0};double vmax[2] = {5.0,5.0};MainWindows::MainWindows(QWidget *parent) :    QMainWindow(parent){    scene = new QGraphicsScene(-600, -600, 1200, 1200);    scene->setItemIndexMethod(QGraphicsScene::NoIndex);    cheesePos = new CheesePoint[CheeseCount];    cheeses = new Cheese[CheeseCount];    cheeses_size = new double[CheeseCount];    mouses = new Mouse[MouseCount];    view = new QGraphicsView();    view->setScene(scene);    view->setDragMode(QGraphicsView::ScrollHandDrag);    view->resize(1400, 1400);    mainlayout = new QVBoxLayout();    uplayout = new QHBoxLayout();    label1 = new QLabel("迭代次数");    label2 = new QLabel(QString::number(0));    label3 = new QLabel(QString::number(0));    label4 = new QLabel(QString::number(0));    initPushButton = new QPushButton(tr("初始化"));    nextPushButton = new QPushButton(tr("下一步"));    uplayout->addWidget(label1);    uplayout->addWidget(label2);    uplayout->addWidget(label3);    uplayout->addWidget(label4);    uplayout->addWidget(initPushButton);    uplayout->addWidget(nextPushButton);    mainlayout->addLayout(uplayout);    mainlayout->addWidget(view);    mymix = new MixAlogrithm(2, MouseCount);    //showDensity();    mymix->SetXup(xup);    mymix->SetXdown(xdown);    mymix->SetVmax(vmax);//设置最大速度为5个像素    mymix->Initialize();    mymix->SetC1(2.0);    mymix->SetC2(2.1);    mymix->SetW(0.9);    InitProcess(); //初始化    QWidget * w = new QWidget(this);    w->setLayout(mainlayout);    setCentralWidget(w);    setWindowTitle(QObject::tr("小老鼠找奶酪"));}//初始化void MainWindows::InitProcess(){    double p[2];    double *dTemp;    for(int i=0;i<CheeseCount;i++)    {        cheesePos[i].X = (qrand()%100)*8 -400;  //奶酪都在比较靠中间的位置        cheesePos[i].Y = (qrand()%100)*8 -400;        cheeses_size[i] = (qrand() % 100) / 100.0;        cheeses[i].setSize(cheeses_size[i]*64);        cheeses[i].setPos(cheesePos[i].X-cheeses_size[i]*32,cheesePos[i].Y-cheeses_size[i]*32);        scene->addItem(&cheeses[i]);    }    steps = 0;    label2->setText(QString::number(steps));    //假设老鼠开始的位置是半径为700的一圈    for (int i = 0; i < MouseCount; ++i)    {        p[0] = ::sin((i * 6.28) / MouseCount) * 700;        p[1] = ::cos((i * 6.28) / MouseCount) * 700;        mouses[i].setPos(p[0],p[1]);        mymix->SetX(i,p);        mymix->SetFit(getDensity(i,0),i,0);        mymix->SetFitBest(getDensity(i,0),i);        dTemp = mymix->GetX(i,0);        label3->setText(QString::number(dTemp[0],'f',6));        scene->addItem(&mouses[i]);    }}//优化过程void MainWindows::OPSCheeses(){    double *dTemp;    double value;    mymix->FindBestParticle();//查找最优的粒子    dTemp = mymix->GetBest();    value = dTemp[2];//最优值在第三个值    label4->setText(QString::number(value,'f',6));    mymix->ParticleFly(); //粒子飞翔    steps++;    label2->setText(QString::number(steps));    for(int i=0;i<MouseCount;i++)    {        dTemp = mymix->GetX(i,0);        label3->setText(QString::number(dTemp[0],'f',6));        mouses[i].setPos(dTemp[0],dTemp[1]);        value = getDensity(i,0);        mymix->SetFit(value,i,0);    }    mymix->Cross();    for(int i=0;i<MouseCount;i++)    {        value = getDensity(i,1);        mymix->SetFit(value,i,1);    }    mymix->Vary();    for(int i=0;i<2*MouseCount;i++)    {        value = getDensity(i,2);        mymix->SetFit(value,i,2);    }    mymix->VarySelect();    for(int i=0;i<MouseCount;i++)    {        value = getDensity(i,0);        mymix->SetFit(value,i,0);    }    mymix->GeneSelect();    for(int i=0;i<MouseCount;i++)    {        value = getDensity(i,0);        mymix->SetFit(value,i,0);    }}double MainWindows::getDensity(int m, int sel){    double density = 0.0;    double *dTemp;    dTemp = mymix->GetX(m,sel); //获得老鼠的坐标    for(int i=0;i<CheeseCount;i++)    {        density = density +                  cheeses_size[i] *                  exp(-1*                      (((dTemp[0]-cheesePos[i].X)/600.0)*((dTemp[0]-cheesePos[i].X)/600.0)+                      ((dTemp[1]-cheesePos[i].Y)/600.0)*((dTemp[1]-cheesePos[i].Y)/600.0))                      /0.1);    }    return density;}void MainWindows::showDensity(){    double temp[2];    double den;    int width = 1;    int height = 1;    for(int x=-600;x<=600;x+=100)    {        for(int y=-600;y<=600;y+=100)        {            temp[0] = x;            temp[1] = y;            mymix->SetX(0,temp);            den = getDensity(0,0);            QGraphicsEllipseItem *ellepseitem = new QGraphicsEllipseItem(x,y,width*den, height*den);            scene->addItem(ellepseitem);        }    }}

#include "MixAlogrithm.h"#include  <cstdlib>MixAlogrithm::MixAlogrithm(int dim, int num){    particles = new MyParticle[num];    sonparticles = new MyParticle[num];    varyparticles = new MyParticle[2*num];    for(int i=0; i<num; i++)    {        particles[i].InitParticle(dim);        sonparticles[i].InitParticle(dim);    }    for(int i=0; i<2*num; i++)        varyparticles[i].InitParticle(dim);    PNum = num;    GBestIndex = 0;    Xup = new double[dim];    Xdown = new double[dim];    Vmax = new double[dim];    FitBak = new double[PNum];    W = 1;    C1 = 2;    C2 = 2;}void MixAlogrithm::Initialize(){    for(int i=0; i<PNum; i++)    {        for(int j=0; j<particles[i].Dim; j++)        {            particles[i].X[j] = ((qrand()%100)/100.0)*(Xup[j]-Xdown[j])+Xdown[j];//初始化坐标            particles[i].XBest[j] = particles[i].X[j];            particles[i].V[j] = ((qrand()%100)/100.0)*Vmax[j]-Vmax[j]/2;//初始化速度        }        particles[i].FitBest = particles[i].Fit; //设最优适合度初值        if(particles[i].Fit > particles[GBestIndex].Fit)            GBestIndex = i;//查找群体最优微粒    }}int MixAlogrithm::SetXup(double* xup){    //if(sizeof(xup) == particles[0].GetDim())    //{        for(int i=0; i<particles[0].GetDim(); i++)            Xup[i] = xup[i];        return 0;    //}    //else    //{        //return -1;    //}}int MixAlogrithm::SetXdown(double* dXdown){    //if(sizeof(dXdown) == particles[0].GetDim())    //{        for(int i=0; i<particles[0].GetDim();i++)            Xdown[i] = dXdown[i];        return 0;    //}    //else    //{    //    return -1;    //}}int MixAlogrithm::SetVmax(double* dVMax){    //if(sizeof(dVMax) == particles[0].GetDim())    //{        for(int i=0; i<particles[0].GetDim();i++)            Vmax[i] = dVMax[i];        return 0;    //}    //else    //{        //return -1;    //}}int MixAlogrithm::SetVmax(double dPer){    if(particles[0].GetDim() > 0)    {        for(int i=0; i<particles[0].GetDim(); i++)            Vmax[i] = (Xup[i]-Xdown[i])*dPer;    }    else    {        return -1;    }    return 0;}void MixAlogrithm::SetW(double w){    W=w;}void MixAlogrithm::SetC1(double c){    C1 = c;}void MixAlogrithm::SetC2(double c){    C2 = c;}void MixAlogrithm::SetFit(double dFit,int i,int sel){    switch(sel)    {    case 0:        particles[i].SetFit(dFit);        break;    case 1:        sonparticles[i].SetFit(dFit);        break;    case 2:        varyparticles[i].SetFit(dFit);        break;    default:        particles[i].SetFit(dFit);    }}void MixAlogrithm::SetFitBest(double dFit, int i){    particles[i].SetFitBest(dFit);}double MixAlogrithm::GetFit(int i){    return particles[i].GetFitness();}//微粒飞翔,产生新一代微粒void MixAlogrithm::ParticleFly(){    //整个群体飞向新的位置    for(int i=0; i<PNum; i++)    {        for(int j=0; j<particles[i].Dim; j++)        {            //修改速度            particles[i].V[j] = W*particles[i].V[j]+                    ((qrand()%100)/100.0)*C1*(particles[i].XBest[j]-particles[i].X[j])+                    ((qrand()%100)/100.0)*C2*(particles[GBestIndex].XBest[j]-particles[i].X[j]);        }        for(int j=0; j<particles[i].Dim; j++) //检查速度最大值        {            if(particles[i].V[j]>Vmax[j]) particles[i].V[j] = Vmax[j];//速度保护            if(particles[i].V[j]<-Vmax[j]) particles[i].V[j] = -Vmax[j];//速度保护        }        for(int j=0; j<particles[i].Dim; j++)        {            particles[i].X[j] += particles[i].V[j]; //修改坐标            if(particles[i].X[j]>Xup[j]) particles[i].X[j]=Xup[j];//位置保护            if(particles[i].X[j]<Xdown[j]) particles[i].X[j]=Xdown[j];//位置保护        }    }    //记录上一次的Fit值    for(int i=0; i<PNum; i++)        FitBak[i] = particles[i].Fit;}//找到最优的粒子void MixAlogrithm::FindBestParticle(){    //设置新的个体最好位置    for(int i=0; i<PNum; i++)    {        if(particles[i].Fit>=particles[i].FitBest)        {            particles[i].FitBest = particles[i].Fit;            for(int j=0; j<particles[i].Dim; j++)                particles[i].XBest[j] = particles[i].X[j];        }    }    //设置新的最优个体    for(int i=0; i<PNum; i++)        if(particles[i].FitBest>=particles[GBestIndex].FitBest && i!=GBestIndex) GBestIndex = i;}//设置所选粒子的坐标,可以初始化一个已知的粒子,避免太多的随机性void MixAlogrithm::SetX(int i, double* dX){    //if(sizeof(dX) == particles[i].Dim)    //{        for(int j=0; j<particles[i].Dim;j++)            particles[i].X[j] = dX[j];    //}}//返回所选粒子的坐标double* MixAlogrithm::GetX(int i, int sel){    switch(sel)    {    case 0:        return particles[i].X;        break;    case 1:        return sonparticles[i].X;        break;    case 2:        return varyparticles[i].X;        break;    default:        return particles[i].X;    }}//返回最佳粒子的X和最佳适合度double* MixAlogrithm::GetBest(){    double* dret = new double[particles[GBestIndex].Dim +1];    for(int i=0; i<particles[GBestIndex].Dim; i++)        dret[i] = particles[GBestIndex].XBest[i];    dret[particles[GBestIndex].Dim] = particles[GBestIndex].FitBest;    return dret;}//选择、交叉void MixAlogrithm::Cross(){    int Dad[10];    int SelSign = 0x000003ff , Select;    int i,j=0;    //随机两两配对    while(SelSign != 0)    {        Select = qrand()%10;        i = (0x00000001<<Select);        if(SelSign & i)        {            Dad[j] = Select;            j++;            SelSign &= (~i);        }    }    //交叉    for(i=0;i<(PNum/2);i++)    {        double r = (qrand()%100)/100.0;        int id1,id2;        id1 = 2*i;        id2 = id1+1;        for(j=0;j<particles[0].Dim;j++)        {            sonparticles[Dad[id1]].X[j] = r*particles[Dad[id1]].X[j] + (1.0-r)*particles[Dad[id2]].X[j];            sonparticles[Dad[id2]].X[j] = r*particles[Dad[id2]].X[j] + (1.0-r)*particles[Dad[id1]].X[j];            sonparticles[Dad[id1]].V[j] = r*particles[Dad[id1]].V[j] + (1.0-r)*particles[Dad[id2]].V[j];            sonparticles[Dad[id2]].V[j] = r*particles[Dad[id2]].V[j] + (1.0-r)*particles[Dad[id1]].V[j];        }    }}void MixAlogrithm::Vary(){    for(int i=0; i<2*PNum; i++)    {        for(int j=0; j<varyparticles[i].Dim; j++)        {            varyparticles[i].X[j] = ((qrand()%100)/100.0)*(Xup[j]-Xdown[j])+Xdown[j];        }    }}void MixAlogrithm::VarySelect(){    for(int i=0;i<PNum;i++)    {        if(particles[i].Fit < varyparticles[i].Fit)        {            for(int j=0;j<particles[i].Dim;j++)            {                if((varyparticles[i].X[j]-particles[i].X[j])>Vmax[j])//坐标保护                    particles[i].X[j] += Vmax[j];                else if((varyparticles[i].X[j]-particles[i].X[j])<-Vmax[j])                    particles[i].X[j] += -Vmax[j];                else                    particles[i].X[j] = varyparticles[i].X[j];            }        }        if(sonparticles[i].Fit < varyparticles[PNum+i].Fit)        {            sonparticles[i].Fit = varyparticles[PNum+i].Fit;            for(int j=0;j<sonparticles[i].Dim;j++)                sonparticles[i].X[j] = varyparticles[PNum+i].X[j];        }    }}void MixAlogrithm::GeneSelect(){    for(int i=0;i<PNum;i++)    {        if(particles[i].Fit < sonparticles[i].Fit)        {            for(int j=0;j<particles[i].Dim;j++)            {                if((sonparticles[i].X[j]-particles[i].X[j])>Vmax[j])//坐标保护                    particles[i].X[j] += Vmax[j];                else if((sonparticles[i].X[j]-particles[i].X[j])<-Vmax[j])                    particles[i].X[j] += -Vmax[j];                else                    particles[i].X[j] = sonparticles[i].X[j];                particles[i].V[j] = sonparticles[i].V[j];            }        }    }}

/******************************************************************************** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).** Contact: http://www.qt-project.org/legal**** This file is part of the examples of the Qt Toolkit.**** $QT_BEGIN_LICENSE:BSD$** You may use this file under the terms of the BSD license as follows:**** "Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions are** met:**   * Redistributions of source code must retain the above copyright**     notice, this list of conditions and the following disclaimer.**   * Redistributions in binary form must reproduce the above copyright**     notice, this list of conditions and the following disclaimer in**     the documentation and/or other materials provided with the**     distribution.**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names**     of its contributors may be used to endorse or promote products derived**     from this software without specific prior written permission.****** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."**** $QT_END_LICENSE$******************************************************************************/#include "mouse.h"#include <QGraphicsScene>#include <QPainter>#include <QStyleOption>#include <math.h>static const double Pi = 3.14159265358979323846264338327950288419717;static double TwoPi = 2.0 * Pi;static qreal normalizeAngle(qreal angle){    while (angle < 0)        angle += TwoPi;    while (angle > TwoPi)        angle -= TwoPi;    return angle;}//! [0]Mouse::Mouse()    : angle(0), speed(0), mouseEyeDirection(0),      color(qrand() % 256, qrand() % 256, qrand() % 256){    setRotation(qrand() % (360 * 16));}//! [0]//! [1]QRectF Mouse::boundingRect() const{    qreal adjust = 0.5;    return QRectF(-18 - adjust, -22 - adjust,                  36 + adjust, 60 + adjust);}//! [1]//! [2]QPainterPath Mouse::shape() const{    QPainterPath path;    path.addRect(-10, -20, 20, 40);    return path;}//! [2]//! [3]  //draw the mousevoid Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *){    // Body    painter->setBrush(color);    painter->drawEllipse(-10, -20, 20, 40);    // Eyes    painter->setBrush(Qt::white);    painter->drawEllipse(-10, -17, 8, 8);    painter->drawEllipse(2, -17, 8, 8);    // Nose    painter->setBrush(Qt::black);    painter->drawEllipse(QRectF(-2, -22, 4, 4));    // Pupils    painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));    painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));    // Ears    painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red);    painter->drawEllipse(-17, -12, 16, 16);    painter->drawEllipse(1, -12, 16, 16);    // Tail    QPainterPath path(QPointF(0, 20));    path.cubicTo(-5, 22, -5, 22, 0, 25);    path.cubicTo(5, 27, 5, 32, 0, 30);    path.cubicTo(-5, 32, -5, 42, 0, 35);    painter->setBrush(Qt::NoBrush);    painter->drawPath(path);}//! [3]//! [4]void Mouse::advance(int step){    if (!step)        return;//! [4]    // Don't move too far away//! [5]    QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0));    if (lineToCenter.length() > 150) {        qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length());        if (lineToCenter.dy() < 0)            angleToCenter = TwoPi - angleToCenter;        angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2);        if (angleToCenter < Pi && angleToCenter > Pi / 4) {            // Rotate left            angle += (angle < -Pi / 2) ? 0.25 : -0.25;        } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {            // Rotate right            angle += (angle < Pi / 2) ? 0.25 : -0.25;        }    } else if (::sin(angle) < 0) {        angle += 0.25;    } else if (::sin(angle) > 0) {        angle -= 0.25;//! [5] //! [6]    }//! [6]    // Try not to crash with any other mice//! [7]    QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF()                                                       << mapToScene(0, 0)                                                       << mapToScene(-30, -50)                                                       << mapToScene(30, -50));    foreach (QGraphicsItem *item, dangerMice) {        if (item == this)            continue;        QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0));        qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length());        if (lineToMouse.dy() < 0)            angleToMouse = TwoPi - angleToMouse;        angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2);        if (angleToMouse >= 0 && angleToMouse < Pi / 2) {            // Rotate right            angle += 0.5;        } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {            // Rotate left            angle -= 0.5;//! [7] //! [8]        }//! [8] //! [9]    }//! [9]    // Add some random movement//! [10]    if (dangerMice.size() > 1 && (qrand() % 10) == 0) {        if (qrand() % 1)            angle += (qrand() % 100) / 500.0;        else            angle -= (qrand() % 100) / 500.0;    }//! [10]//! [11]    speed += (-50 + qrand() % 100) / 100.0;    qreal dx = ::sin(angle) * 10;    mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5;    setRotation(rotation() + dx);    setPos(mapToParent(0, -(3 + sin(speed) * 3)));}//! [11]

#include "particle.h"MyParticle::MyParticle(){    iValid = 0;    Dim = 0;}MyParticle::MyParticle(int d){    iValid = 1;    Dim = d;    X = new double[Dim];    V = new double[Dim];    XBest = new double[Dim];}void MyParticle::InitParticle(int d){    iValid = 1;    Dim = d;    X = new double[Dim];    V = new double[Dim];    XBest = new double[Dim];}int MyParticle::GetDim(){    return Dim;}void MyParticle::SetDim(int dim){    Dim = dim ;}int MyParticle::IsValid(){    return iValid;}double MyParticle::GetFitness(){    return Fit;}void MyParticle::SetFit(double fit){    Fit = fit;}void MyParticle::SetFitBest(double fit){    FitBest = fit;}


演示结果



原创粉丝点击