基于遗传算法和粒子群算法的混合算法实现小老鼠找奶酪问题
来源:互联网 发布:服务器域名根目录 编辑:程序博客网 时间: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;}
演示结果
- 基于遗传算法和粒子群算法的混合算法实现小老鼠找奶酪问题
- 粒子群算法(8)---混合粒子群算法的实现
- 粒子群算法(8)---混合粒子群算法的实现
- 混合粒子群算法的实现
- 基于Matlab的粒子群算法实现
- 【神经网络学习笔记】粒子群算法和遗传算法比较
- 从遗传算法、粒子群算法、模拟退火算法理解启发式算法优化的本质
- 遗传蚁群粒子群算法原理
- 粒子群优化算法与遗传脚本
- 粒子群算法(5)-----标准粒子群算法的实现
- 粒子群算法(5)-----标准粒子群算法的实现
- 粒子群算法(5)-----标准粒子群算法的实现
- 进化算法、遗传算法与粒子群算法之间的比较
- 进化算法 遗传算法与粒子群算法之间的比较
- 进化算法、遗传算法与粒子群算法之间的比较
- 旅行销售员问题的遗传算法实现
- 旅行销售员问题的遗传算法实现
- TSP问题的遗传算法实现
- 快乐编程的好习惯
- Android Matrix理论与使用详解
- 对treeMap的value 排序
- mime type与content type
- 拓展--求四个最大公约数
- 基于遗传算法和粒子群算法的混合算法实现小老鼠找奶酪问题
- uva 11991 - Easy Problem from Rujia Liu?
- SEO必须搞懂这几个问题
- 采用标准工具备份与恢复数据
- Ext.Net Status text: transaction aborted
- poll2
- Android使用adb指令在虚拟机中安装、卸载apk程序
- Error:No suitable device found: no device found for connection "System eth1" .
- Android Matrix理论与使用详解