【CSP试题回顾】202006-1-线性分类器

CSP-202006-1-线性分类器

解题思路

线性分类问题,即根据给定的数据点和分类界限,判断是否存在一条线能够将属于不同类别的点完全分开。具体来说,数据点被分为两类,标记为A和B,我们要找出是否存在一个线性决策边界(由参数θ0、θ1和θ2确定),使得所有的A点和B点能被这条直线准确地分开。

  1. 输入数据处理

    • 代码首先通过输入读取数据点的数量(n个)和线性分类器的数量(m个)。根据输入的数据点的坐标和类别(A或B),将这些点存储到两个不同的向量listAlistB中。
  2. 遍历每个线性分类器

    • 对于每一个线性分类器,代码将检查所有的A类和B类数据点是否能被当前的分类器准确分类。
    • 分类器的决策规则是基于线性方程 θ 0 + θ 1 ∗ x + θ 2 ∗ y \theta_0 + \theta_1 * x + \theta_2 * y θ0+θ1x+θ2y 的结果是否大于0来决定的。如果大于0,我们认为点被分类为一类;如果小于或等于0,则被分类为另一类。
  3. 检查A类和B类数据点的分类

    • 对于A类的每一个点,代码会检查它们是否都在分类器定义的同一侧。这是通过计算 θ 0 + θ 1 ∗ x + θ 2 ∗ y \theta_0 + \theta_1 * x + \theta_2 * y θ0+θ1x+θ2y 的值并与首个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;
}

请添加图片描述

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值