MATLAB初学者入门(11)—— 贪心算法

        贪心算法是一种简单直观的算法设计方法,常用于解决需要做出一系列选择以达到最优解的问题。贪心算法的核心思想是每一步都选择当前看起来最好的选项,而不考虑大局。这种方法通常易于实现,但不总是能得到全局最优解。下面,将详细介绍如何在MATLAB中实现贪心算法。

案例分析:分数背包问题

        假设你是一个小偷,打算抢劫一个商店。你有一个可以承载限定重量的背包,商店里有多种物品,每种物品都有其重量和价值,你可以拿走整个物品或者物品的一部分。目标是在不超过背包承重的情况下,最大化背包中物品的总价值。

步骤 1: 定义物品和背包

        首先定义各个物品的重量和价值,以及背包的最大承重。

weights = [10, 20, 30];  % 各物品的重量
values = [60, 100, 120];  % 各物品的价值
capacity = 50;  % 背包的最大承重
步骤 2: 计算价格与重量的比率

        为了应用贪心策略,我们需要计算每个物品单位重量的价值(即价值与重量的比率),并按此比率降序排序物品。

% 计算单位重量的价值并排序
[valuePerWeight, indices] = sort(values ./ weights, 'descend');
sortedWeights = weights(indices);
sortedValues = values(indices);
步骤 3: 贪心算法选择物品

        遍历排序后的物品列表,尽可能多地取每种物品,直到背包装不下为止。

totalValue = 0;
remainingCapacity = capacity;

for i = 1:length(sortedWeights)
    if remainingCapacity == 0
        break;
    end
    if sortedWeights(i) <= remainingCapacity
        % 如果当前物品可以完全装入背包
        totalValue = totalValue + sortedValues(i);
        remainingCapacity = remainingCapacity - sortedWeights(i);
    else
        % 如果当前物品只能装入一部分
        totalValue = totalValue + valuePerWeight(i) * remainingCapacity;
        break;
    end
end
步骤 4: 输出结果

        显示背包中物品的总价值。

disp(['Total value in the knapsack: ', num2str(totalValue)]);

案例分析:最小生成树的贪心算法——Kruskal算法

        Kruskal算法是解决最小生成树问题的一种贪心算法。该算法按照边的权重(成本)顺序,从最小的开始选择,只要这条边不会与已选择的边形成环。

步骤 1: 定义图

        首先定义图的节点和边,以及每条边的权重。

% 示例数据 - 每个元素表示一条边和其两个节点和权重
edges = [1 2 7; 1 3 5; 2 3 9; 2 4 8; 2 5 7; 3 4 15; 3 5 6; 4 5 8; 4 6 9; 5 6 11];
% 边由其两个端点和权重组成
步骤 2: 对边按权重排序

        为了应用贪心策略,我们需要按边的权重升序排序。

% 按权重排序边
[sortedEdges, index] = sortrows(edges, 3);
步骤 3: 使用Kruskal算法构建最小生成树

        使用并查集数据结构来检测环。

% 初始化并查集
numNodes = max(max(edges(:,1:2)));  % 获取节点数
parent = 1:numNodes;

% 查找根节点函数
function p = find(parent, i)
    while parent(i) ~= i
        i = parent(i);
    end
    p = i;
end

% 并查集合并函数
function parent = union(parent, x, y)
    rootX = find(parent, x);
    rootY = find(parent, y);
    if rootX ~= rootY
        parent(rootY) = rootX;
    end
end

% Kruskal主算法
mst = [];  % 存储MST中的边
for i = 1:size(sortedEdges, 1)
    if find(parent, sortedEdges(i, 1)) ~= find(parent, sortedEdges(i, 2))
        mst = [mst; sortedEdges(i, :)];  % 添加边到MST
        parent = union(parent, sortedEdges(i, 1), sortedEdges(i, 2));
    end
end
步骤 4: 输出最小生成树和总成本

        显示构建的最小生成树和其总权重。

disp('Edges in the Minimum Spanning Tree:');
disp(mst);
totalCost = sum(mst(:,3));
disp(['Total cost of the Minimum Spanning Tree: ', num2str(totalCost)]);

案例分析:活动选择问题

        假设你有多个活动,每个活动都有一个开始时间和结束时间。任务是选择最大集合的相互兼容活动(即它们不重叠)。这是一个典型的贪心算法应用场景,通常通过选择结束时间最早的活动来实现。

步骤 1: 定义活动

        首先定义一组活动及其开始和结束时间。

% 示例数据:每行一个活动,第一列为开始时间,第二列为结束时间
activities = [
    1, 4;
    3, 5;
    0, 6;
    5, 7;
    3, 9;
    5, 9;
    6, 10;
    8, 11;
    8, 12;
    2, 14;
    12, 16;
];

% 对活动按结束时间排序
sortedActivities = sortrows(activities, 2);
步骤 2: 应用贪心策略选择活动

        选择结束时间最早的活动,然后选择下一个与已选择活动不冲突的结束时间最早的活动。

% 选择活动
selectedActivities = [];
lastEndTime = -inf;

for i = 1:size(sortedActivities, 1)
    if sortedActivities(i, 1) >= lastEndTime
        selectedActivities = [selectedActivities; sortedActivities(i, :)];
        lastEndTime = sortedActivities(i, 2);
    end
end
步骤 3: 输出结果

        展示选定的活动以及总数。

disp('Selected activities (start time, end time):');
disp(selectedActivities);
disp(['Total number of selected activities: ', num2str(size(selectedActivities, 1))]);

结论

(1)在这个分数背包问题的例子中,贪心算法提供了一种有效的方法来快速求解,并通常能得到非常接近最优解的结果。此案例显示了贪心算法在解决优化问题中的实用性,特别是当问题允许采取“分数解”时,贪心策略特别有效。
        贪心算法虽然简单且易于实现,但它有时可能不会提供一个全局最优解,特别是在要求得到全局最优解的问题中。因此,在应用贪心算法时,需要仔细考虑问题的特性和对解的要求。在一些问题中,可能还需要与其他算法(如动态规划或回溯算法)结合使用,以达到更好的效果。

(2)通过此案例,Kruskal算法成功解决了最小生成树问题,展示了贪心算法在网络设计和优化中的实用性。此算法不仅适用于电信或计算机网络的设计,还广泛应用于其他需要高效连接多个点的场景,如交通规划、供电网络等。Kruskal算法以其简单和高效的特点,在工程和科学计算中非常有用。此外,MATLAB提供的矩阵和数组操作功能使得实现此类算法变得直接和高效。

(3)在这个活动选择问题中,我们利用贪心算法成功地选择了最大数量的互不冲突的活动。此案例表明贪心算法在解决调度和规划问题中的高效性,特别是在需要做出一系列优化选择时。贪心策略通常简单易实现,且在许多情况下可以提供最优或接近最优的解决方案。此外,由于算法的直观性和效率,它广泛应用于实时系统和其他需要快速决策的应用中。
        此类贪心算法不仅适用于会议或活动安排,也可以扩展到资源分配、工作调度等其他领域,为这些领域中的优化问题提供了有效的解决策略。通过探索和实施这些策略,可以优化决策过程,提高系统的整体效率和效果。

贪心算法是一种求解最优化问题的算法,它以局部最优解为基础,通过不断地做出贪心选择来达到全局最优解。引用提到了贪心算法的基本原理、性质以及一些例子,而引用则给出了贪心算法的基本步骤和MATLAB实现的例子。 贪心算法的基本步骤包括以下几个方面: 1. 确定问题的最优化目标和约束条件。 2. 根据问题的特点和属性,选择合适的贪心策略,即每一步都选择当前最优解。 3. 通过贪心选择,逐步构建问题的解,并更新问题的状态。 4. 判断是否达到最优解或满足约束条件,如果是,则结束算法;如果不是,则继续执行贪心选择步骤。 5. 最后,得到问题的最优解或近似最优解。 贪心算法MATLAB中的实现可以根据具体问题的特点进行编写,可以使用循环、条件判断等基本语法结构来实现贪心策略的选择和更新。 需要注意的是,虽然贪心算法在一些问题上可以得到最优解或接近最优解,但并不是所有问题都适合使用贪心算法。引用指出,贪心法一般不能解决一些特定问题,而且选择最优解可能会导致辛普森悖论。因此,在应用贪心算法时,需要结合具体问题进行分析和判断,确保贪心算法能够得到符合要求的结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [贪心算法-MATLAB实现](https://blog.csdn.net/qq_62277772/article/details/128353211)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Matlab-贪心/贪婪算法](https://blog.csdn.net/weixin_41008284/article/details/108659604)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贾贾乾杯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值