【CUPK小学期】笔记5:局部最优搜索-课后习题

叙述局部最优搜索的特点

  1. 局部搜索:局部最优搜索算法只关注当前解的邻域内的解,通过在邻域内搜索来逐步逼近最优解。它不会全局搜索整个解空间,因此只能找到局部最优解,而不能保证找到全局最优解。

  2. 迭代优化:局部最优搜索是一个迭代的过程,通过不断地更新当前解,逐步寻找更优的解。每一次迭代都会生成一个邻域解,并根据一定的评估准则来判断是否更新当前解。通过多次迭代,可以逐步逼近最优解。

  3. 邻域搜索:局部最优搜索算法通过定义邻域函数来生成当前解的邻域解。邻域解是在当前解的基础上进行微小的变动得到的。通过搜索邻域内的解,可以探索解空间中的局部结构,找到更优的解。

  4. 依赖初始解:局部最优搜索算法的初始解对最终结果有影响。不同的初始解可能会导致不同的局部最优解。因此,在应用局部最优搜索算法时,需要选择一个合适的初始解。

  5. 可能陷入局部最优解:由于局部最优搜索只关注局部解,存在可能陷入局部最优解的问题。如果解空间中存在多个局部最优解,局部最优搜索算法可能会停留在其中一个局部最优解而无法跳出。为了解决这个问题,可以使用一些改进策略,如引入随机性、多次运行算法等。

解释显式图和隐式图 

显式图和隐式图是数据结构中常用的两种图的表示方法。

显式图是通过使用图的顶点集合和边集合来表示图结构的一种方法。具体来说,我们可以使用数组或链表来存储顶点集合和边集合,其中每个顶点都有一个唯一的标识符,而每条边都连接两个顶点。这种表示方法可以直观地展现图的结构,方便我们对图进行遍历和操作。

隐式图是通过使用某种特定的规则或算法来生成图的结构的一种方法。与显式图不同,隐式图不需要使用额外的数据结构来存储图的顶点和边,而是根据规则或算法来判断图中的顶点和边的关系。这种表示方法适用于某些特殊的图,例如迷宫、棋盘等。在这些情况下,我们可以根据规则或算法生成图的结构,并通过相应的算法来进行图的遍历和操作。

下面是用C语言代码举例的显式图和隐式图表示方法:

// 显式图的表示方法

// 定义图的最大顶点数
#define MAX_VERTICES 100

// 定义图的顶点结构体
typedef struct {
    int id;
    // 其他属性...
} Vertex;

// 定义图的边结构体
typedef struct {
    int source;
    int target;
    // 其他属性...
} Edge;

// 定义图结构体
typedef struct {
    Vertex vertices[MAX_VERTICES];
    Edge edges[MAX_VERTICES];
    int numVertices;
    int numEdges;
} Graph;

// 隐式图的表示方法

// 定义迷宫的大小
#define MAZE_SIZE 10

// 定义迷宫的结构体
typedef struct {
    int maze[MAZE_SIZE][MAZE_SIZE];
    // 其他属性...
} Maze;

// 生成迷宫的函数
void generateMaze(Maze* maze) {
    // 根据规则生成迷宫的结构
    // ...
}

// 遍历迷宫的函数
void traverseMaze(Maze* maze) {
    // 根据算法遍历迷宫
    // ...
}

完成以下程序 

void priTraPath(TRAVELPATH trapath)   //显示旅行商路径
void priNeighbors(TRAVELPATH *neighbors)   //显示所有派生路径
#include <stdio.h>

// 定义旅行商路径的结构体
typedef struct {
    int path[100]; // 旅行路径数组
    int length; // 路径长度
} TRAVELPATH;

// 显示旅行商路径
void priTraPath(TRAVELPATH trapath) {
    int i;
    printf("Travel Path: ");
    for (i = 0; i < trapath.length; i++) {
        printf("%d ", trapath.path[i]);
    }
    printf("\nPath Length: %d\n", trapath.length);
}

// 显示所有派生路径
void priNeighbors(TRAVELPATH *neighbors) {
    int i, j;
    printf("Neighbors:\n");
    for (i = 0; i < 10; i++) {
        printf("Neighbor %d: ", i+1);
        for (j = 0; j < neighbors[i].length; j++) {
            printf("%d ", neighbors[i].path[j]);
        }
        printf("\n");
    }
}

int main() {
    TRAVELPATH trapath = {{1, 2, 3, 4, 5}, 5}; // 示例旅行商路径
    
    priTraPath(trapath);
    
    TRAVELPATH neighbors[10]; // 示例派生路径数组
    
    // 初始化派生路径数组
    int i, j;
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 5; j++) {
            neighbors[i].path[j] = (i+1) * (j+1);
        }
        neighbors[i].length = 5;
    }
    
    priNeighbors(neighbors);
    
    return 0;
}

设计多元多峰函数,求解全局最优值 

#include <stdio.h>
#include <math.h>

#define NUM_DIMENSIONS 2

typedef struct {
    double x[NUM_DIMENSIONS];
} Point;

double multimodalFunction(Point p) {
    // 这里是多元多峰函数的计算逻辑
    double result = pow(p.x[0], 2) + pow(p.x[1], 2);
    result += sin(5 * p.x[0]) * sin(5 * p.x[1]);
    result += 2 * sin(10 * p.x[0]) * sin(10 * p.x[1]);
    return result;
}

Point getRandomPoint(double minX, double maxX, double minY, double maxY) {
    Point p;
    p.x[0] = (double) rand() / RAND_MAX * (maxX - minX) + minX;
    p.x[1] = (double) rand() / RAND_MAX * (maxY - minY) + minY;
    return p;
}

Point getRandomNeighbor(Point p, double stepSize) {
    Point neighbor;
    neighbor.x[0] = p.x[0] + (double) rand() / RAND_MAX * stepSize - stepSize / 2;
    neighbor.x[1] = p.x[1] + (double) rand() / RAND_MAX * stepSize - stepSize / 2;
    return neighbor;
}

double searchGlobalOptimum(double minX, double maxX, double minY, double maxY, double stepSize, int numIterations) {
    Point currentPoint = getRandomPoint(minX, maxX, minY, maxY);
    double currentBestValue = multimodalFunction(currentPoint);

    for (int i = 0; i < numIterations; i++) {
        Point neighbor = getRandomNeighbor(currentPoint, stepSize);
        double neighborValue = multimodalFunction(neighbor);

        if (neighborValue < currentBestValue) {
            currentPoint = neighbor;
            currentBestValue = neighborValue;
        }
    }

    return currentBestValue;
}

int main() {
    double minX = -10.0;
    double maxX = 10.0;
    double minY = -10.0;
    double maxY = 10.0;
    double stepSize = 0.1;
    int numIterations = 10000;

    double globalOptimum = searchGlobalOptimum(minX, maxX, minY, maxY, stepSize, numIterations);
    printf("Global Optimum: %lf\n", globalOptimum);

    return 0;
}

0-1背包问题:设容积为V的背包中有n个体积分别为ai(i=1,2,...,n)的物体,价值分别为ci,如何确保装进包内的物体具有最大价值?如V=10,物体a,b,c,d,e的体积分别为2,2,6,5,4,对应价值为6,3,5,4,6,求解装进包内哪些物体时价值最大?

#include <stdio.h>
#include <stdlib.h>

#define MAX_ITEMS 100 // 最大物品数量
#define MAX_VOLUME 100 // 最大背包容积

typedef struct {
    int volume; // 物品体积
    int value; // 物品价值
} Item;

int max(int a, int b) {
    return (a > b) ? a : b;
}

int knapsack(int V, Item items[], int n) {
    int dp[MAX_ITEMS][MAX_VOLUME+1]; // 动态规划数组

    // 初始化第一行和第一列为0
    for (int i = 0; i <= n; i++) {
        dp[i][0] = 0;
    }
    for (int j = 0; j <= V; j++) {
        dp[0][j] = 0;
    }

    // 填充动态规划数组
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= V; j++) {
            if (items[i-1].volume <= j) {
                dp[i][j] = max(dp[i-1][j], items[i-1].value + dp[i-1][j-items[i-1].volume]);
            } else {
                dp[i][j] = dp[i-1][j];
            }
        }
    }

    // 返回最大价值
    return dp[n][V];
}

int main() {
    int V = 10; // 背包容积
    Item items[] = {{2, 6}, {2, 3}, {6, 5}, {5, 4}, {4, 6}}; // 物品数组
    int n = sizeof(items) / sizeof(items[0]); // 物品数量

    int maxValue = knapsack(V, items, n);
    printf("Maximum value: %d\n", maxValue);

    return 0;
}

 采用递归思想实现局部最优搜索

#include <stdio.h>
#include <stdlib.h>

#define MAX_CITIES 10 // 最大城市数量

typedef struct {
    int cities[MAX_CITIES]; // 城市编号数组
    int numCities; // 城市数量
    int cost; // 路径长度
} TRAVELPATH;

void priTraPath(TRAVELPATH trapath) {
    printf("Travel Path: ");
    for (int i = 0; i < trapath.numCities; i++) {
        printf("%d ", trapath.cities[i]);
    }
    printf("\n");
    printf("Cost: %d\n", trapath.cost);
}

void priNeighbors(TRAVELPATH *neighbors) {
    printf("Neighbors:\n");
    for (int i = 0; i < neighbors->numCities; i++) {
        printf("Neighbor %d: ", i+1);
        for (int j = 0; j < neighbors[i].numCities; j++) {
            printf("%d ", neighbors[i].cities[j]);
        }
        printf("\n");
        printf("Cost: %d\n", neighbors[i].cost);
    }
}

// 局部最优搜索函数
void localOptimalSearch(TRAVELPATH currentPath) {
    // 判断是否到达目标状态(所有城市都已经访问过)
    if (currentPath.numCities == MAX_CITIES) {
        priTraPath(currentPath);
        return;
    }

    // 生成所有派生路径
    TRAVELPATH neighbors[MAX_CITIES];
    for (int i = 1; i <= MAX_CITIES; i++) {
        int isVisited = 0;
        for (int j = 0; j < currentPath.numCities; j++) {
            if (currentPath.cities[j] == i) {
                isVisited = 1;
                break;
            }
        }

        if (!isVisited) {
            neighbors[currentPath.numCities] = currentPath;
            neighbors[currentPath.numCities].cities[currentPath.numCities] = i;
            neighbors[currentPath.numCities].numCities++;
            neighbors[currentPath.numCities].cost += i;

            currentPath.numCities++;
            currentPath.cost += i;
            localOptimalSearch(currentPath);
            currentPath.numCities--;
            currentPath.cost -= i;
        }
    }

    // 打印所有派生路径
    priNeighbors(neighbors);
}

int main() {
    TRAVELPATH currentPath = {{1}, 1, 1};
    localOptimalSearch(currentPath);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值