算法上机3(背包问题(贪心算法),最小生成树(普里姆算法))

本文介绍了如何使用贪心算法中的快速排序和求解背包问题的knapsack_greedy函数,以及普里姆算法实现最小生成树的Prim函数,通过C语言代码展示了这两个经典算法的应用。
摘要由CSDN通过智能技术生成
  1. 背包问题(贪心算法)

#include<stdio.h>

#include<stdlib.h>

typedef struct {

    float w;

    float p;

    float v;

} OBJECT;

void swap(OBJECT *a, OBJECT *b) {

    OBJECT temp = *a;

    *a = *b;

    *b = temp;

}

int partition(OBJECT instance[], int low, int high) {

    OBJECT pivot = instance[high];

    int i = low - 1;

    for (int j = low; j <= high - 1; j++) {

        if (instance[j].v > pivot.v) {

            i++;

            swap(&instance[i], &instance[j]);

        }

    }

    swap(&instance[i + 1], &instance[high]);

    return i + 1;

}

void quick_sort(OBJECT instance[], int n) {

    int low = 0;

    int high = n - 1;

    while (low < high) {

        int pi = partition(instance, low, high);

        if (pi - low < high - pi) {

            low = pi + 1;

        } else {

            high = pi - 1;

        }

    }

}

float knapsack_greedy(float M, OBJECT instance[], float x[], int n) {

    int i;

    float m, p = 0;

    for (i = 0; i < n; i++) {

        instance[i].v = instance[i].p / instance[i].w; // 计算价值比并存储回结构体数组

        x[i] = 0;

    }

    quick_sort(instance, n);

    m = M;

    for (i = 0; i < n; i++) {

        if (instance[i].w <= m) {

            x[i] = 1;

            m = m - instance[i].w;

            p = p + instance[i].p;

        } else {

            x[i] = m / instance[i].w;

            p = p + x[i] * instance[i].p;

            break;

        }

    }

    return p;

}

int main() {

    float M = 50;

    OBJECT instance[] = {{20, 60}, {30, 120}, {10, 50}};

    int n = sizeof(instance) / sizeof(instance[0]);

    float x[n];

    float max_value = knapsack_greedy(M, instance, x, n);

    printf("最大价值为: %.2f", max_value);

    printf("选择的物品为: ");

    for (int i = 0; i < n; i++) {

        if (x[i] == 1) {

            printf("物品%d ", i + 1);

        }

    }

    printf("");

    return 0;

}

2.最小生成树(普里姆算法)

#include <stdio.h>

#include <stdbool.h>

#include <limits.h>

#define MAX_FLOAT_NUM 3.14e38

#define EDGE_NUM 100

typedef struct {

    int u, v;

    float key;

} EDGENT;

void prim(float c[][EDGE_NUM], int n, EDGENT T[], int &k) {

    int i, j, u;

    bool *s = new bool[n];

    int *neig = new int[n];

    float min, *w = new float[n];

    s[0] = true;

    for (i = 1; i < n; i++) {

        w[i] = c[0][i];

        neig[i] = 0;

        s[i] = false;

    }

    k = 0;

    for (i = 1; i < n; i++) {

        u = 0;

        min = MAX_FLOAT_NUM;

        for (j = 1; j < n; j++)

            if (!s[j] && w[j] < min) {

                u = j;

                min = w[j];

            }

        if (u == 0)

            break;

        T[k].u = neig[u];

        T[k].v = u;

        T[k++].key = w[u];

        s[u] = true;

        for (j = 1; j < n; j++) {

            if (!s[j] && c[u][j] < w[j]) {

                w[j] = c[u][j];

                neig[j] = u;

            }

        }

    }

    delete[] s;

    delete[] w;

    delete[] neig;

}

int main() {

    int n = 5;

    float c[][EDGE_NUM] = {

        {0, 2, 0, 6, 0},

        {2, 0, 3, 8, 5},

        {0, 3, 0, 0, 7},

        {6, 8, 0, 0, 9},

        {0, 5, 7, 9, 0},

    };

    EDGENT T[EDGE_NUM];

    int k;

    prim(c, n, T, k);

    for (int i = 0; i < k; i++) {

        printf("Edge %d: (%d, %d), weight: %f", i + 1, T[i].u, T[i].v, T[i].key);

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值