如何在Processing/Arduino中计算统计模式

发布于 2024-12-11 15:43:29 字数 414 浏览 0 评论 0原文

我是一名设计老师,试图帮助学生应对编程挑战,所以我编写代码是为了乐趣,但我不是专家。

她需要在使用构建的数据集中找到模式(最常见的值)来自连接到 Arduino 的传感器的数据,然后根据结果激活一些功能。

除了如何在 Arduino 中计算模式之外,我们已经弄清楚了大部分内容。我找到了帖子 获取在array 解决了 JavaScript 中的问题,但我无法“移植”它。

I'm a design teacher trying to help a student with a programming challenge, so I code for fun, but I'm no expert.

She needs to find the mode (most frequent value) in a dataset built using data from sensors coupled to an Arduino, and then activate some functions based on the result.

We've got most of it figured out, except how to calculate the mode in Arduino. I found the post Get the element with the highest occurrence in an array that solves the problem in JavaScript, but I haven't been able to "port" it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温柔戏命师 2024-12-18 15:43:29

我使用了 HashMap 来替换 js {} 动态对象实例和浮动,但 @weberik 的端口看起来更简单。

void setup() {
    int numValues = 10;
    float[] values = new float[numValues]; //Create an empty sample array
    for(int i = 0 ; i < numValues ; i++) values[i] = random(0.0,100.0); //Populate it with random values.
    println("mode: " + mode(values));
}

float mode(float[] source) {
    if (source.length == 0)
        return -1;
    HashMap<Float,Integer> modeMap = new HashMap<Float,Integer>();
    float result = source[0];
    int maxCount = 1;
    for (int i = 0; i < source.length; i++) {
        float el = source[i];
        if (modeMap.get(el) == null)
            modeMap.put(el,1);
        else
            modeMap.put(el,modeMap.get(el)+1);
        if (modeMap.get(el) > maxCount) {
            result = el;
            maxCount = modeMap.get(el);
        }
    }
    return result;
}

您提到了传感器输入,所以我假设数据将被连续采样,因此可以以一定的间隔存储值,然后发送到该模式的处理。
只是一个疯狂的猜测,但她不是想平均/平滑传感器读数吗?
如果是这样,她可以在 Arduino 的数组中缓存一些值(比如 10 个),并在每次添加新值时获取平均值:

int vals[10]; //Array to store caches values.

void setup() {
    Serial.begin(9600);
    for (int i=0 ; i < 10 ; i++) 
        vals[i] = 0; //Init with zeroes
}

void loop() {
    delay(100);
    int currentVal = average(analogRead(0));
    //Serial.print(currentVal,BYTE);
    Serial.println(currentVal);
}

int average(int newVal) {
    int total = 0; //Used to store the addition of all currently cached values
    for(int i = 9; i > 0; i--) { //Loop backwards from the one before last to 0
        vals[i] = vals[i-1]; //Overwrite the prev. value with the current(shift values in array by 1)
        total += vals[i]; //Add to total
    }
    vals[0] = newVal; //Add the newest value at the start of the array
    total += vals[0]; //Add that to the total as well
    return total *= .1; //Get the average (for 10 elemnts) same as total /= 10, but multiplication is faster than division.
}

I've used a HashMap to replace the js {} dynamic object instance and floats, but @weberik's port looks more straightforward.

void setup() {
    int numValues = 10;
    float[] values = new float[numValues]; //Create an empty sample array
    for(int i = 0 ; i < numValues ; i++) values[i] = random(0.0,100.0); //Populate it with random values.
    println("mode: " + mode(values));
}

float mode(float[] source) {
    if (source.length == 0)
        return -1;
    HashMap<Float,Integer> modeMap = new HashMap<Float,Integer>();
    float result = source[0];
    int maxCount = 1;
    for (int i = 0; i < source.length; i++) {
        float el = source[i];
        if (modeMap.get(el) == null)
            modeMap.put(el,1);
        else
            modeMap.put(el,modeMap.get(el)+1);
        if (modeMap.get(el) > maxCount) {
            result = el;
            maxCount = modeMap.get(el);
        }
    }
    return result;
}

You've mentioned sensor input, so I presume data will be sampled continuously, so values could be stored at a certain interval, then sent to Processing for the mode.
Just a wild guess, but isn't she looking to average/smooth out sensor readings a bit?
If so, she could cache a few values (say 10) in an array in Arduino and get the average everytime a new values is added:

int vals[10]; //Array to store caches values.

void setup() {
    Serial.begin(9600);
    for (int i=0 ; i < 10 ; i++) 
        vals[i] = 0; //Init with zeroes
}

void loop() {
    delay(100);
    int currentVal = average(analogRead(0));
    //Serial.print(currentVal,BYTE);
    Serial.println(currentVal);
}

int average(int newVal) {
    int total = 0; //Used to store the addition of all currently cached values
    for(int i = 9; i > 0; i--) { //Loop backwards from the one before last to 0
        vals[i] = vals[i-1]; //Overwrite the prev. value with the current(shift values in array by 1)
        total += vals[i]; //Add to total
    }
    vals[0] = newVal; //Add the newest value at the start of the array
    total += vals[0]; //Add that to the total as well
    return total *= .1; //Get the average (for 10 elemnts) same as total /= 10, but multiplication is faster than division.
}
苍风燃霜 2024-12-18 15:43:29

我将代码从您链接的帖子移植到处理,但仅限于int 数组。
我希望这有帮助。

void setup()
{
    int[] numbers = {1, 2, 3, 2, 1, 1, 1, 3, 4, 5, 2};
    println(mode(numbers));
}


int mode(int[] array) {
    int[] modeMap = new int [array.length];
    int maxEl = array[0];
    int maxCount = 1;

    for (int i = 0; i < array.length; i++) {
        int el = array[i];
        if (modeMap[el] == 0) {
            modeMap[el] = 1;
        }
        else {
            modeMap[el]++;
        }

        if (modeMap[el] > maxCount) {
            maxEl = el;
            maxCount = modeMap[el];
        }
    }
    return maxEl;
}

I ported the code from your linked post to Processing, but it's limited to int arrays.
I hope that helps.

void setup()
{
    int[] numbers = {1, 2, 3, 2, 1, 1, 1, 3, 4, 5, 2};
    println(mode(numbers));
}


int mode(int[] array) {
    int[] modeMap = new int [array.length];
    int maxEl = array[0];
    int maxCount = 1;

    for (int i = 0; i < array.length; i++) {
        int el = array[i];
        if (modeMap[el] == 0) {
            modeMap[el] = 1;
        }
        else {
            modeMap[el]++;
        }

        if (modeMap[el] > maxCount) {
            maxEl = el;
            maxCount = modeMap[el];
        }
    }
    return maxEl;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文