Halcom 发表于 2021-11-13 16:38:52

教与学算法

TLBO.cpp
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include"roundx.h"
#include"KP01.h"
#include"maxValue.h"
#include"maxValueIndex.h"
#include"minValue.h"
#include"randi.h"

/* 教与学算法 */
#define sizepop 10      /* 表示种群数 */
#define maxiter 50   /* 进化次数 */
#define C 2.6         /* 背包载重*/
#define nvar 3          /* 3个变量 */

extern double v = { { 0.5, 0.4, 0.9 },
                                              { 0.4, 0.7, 1.1 },
                                              { 0.3, 0.7, 1.0 } };
extern double w = { { 0.6, 0.7, 0.8 },
                                                  { 0.7, 0.4, 0.8 },
                                              { 0.5, 0.6, 0.7 } };
void main(void)
{
        typedef long clock_t;
        clock_t start, finish;
        double duration;
        start = clock();//启动计时
        srand((unsigned int)time(NULL));//随机种子
        srand(time(0));// 初始化随机种子

        // 变量声明
        int pop = { 0 }, zbest = { 0 }, newpop = { 0 }, Mean = { 0 }, Teacher_pop = { 0 }, Step = {0};
        int popmin = { 1, 1, 1 };
        int popmax = { 3, 3, 3 };
        int S = 0, Smin = 0, Smax = 5, Exponent = 2;
        double sigma_initial = 0.5, sigma_final = 0.001;
        double fitness = { 0 }, newfitness = 0.0, Teacher_fitness = 0.0;
        double temp = 0.0, randk = 0.0;
        double bestfitness = 0.0, sigma = 0.0, BestCost = 0.0, WorstCost = 0.0, ratio = 0.0;
        int bestLoc = 0, bestLoc2 = 0, TF = 1;
        int xx = { 0 };

        // 初始化种群
        for (int i = 0; i < sizepop; i++)
        {
                for (int j = 0; j < nvar; j++)
                {
                        randk = double(rand()) / double(RAND_MAX); //0-1随机数
                        temp = (popmin + randk*(popmax - popmin));
                        pop = roundx(temp);
                }
                fitness = KPO1(pop);   // 适应度函数
        }
        // 记录一组最优值
        bestfitness = maxValue(fitness);
        bestLoc = maxValueIndex(fitness);
        memcpy(zbest, pop, 12); // 3个整型,12个字节

        // 迭代寻优
        for (int iter = 0; iter < maxiter; iter++)
        {
                // Calculate Population Mean
                for (int k = 0; k < nvar; k++)
                        Mean = 0;
                for (int k = 0; k < nvar; k++)
                {
                        for (int i = 0; i < sizepop; i++)
                        {
                                Mean = Mean + pop;
                        }
                        Mean = (int)(Mean / sizepop);
                }
                // Select Teacher
                Teacher_fitness = maxValue(fitness);
                bestLoc = maxValueIndex(fitness);
                memcpy(Teacher_pop, pop, 12); // 3个整型,12个字节

                // Teacher Phase
                for (int i = 0; i < sizepop; i++)
                {
                        TF = randi(1, 2);
                        // Teaching (moving towards teacher)
                        S = roundx(Smin + (Smax - Smin)*ratio);
                        for (int k = 0; k < nvar; k++)
                        {
                                randk = double(rand()) / double(RAND_MAX); //0-1随机数
                                newpop = roundx(pop + (Teacher_pop - TF*Mean)*randk);
                                // 局部搜索
                                if (iter>int(maxiter / 2))
                                {
                                        newpop = roundx(zbest + (Teacher_pop - TF*Mean)*randk);
                                }

                                if (newpop>popmax)
                                        newpop = popmax;
                                else if (newpop < popmin)
                                        newpop = popmin;
                        }
                        newfitness = KPO1(newpop);   // 适应度函数

                        if (newfitness>fitness)
                        {
                                fitness = newfitness;
                                memcpy(pop, newpop, 12); // 3个整型,12个字节
                        }
                        if (newfitness > bestfitness)
                        {
                                bestfitness = newfitness;
                                memcpy(zbest, newpop, 12); // 3个整型,12个字节
                        }
                }

                //printf("最优适应度值为: %lf\n", bestfitness);         // 输出显示
        }
        // Learner Phase
        for (int i = 0; i < sizepop; i++)
        {
                bestLoc = randi(1, sizepop);
                bestLoc2 = randi(1, sizepop);
                for (int k = 0; k < nvar; k++)
                {
                        Step = pop - pop;
                }
                if (fitness < fitness)
                {
                        for (int k = 0; k < nvar; k++)
                        {
                                Step = -Step;
                        }
                }
                for (int k = 0; k < nvar; k++)
                {
                        // 交叉
                        newpop = 0.5*pop + 0.5*pop;
                        // 变异
                        randk = double(rand()) / double(RAND_MAX); //0-1随机数
                        if (randk>0.5)
                        {
                                newpop = roundx(pop + randk*Step);
                        }       
                }
                newfitness = KPO1(newpop);   // 适应度函数

                if (newfitness>fitness)
                {
                        fitness = newfitness;
                        memcpy(pop, newpop, 12); // 3个整型,12个字节
                }
                if (newfitness > bestfitness)
                {
                        bestfitness = newfitness;
                        memcpy(zbest, newpop, 12); // 3个整型,12个字节
                }

                printf("最优适应度值为: %lf\n", bestfitness);         // 输出显示
        }

        printf("\n");         // 输出显示

        // 最终的解
        printf("最终的解为: \n");         // 输出显示
        for (int i = 0; i < nvar; i++)
        {
                if (zbest == 1)
                        xx = 1;
                else if (zbest == 2)
                        xx = 1;
                else if (zbest == 3)
                        xx = 1;
                printf("%d\t %d\t %d\n", xx, xx, xx);   // C0-C4输出显示
        }

        printf("\n");         // 输出显示
        system("pause");    // 消除屏幕一闪即消失的情况
}roundx.cpp
#include<stdio.h>
#include<math.h>

int roundx(double x)
{
        int x1 = (int)x;
        if (x - x1 >= 0.5)
                return x1 + 1;
        else
                return x1;
}randi.cpp
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include"roundx.h"

// 函数目的:随机产生在某个区间的整数
int randi(int a, int b)
{
        typedef long clock_t;
        clock_t start, finish;
        double duration;
        start = clock();//启动计时
        srand((unsigned int)time(NULL));//随机种子
        srand(time(0));// 初始化随机种子

        double randk = double(rand()) / double(RAND_MAX); //0-1随机数
        return roundx(a + (b - a)*randk);
}minValue.cpp
#include<stdio.h>
#include<math.h>
// 函数目的:求解最小值
#define sizepop 50      /* 表示种群数 */
double minValue(double x)
{
        double temp = 100000.0;
        for (int i = 0; i < sizepop; i++)
        {
                if (x<temp)
                        temp = x;
        }
        return temp;
}maxValueIndex.cpp
#include<stdio.h>
#include<math.h>
// 函数目的:求解最大值对应的索引
#define sizepop 50      /* 表示种群数 */
int maxValueIndex(double x)
{
        int index = 0;
        double temp = 0.0;
        for (int i = 0; i < sizepop; i++)
        {
                if (x>temp)
                {
                        temp = x;
                        index = i;
                }
        }
        return index;
}maxValue.cpp
#include<stdio.h>
#include<math.h>
// 函数目的:求解最大值
#define sizepop 50      /* 表示种群数 */
double maxValue(double x)
{
        double temp = 0.0;
        for (int i = 0; i < sizepop; i++)
        {
                if (x>temp)
                        temp = x;
        }
        return temp;
}目标函数:
#include<stdio.h>
#include<math.h>
/* 适应度函数 */
/*全局变量*/
#define C 2.6         /* 背包载重*/
#define nvar 3          /* 3个变量 */
extern double v, w;

double KPO1(int *x)
{
        int i = 0, j = 0;
        double xw = 0, xv = 0;
        int xx = {0};
        for (i = 0; i < nvar; i++)
        {
                if (x == 1)
                        xx = 1;
                else if (x == 2)
                        xx = 1;
                else if (x == 3)
                        xx = 1;
        }
        for (i = 0; i < nvar; i++)
        {
                for (j = 0; j < nvar; j++)
                {
                        xw = xw + xx * w;
                        xv = xv + xx * v;
                }
        }
        if (xw <= C)
                return xv;
        else
                return -1;
}




















Halcom 发表于 2021-11-13 16:41:01

roundx.h
#ifndef _ROUNDX_H_
#define _ROUNDX_H_

int roundx(double x);

#endifminValue.h
#ifndef _MINVALUE_H_
#define _MINVALUE_H_

#define sizepop 50      /* 表示种群数 */
double minValue(double x);

#endif
maxValue.h
#ifndef _MAXVALUE_H_
#define _MAXVALUE_H_

#define sizepop 50      /* 表示种群数 */
double maxValue(double x);

#endif
其余
KP01.h、maxValueIndex.h、randi.h同理









Halcom 发表于 2021-11-13 16:41:50

目标函数的matlab代码如下:
% 适应度函数
CostFunction = @(x) KP01(x);% 目标函数Objective Function
nvar = 3;         % 变量个数
popmin = ;       % Lower Bound of Decision Variables
popmax = ;      % Upper Bound of Decision Variables
maxiter=100;       % 最大迭代次数
sizepop = 50;      % 最大种群数量
function = KP01(x)
C = 2.6;
v = [0.5      0.4      0.9
    0.4      0.7      1.1
    0.3      0.7      1.0];
w = [0.6      0.7      0.8
    0.7      0.4      0.8
    0.5      0.6      0.7];
xx = zeros(size(v));
for i=1:length(x)
    if x(i)==1
      xx(i,1) = 1;
    elseif(x(i)==2)
      xx(i,2) = 1;
    elseif(x(i)==3)
      xx(i,3) = 1;
    end
end
if(sum(sum(xx.*w))<=C)
    fitness = sum(sum(xx.*v));
else
    fitness = -1;
end

Halcom 发表于 2021-11-14 16:50:00

bilibili视频观察代码运行效果:
https://www.bilibili.com/video/BV12L4y1v7NK/
页: [1]
查看完整版本: 教与学算法