LOOP判断单环

这篇博客介绍了一个用C++实现的程序,用于判断一个给定的点集是否存在单环。程序包含了点的定义、图的构建、输入处理、循环检查等功能,通过计算角度和向量的方法确定点的连接顺序。
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <cmath>
  7 #include <map>
  8 using namespace std;
  9 const int maxn = 1010;//点的个数  可以修改  maxn <= 20005即可满足要求
 10 const double pi = 3.141592653589;
 11 struct Point {
 12     int id;
 13     int x;
 14     int y;
 15 };
 16 bool cmp(Point p1, Point p2) {
 17     if(p1.id != p2.id) return p1.id < p2.id;
 18 }
 19 
 20 class Loop {
 21 public:
 22     int n;
 23     int G[maxn][maxn];
 24     vector<int> V[maxn];
 25     Point init[maxn], point[maxn], ans[maxn];
 26     map<string, int> mp;
 27 
 28     void Init(int n) {
 29         this -> n = n;
 30         for(int i = 1; i <= n; i++) {
 31             V[i].clear();
 32         }
 33         mp.clear();
 34         memset(G, 0, sizeof(G));
 35     }
 36 
 37     void input() {
 38         for(int i = 1; i <= n; i++) {
 39             scanf("%d %d %d",&init[i].id, &init[i].x, &init[i].y);
 40         }
 41         int u, v;
 42         for(int i = 1; i <= n; i++) {
 43             scanf("%d",&u);
 44             for(int j = 1; j <= 4; j++) {
 45                 scanf("%d",&v);
 46                 if(v != 0) {
 47                     G[u][v] = G[v][u] = 1;
 48                     V[u].push_back(v);
 49                 }
 50             }
 51         }
 52     }
 53 
 54     void check(Point a[maxn], int cnt) {
 55         if(cnt < 3) return ;
 56         Point b[maxn];
 57         for(int i = 0; i < cnt; i++) {
 58             b[i] = a[i];
 59         }
 60         sort(b, b + cnt, cmp);
 61         string s;
 62         for(int i = 0; i < cnt; i++) {
 63             char str[10];
 64             sprintf(str, "%d", b[i].id);
 65             s += str;
 66         }
 67         s += '\0';
 68         if(!mp[s]) {
 69             mp[s] = 1;
 70             for(int i = 0; i < cnt; i++) {
 71                 printf("%d ", a[i].id);
 72             } puts("");
 73         }
 74     }
 75 
 76     double C(Point p0, Point p1, Point p2) {
 77         double x1 = p1.x - p0.x; double y1 = p1.y - p0.y;
 78         double x2 = p2.x - p0.x; double y2 = p2.y - p0.y;
 79         double a = sqrt( x1*x1 + y1*y1 );
 80         double b = sqrt( x2*x2 + y2*y2 );
 81         double ab = x1*x2 + y1*y2;
 82         double caob = ab / ( a * b );
 83         double jiaodu = acos(caob);
 84         return jiaodu / pi * 180 + 1e-6;
 85     }
 86     double D(Point p0, Point p1, Point p2) {
 87         double x1 = p1.x - p0.x; double y1 = p1.y - p0.y;
 88         double x2 = p2.x - p0.x; double y2 = p2.y - p0.y;
 89         double ans = x1 * y2 - x2 * y1;
 90         return ans;
 91     }
 92     int eps(double x) {
 93         if(fabs(x) < 1e-8) return 0;
 94         if(x < 0) return -1;
 95         return 1;
 96     }
 97 
 98     void solve() {
 99         for(int i = 1; i <= n; i++) {
100             for(int j = 1; j <= n; j++) {
101                 if(i == j) continue;
102                 if(!G[i][j]) continue;
103                 int vis[maxn] = { 0 };
104                 int cnt = 1;
105                 vis[i] = vis[j] = 1;
106                 point[cnt++] = init[i];
107                 point[cnt++] = init[j];
108                 int num = n - 2;
109                 while(num--) {
110                     double ang = 181;
111                     int id_num = n + 1;
112                     int now = point[cnt - 1].id;
113                     bool fla = false;
114                     for(int k = 0; k < V[now].size(); k++) {
115                         int u = V[now][k];
116                         if(vis[u]) continue;
117                         double a1 = D(point[cnt - 1], point[cnt - 2], init[u]);
118                         if(eps(a1) >= 0) {
119                             double a2 = C(point[cnt - 1], point[cnt - 2], init[u]);
120                             if(ang > a2) {
121                                 ang = a2;
122                                 id_num = u;
123                             }
124                         }
125                     }
126                     if(id_num <= n) {
127                         fla = true;
128                         point[cnt++] = init[id_num];
129                         vis[id_num] = 1;
130                     } else {
131                         double ang2 = -1;
132                         int id_num2 = n + 1;
133                         for(int k = 0; k < V[now].size(); k++) {
134                             int u = V[now][k];
135                             if(vis[u]) continue;
136                             double a1 = D(point[cnt - 1], point[cnt - 2], init[u]);
137                             if(eps(a1) < 0) {
138                                 double a2 = C(point[cnt - 1], point[cnt - 2], init[u]);
139                                 if(ang < a2) {
140                                     ang2 = a2;
141                                     id_num2 = u;
142                                 }
143                             }
144                         }
145                         if(id_num2 <= n) {
146                             fla = true;
147                             point[cnt++] = init[id_num2];
148                             vis[id_num2] = 1;
149                         }
150                     }
151                     if(!fla) break;
152                     bool flag = false;
153                     for(int l = cnt - 3; l >= 1; l--) {
154                         if(G[point[l].id][id_num]) {
155                             flag = true;
156                             int cnt_1 = 0;
157                             for(int ll = l; ll < cnt; ll++) {
158                                 ans[cnt_1++] = point[ll];
159                             }
160                             check(ans, cnt_1);
161                             break;
162                         }
163                     }
164                     if(flag) {
165                         break;
166                     }
167                 }
168             }
169         }
170     }
171 };
172 Loop l1;
173 
174 int main() {
175     int n;
176     freopen("in.txt","r",stdin);
177     while(EOF != scanf("%d",&n) ) {
178         l1.Init(n);
179         l1.input();
180         l1.solve();
181     }
182     return 0;
183 }
View Code
GYN托我很久了   昨晚正式帮他写好了
也算是第一次帮写项目了哈哈哈
### 单环与多环抗扰控制原理及实现 单环和多环抗扰控制是控制系统设计中的重要概念,尤其是在需要提高系统鲁棒性和抗干扰能力的场景中。以下是对这两种控制方法的详细解析。 #### 1. 单环抗扰控制 单环抗扰控制是一种较为简单的控制策略,通常只包含一个反馈回路。其核心思想是通过单一控制器(如PID控制器)对被控对象进行调节,同时利用误差信号来抑制外部扰动的影响。在实际应用中,单环控制的优点在于结构简单、易于实现,但其抗扰能力有限,尤其是在面对复杂或高频扰动时表现较差[^1]。 单环抗扰控制的具体实现步骤如下: - 确定系统的被控量(如电机转速、电压等)。 - 设计单一控制器(如PID控制器),根据误差信号调整输出。 - 通过实时采集系统状态数据并计算误差值,调整控制器参数以优化性能。 ```python # 示例:单环PID控制实现 def pid_control(error, kp, ki, kd, prev_error, integral): integral += error # 积分项 derivative = error - prev_error # 微分项 output = kp * error + ki * integral + kd * derivative # PID输出 return output, error # 返回控制输出和当前误差 ``` #### 2. 多环抗扰控制 多环抗扰控制通过引入多个反馈回路来增强系统的抗扰能力。常见的多环控制结构包括双环控制和串级控制。例如,在电机控制系统中,可以采用速度外环和电流内环的双环控制结构。这种结构的优势在于能够分别对不同动态特性进行优化,从而提升整体性能[^3]。 ##### 双环控制 双环控制通常由两个闭环组成,外环负责调节系统的主变量(如电压或速度),内环则用于快速响应次变量(如电流)。通过内外环的协同作用,双环控制能够在保证系统稳定性的前提下,显著提高动态响应速度和抗扰能力。 ```python # 示例:双环控制实现 def outer_loop_control(voltage_error, kp_outer, ki_outer, kd_outer, prev_voltage_error, integral_outer): integral_outer += voltage_error derivative_outer = voltage_error - prev_voltage_error current_reference = kp_outer * voltage_error + ki_outer * integral_outer + kd_outer * derivative_outer return current_reference, voltage_error def inner_loop_control(current_error, kp_inner, ki_inner, kd_inner, prev_current_error, integral_inner): integral_inner += current_error derivative_inner = current_error - prev_current_error control_signal = kp_inner * current_error + ki_inner * integral_inner + kd_inner * derivative_inner return control_signal, current_error ``` ##### 串级控制 串级控制是一种特殊的多环控制形式,其中每个子控制器的输出作为下一个控制器的输入。这种结构广泛应用于直立车、无人机等复杂系统的控制中。通过将复杂的控制问题分解为多个简单的子问题,串级控制能够有效应对非线性和时变性较强的系统[^1]。 #### 抗扰能力的提升 无论是单环还是多环控制,抗扰能力的提升都依赖于合理的控制器参数设计和滤波技术的应用。例如,可以通过增加前馈补偿、使用低通滤波器等方式减少外界干扰对系统的影响[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值