Gym 101142G Gangsters in Central City【思维+Lca】

本文探讨了一种树状供水网络模型,通过计算最少卡住的节点数来阻止强盗占领的房子获取水源,并确保未被占领房子的供水最小损失。采用深度优先搜索、最近公共祖先算法和区间最小值查询等技术实现策略调整。

题意:

  • 给一棵树,叶子节点为房子,q次操作,节点1为根节点(蓄水池)向房子供水
  • 每次操作有两种类型,+ x 强盗占领了编号为x的房子,- x强盗离开了编号为x的房子。
  • 对每次操作,ans1计算出最少卡住几个节点使得强盗占领的房子都没水喝,ans2卡住这些点后没有被强盗占领的房子通不了水的数量最小,每次输出这两个数

思路:

  • 对根节点,如果有k个直接连接的点,拆成k棵子树。每棵有强盗占领的子树肯定最多只需要卡住一个点,那ans1就是k个子树中有强盗的的子树数量。
  • 对每棵子树求出被强盗占领的点dfs序最大的和最小的两个点的lca就是这棵子树中被强盗占领的所有的点的lca。处理出每个节点下有多少个房子(sz[i]),那么求出lca后,先减去没进行这次操作前这个子树的贡献,然后再加上这个操作,求出这颗子树上的点的lca,再加上这棵子树的贡献。ans2=sz[lca]-强盗占领的点

代码:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t) for(int i=(s);i<(t);++i)
#define per(i,s,t) for(int i=((t)-1);i>=(s);--i)
#define pb push_back
#define dd(x) cout<<#x<<'='<<x<<' '
#define de(x) cout<<#x<<'='<<x<<'\n'
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int N=1e6+5;
int dp[N][20],n;
vi G[N];
set<int>st[N]; //维护第i棵子树中的dfs序
int tot,ver[N*2],R[N*2],First[N*2],bel[N],sz[N],cut[N];
 //cut[i] 第i棵子树中强盗占领的房子数量 
//bel[i],节点i属于那棵子数
// First[u] u节点的在ver中第一次出现的下标,即dfs序
bool vis[N];
void dfs(int u,int dep){
    vis[u]=true;ver[++tot]=u;First[u]=tot;R[tot]=dep;
    rep(i,0,G[u].size()){
        int v=G[u][i];
        if(!vis[v]){
            dfs(v,dep+1);
            ver[++tot]=u;
            R[tot]=dep;
        }
    }
}
void ST(){
    rep(i,1,tot+1){
        dp[i][0]=i;
    }
    for(int j=1;(1<<j)<=tot;++j){
        for(int i=1;i+(1<<j)-1<=tot;++i){
            int a=dp[i][j-1];http://codeforces.com/group/aUVPeyEnI2/contest/229510/attachments
            int b=dp[i+(1<<(j-1))][j-1];
            if(R[a]<R[b])dp[i][j]=a;
            else dp[i][j]=b;
        }
    }
}
int RMQ(int l,int r){
    int k=0;
    while(1<<(k+1)<=r-l+1){
        k++;
    }
    int a=dp[l][k],b=dp[r-(1<<k)+1][k];
    return R[a]<R[b]?a:b;
}
int LCA(int u,int v){
    int res=RMQ(u,v);
    return ver[res];
}
void Dfs(int u,int rt){
    bel[u]=rt;
    vis[u]=true;
    if(G[u].size())sz[u]=0;
    else sz[u]=1;
    rep(i,0,G[u].size()){
        int v=G[u][i];
        if(!vis[v]){
            Dfs(v,rt);
            sz[u]+=sz[v];
        }
    }
}
int main()
{
    tot=0;
    memset(vis,0,sizeof(vis));
    memset(sz,0,sizeof(sz));
    int q,p;
    scanf("%d%d",&n,&q);
    rep(i,2,n+1){
        scanf("%d",&p);
        G[p].pb(i);
    }
    dfs(1,1);
    ST();
    memset(vis,0,sizeof(vis));
    rep(i,0,G[1].size()){
        Dfs(G[1][i],i+1);
    }
    int ans1=0,ans2=0;
    char op[10];
    int x,fa,mi,ma,lca;
    while(q--){
          scanf("%s%d",op,&x);
          if(op[0]=='+'){
                fa=bel[x];
                if(cut[fa]){
                    mi=*st[fa].begin(),ma=*st[fa].rbegin();
                    lca=LCA(mi,ma);
                    ans2-=sz[lca]-cut[fa];
                }
                if(cut[fa]==0)ans1++;
                cut[fa]++;
                st[fa].insert(First[x]);
                mi=*st[fa].begin(),ma=*st[fa].rbegin();
                lca=LCA(mi,ma);
                ans2+=sz[lca]-cut[fa];
          }
          else{
                fa=bel[x];
                mi=*st[fa].begin(),ma=*st[fa].rbegin();
                lca=LCA(mi,ma);
                ans2-=sz[lca]-cut[fa];
                if(cut[fa]==1)ans1--;
                cut[fa]--;
                st[fa].erase(First[x]);
                if(cut[fa]){
                    mi=*st[fa].begin(),ma=*st[fa].rbegin();
                    lca=LCA(mi,ma);
                    ans2+=sz[lca]-cut[fa];
                }
          }
          printf("%d %d\n",ans1,ans2);
    }
    return 0;
}
<think>我们被要求提供一个关于OpenAI Gym和PyBullet的入门指南。根据用户需求,我们将分步骤介绍如何安装、配置以及使用这两个工具进行强化学习仿真开发。同时,我们会参考站内引用中提到的内容,特别是引用[1]中关于OpenAI Gym和PyBullet的信息,以及引用[4]中关于安装环境的提示。 步骤: 1. 环境安装:包括Python环境、OpenAI Gym和PyBullet的安装。 2. 基本概念:简要介绍OpenAI Gym和PyBullet的核心概念。 3. 创建第一个环境:使用OpenAI Gym的经典控制环境和PyBullet的环境。 4. 运行一个简单智能体:使用随机策略来与环境交互。 5. 结合强化学习算法:使用Stable-Baselines3(引用[1]中提到的RL框架)来训练一个简单的智能体。 6. 可视化与调试:使用TensorBoard(引用[1]中提到)来监控训练过程。 注意:在安装过程中,我们推荐使用Anaconda来管理环境(引用[4]中提到)。 下面开始详细步骤: ### 一、环境安装 #### 1. 创建并激活Conda环境(推荐) ```bash conda create -n rl_env python=3.8 conda activate rl_env ``` #### 2. 安装OpenAI Gym和PyBullet 根据引用[1]和[4],我们安装必要的包: ```bash pip install gym[box2d] # 包含Box2D环境,如LunarLander pip install pybullet ``` #### 3. 安装强化学习算法库(可选,但推荐) 我们选择Stable-Baselines3(引用[1]中推荐): ```bash pip install stable-baselines3 ``` #### 4. 安装可视化工具 安装TensorBoard用于监控训练: ```bash pip install tensorboard ``` ### 二、基本概念 - **OpenAI Gym**:提供标准化的环境接口,包括`env.reset()`和`env.step(action)`等核心方法[^1]。 - **PyBullet**:一个开源的物理引擎,提供机器人仿真环境,其环境接口与Gym兼容[^1]。 - **环境(Environment)**:强化学习智能体交互的世界,如倒立摆(CartPole)或月球着陆器(LunarLander)等。 ### 三、创建第一个环境 #### 1. 使用OpenAI Gym的经典控制环境 ```python import gym # 创建倒立摆环境 env = gym.make('CartPole-v1') obs = env.reset() # 初始化环境,返回初始状态 ``` #### 2. 使用PyBullet环境 PyBullet内置了一些机器人环境,如: ```python import pybullet_envs # 需要先导入以注册环境 env = gym.make('AntBulletEnv-v0') # 四足蚂蚁机器人 obs = env.reset() ``` ### 四、运行一个简单智能体(随机策略) ```python env = gym.make('CartPole-v1') obs = env.reset() done = False total_reward = 0 while not done: action = env.action_space.sample() # 随机采动作 obs, reward, done, info = env.step(action) # 执行动作 total_reward += reward env.render() # 渲染环境(可选) print(f"总奖励: {total_reward}") env.close() ``` ### 五、结合强化学习算法训练 使用Stable-Baselines3中的PPO算法训练CartPole智能体: ```python import gym from stable_baselines3 import PPO from stable_baselines3.common.vec_env import DummyVecEnv from stable_baselines3.common.evaluation import evaluate_policy # 创建环境 env = gym.make('CartPole-v1') env = DummyVecEnv([lambda: env]) # 向量化环境(即使只有一个环境) # 创建PPO智能体 model = PPO('MlpPolicy', env, verbose=1) # 训练 model.learn(total_timesteps=10000) # 保存模型 model.save("ppo_cartpole") # 评估 mean_reward, std_reward = evaluate_policy(model, env, n_eval_episodes=10) print(f"平均奖励: {mean_reward}, 标准差: {std_reward}") ``` ### 六、可视化与调试 训练过程中,Stable-Baselines3会自动记录日志到`./logs/`目录。使用TensorBoard查看训练曲线: ```bash tensorboard --logdir ./logs/ ``` 在浏览器中打开`http://localhost:6006`,可以查看奖励曲线、策略损失等。 ### 七、在PyBullet环境中训练 以AntBulletEnv为,训练一个连续控制任务: ```python import gym import pybullet_envs from stable_baselines3 import SAC # 对于连续动作空间,使用SAC算法 env = gym.make('AntBulletEnv-v0') env = DummyVecEnv([lambda: env]) # 使用SAC算法 model = SAC('MlpPolicy', env, verbose=1) model.learn(total_timesteps=100000) model.save("sac_ant") # 测试训练好的模型 obs = env.reset() while True: action, _states = model.predict(obs, deterministic=True) obs, rewards, done, info = env.step(action) env.render() if done: obs = env.reset() ``` ### 常见问题解决 1. **渲染问题**:在无头服务器上运行时,可能需要使用虚拟显示(如Xvfb)或使用`render(mode='human')`改为`render(mode='rgb_array')`。 2. **环境兼容性**:PyBullet环境需要安装`pybullet_envs`包(在安装PyBullet时通常已包含)。 ### 总结 通过以上步骤,我们完成了从环境安装到训练一个强化学习智能体的过程。OpenAI Gym提供了丰富的标准环境,而PyBullet则提供了更复杂的机器人仿真环境。结合Stable-Baselines3,我们可以快速实现强化学习算法的训练和测试。 --- ### 相关问题 1. 如何解决仿真到真实(Sim2Real)的迁移问题?[^4] 2. 在强化学习中如何设计有效的奖励函数?[^2] 3. 如何利用模仿学习(Imitation Learning)来加速强化学习的训练过程?[^4] 4. 在PyBullet中如何加载自定义的机器人URDF模型? 5. 如何评估强化学习智能体的性能?[^1] > 提示:更多代码示可参考OpenAI Spinning Up和CleanRL项目[^1]。</think>### OpenAI Gym 与 PyBullet 强化学习入门指南 #### 一、环境安装与配置 1. **基础环境**(推荐使用 Anaconda[^4]): ```bash conda create -n rl_env python=3.8 conda activate rl_env pip install gym pybullet tensorboard ``` 2. **扩展组件安装**: ```bash # 安装 Box2D 物理引擎支持 pip install gym[box2d] # 安装 Stable-Baselines3 算法库[^1] pip install stable-baselines3 ``` #### 二、OpenAI Gym 基础使用 ```python import gym # 创建经典控制环境(倒立摆) env = gym.make('CartPole-v1') # 环境交互基本框架 obs = env.reset() for _ in range(1000): action = env.action_space.sample() # 随机动作 obs, reward, done, info = env.step(action) if done: obs = env.reset() env.render() # 可视化 env.close() ``` #### 三、PyBullet 环境实战 ```python import pybullet_envs # 创建PyBullet四足机器人环境 env = gym.make('AntBulletEnv-v0') # 使用PPO算法训练(需安装stable-baselines3) from stable_baselines3 import PPO model = PPO('MlpPolicy', env, verbose=1) model.learn(total_timesteps=10000) # 训练1万步 # 测试训练结果 obs = env.reset() while True: action, _states = model.predict(obs) obs, rewards, done, info = env.step(action) env.render() ``` #### 四、关键概念解析 1. **环境核心组件**: - **观测空间**:`env.observation_space`(状态表示) - **动作空间**:`env.action_space`(离散/连续动作) - **奖励函数**:`step()`返回的 reward 值 2. **物理引擎对比**: | 特性 | PyBullet | MuJoCo | Box2D | |---|---|---|---| | 物理精度 | ★★★☆ | ★★★★ | ★★☆ | | 计算速度 | ★★★★ | ★★★☆ | ★★★★★ | | 许可 | 开源免费 | 需商业许可 | 开源免费 | | 机器人支持 | ★★★★ | ★★★★ | ★★☆ | #### 五、训练优化技巧 1. **奖励函数设计**: ```python # 自定义奖励示(倒立摆) def custom_reward(obs): x, theta = obs[0], obs[2] # 平衡奖励 + 位置惩罚 return 1.0 - abs(theta)/0.2 - abs(x)/2.0 ``` 2. **超参数调优**: ```python model = PPO( 'MlpPolicy', env, learning_rate=3e-4, gamma=0.99, n_steps=2048, batch_size=64 ) ``` 3. **训练监控(TensorBoard)**: ```bash tensorboard --logdir ./ppo_tensorboard/ ``` 在训练时添加参数:`tensorboard_log="./ppo_tensorboard/"` #### 六、进阶开发路径 1. **自定义环境开发**: - 继承 `gym.Env` 类 - 实现 `reset()` 和 `step()` 方法 - 注册环境:`gym.register(id='MyEnv-v0', entry_point='my_module:MyEnv')` 2. **Sim2Real 迁移**: ```mermaid graph LR A[仿真环境训练] --> B[域随机化] B --> C[动力学参数扰动] C --> D[传感器噪声注入] D --> E[真实世界部署] ``` #### 七、常见问题解决 1. **渲染报错**: ```python # 无头模式解决方案 env = gym.make('AntBulletEnv-v0', render=False) ``` 2. **安装依赖缺失**: ```bash # 解决OpenGL依赖 sudo apt install libgl1-mesa-glx ``` --- ### 相关问题 1. 如何设计有效的强化学习奖励函数?[^2] 2. 在资源有限的设备上如何优化PyBullet仿真性能? 3. 如何处理连续动作空间与离散动作空间的差异? 4. 如何利用TensorBoard有效分析强化学习训练过程?[^1] 5. Sim2Real迁移中的域随机化具体如何实现?[^3] > 提示:更多实战案可参考 OpenAI Spinning Up 和 CleanRL 项目[^1],进阶开发推荐结合 Isaac Sim 实现工业级应用[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值