CSP-202006-1-线性分类器
解题思路
线性分类问题,即根据给定的数据点和分类界限,判断是否存在一条线能够将属于不同类别的点完全分开。具体来说,数据点被分为两类,标记为A和B,我们要找出是否存在一个线性决策边界(由参数θ0、θ1和θ2确定),使得所有的A点和B点能被这条直线准确地分开。
-
输入数据处理:
- 代码首先通过输入读取数据点的数量(n个)和线性分类器的数量(m个)。根据输入的数据点的坐标和类别(A或B),将这些点存储到两个不同的向量
listA
和listB
中。
- 代码首先通过输入读取数据点的数量(n个)和线性分类器的数量(m个)。根据输入的数据点的坐标和类别(A或B),将这些点存储到两个不同的向量
-
遍历每个线性分类器:
- 对于每一个线性分类器,代码将检查所有的A类和B类数据点是否能被当前的分类器准确分类。
- 分类器的决策规则是基于线性方程 θ 0 + θ 1 ∗ x + θ 2 ∗ y \theta_0 + \theta_1 * x + \theta_2 * y θ0+θ1∗x+θ2∗y 的结果是否大于0来决定的。如果大于0,我们认为点被分类为一类;如果小于或等于0,则被分类为另一类。
-
检查A类和B类数据点的分类:
- 对于A类的每一个点,代码会检查它们是否都在分类器定义的同一侧。这是通过计算 θ 0 + θ 1 ∗ x + θ 2 ∗ y \theta_0 + \theta_1 * x + \theta_2 * y θ0+θ1∗x+θ2∗y 的值并与首个A类点的计算结果比较来实现的。如果有任何一个A类点的判断与第一个点不一致,则输出“No”并停止检查A类的其余点。
- 如果所有A类点都在同一侧,那么代码将对B类点执行相同的检查。如果所有B类点都在与A类点相反的一侧,则认为这个分类器有效,输出“Yes”;如果有任何一个B类点的判断与A类点在同一侧,则输出“No”。
完整代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct MyPoint
{
int x, y;
};
int n, m, myX, myY, theta0, theta1, theta2;
char type;
vector<MyPoint>listA, listB;
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> myX >> myY >> type;
if (type == 'A') listA.push_back({ myX, myY });
else listB.push_back({ myX,myY });
}
for (int i = 0; i < m; i++)
{
cin >> theta0 >> theta1 >> theta2;
bool flagA = theta0 + theta1 * listA[0].x + theta2 * listA[0].y > 0, printA = 0, printB = 0;
for (auto& it : listA) {
if ((theta0 + theta1 * it.x + theta2 * it.y > 0) != flagA) {
cout << "No\n";
printA++;
break;
}
}
if (!printA)
{
for (auto& it : listB) {
if ((theta0 + theta1 * it.x + theta2 * it.y > 0) != (!flagA)) {
cout << "No\n";
printB++;
break;
}
}
}
if (printA == 0 && printB == 0)cout << "Yes\n";
}
return 0;
}