模拟退火——leetcode

本文深入探讨了模拟退火算法在解决复杂优化问题中的应用,包括任务分配、位置选择及字符串匹配等。通过多个实际案例,如LeetCode上的具体题目,展示了如何利用模拟退火算法寻找最优解。

1815. 得到新鲜甜甜圈的最多组数 - 力扣(LeetCode)

class Solution {
   
   
public:
    int batchSize;
    int n;
    int ans = 0;
    vector<int> groups;
    int energy()
    {
   
   
        int res = 1;
        for (int i = 0, s = 0; i < n; i ++ ) {
   
   //计算是否有剩余
            s = (s + groups[i]) % batchSize;
            if (!s && i < n - 1) res ++ ;
        }
        ans = max(ans, res);
        return -res;
    }
    void th()
    {
   
   
        srand(time(NULL));//很重要
        random_shuffle(groups.begin(), groups.end());
        for(double t = 1e6; t > 1e-6; t *= 0.96)
        {
   
   
            int a = rand() % n, b = rand() % n;
            int ea = energy();
            swap(groups[a], groups[b]);
            int eb = energy();
            int dt = eb - ea;
            if(exp(-dt / t) > (double)rand() / RAND_MAX) continue;
            swap(groups[a], groups[b]);
        }
    }
    int maxHappyGroups(int _batchSize, vector<int>& _groups) {
   
   
        //调整groups的顺序,使最多人开心
        batchSize = _batchSize;
        groups = _groups;
        n = groups.size();
        for(int i = 0; i < 40; i ++ )
        th();
        return ans;
    }
};

1723. 完成所有工作的最短时间 - 力扣(LeetCode)

class Solution {
   
   
public:
    int ans = INT_MAX;
    vector<int> jobs;
    int energy(int k)
    {
   
   
        int n = jobs.size();
        vector<int> s(k);
        for(int i = 0; i < n; i ++ )//对于每项工作,找到一个最闲的工人分配
        {
   
   
            int kk = 0;
            for(int j = 1; j < k; j ++ )
                if(s[j] < s[kk]) kk = j;
            s[kk] += jobs[i];
        }
        int res = 0;
        for(auto &x : s)
            res = max(x, res);//找到最大工作时间
        ans = min(ans, res);
        return res; //能量越小越好 
    }
    void th(int k)
    {
   
   
        int n = jobs.size();
        double T = 10000;//一个很高的温度
        random_shuffle(jobs.begin(), jobs.end(
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值