C# 滤波器优化的数据分组算法

C# 滤波器优化的数据分组算法,c#,algorithm,filter,can-bus,C#,Algorithm,Filter,Can Bus,我正在进行一个使用MCP2515(CAN收发器)的项目,该芯片的一个特点是,我可以通过应用规则(掩码)过滤ID,只允许特定范围的数据通过过滤器。我最多可以有6个不同的过滤器。在我正在编写的应用程序中,我解析一个DBC文件来选择我想要接收的信号。如果我有6个或更少的信号,我可以为这些信号中的每一个创建一个“通过规则”,但是如果我有6个以上的信号,我需要创建规则,使我需要的所有ID都能通过。理想情况下,每一组都能获得尽可能小的数据范围。我希望它是自动计算的,所以我需要创建一种算法来重组我的ID 例如

我正在进行一个使用MCP2515(CAN收发器)的项目,该芯片的一个特点是,我可以通过应用规则(掩码)过滤ID,只允许特定范围的数据通过过滤器。我最多可以有6个不同的过滤器。在我正在编写的应用程序中,我解析一个DBC文件来选择我想要接收的信号。如果我有6个或更少的信号,我可以为这些信号中的每一个创建一个“通过规则”,但是如果我有6个以上的信号,我需要创建规则,使我需要的所有ID都能通过。理想情况下,每一组都能获得尽可能小的数据范围。我希望它是自动计算的,所以我需要创建一种算法来重组我的ID

例如,如果选择了以下ID: 32、154、157、160、354、363、680、682、841、845、871、932、936、940

我的数据组是[32]、[154157160]、[354363]、[680682]、[841845871]、[932936940]

这是我现在的代码,但是它在处理范围的末尾时遇到了问题(在上面的例子中:32和940)

private void getMasks()
{
列表字段=新列表();
uint谱=0;
uint chunkSize=0;
id.Sort();
spectrum=IDs.Last()-IDs.First();
//获取第一个分组的整个数据范围的六分之一
chunkSize=(uint)数学上限((双)频谱/6);
//重新组合6个范围中的数据
对于(int i=0;i<6;i++)
{
添加(新列表());
foreach(id中的uint id)
{
如果(id>=((i*chunkSize)+IDs.First())和&id<((i+1)*chunkSize)-1)+IDs.First())
字段[i]。添加(id);
}                
}
//如果某个范围没有数据,则将其删除
对于(int j=0;j=2&&fields[k+1].Count>0&((字段[k][fields[k].Count-1]-fields[k][fields[k].Count-2])>(字段[k+1][fields[k+1].Count-1]-fields[k][fields[k].Count-1]))
{
字段[k+1]。添加(字段[k].Last());
字段[k].RemoveAt(字段[k].Count-1);
}
//如果组中的第一个数据更接近最后一个组的最后一个数据,而不是其自身组的第二个数据,则将其移动到最后一个组。
而(字段[k].Count>0&&fields[k+1].Count>=2&&((字段[k+1][1]-字段[k+1][0])>(字段[k].Last()-字段[k+1][0]))
{
字段[k]。添加(字段[k+1][0]);
字段[k+1]。删除(0);
}
} 
//查找要应用的掩码的其他代码
}
有人能给我一些提示或例子,告诉我如何在尽可能小的范围内重新组合数据吗

谢谢,


Alfred

这是您的列表,其中列出了到下一项的计算“距离”:

32(122), 154(3), 157(3), 160(194), 354(9), 363(317), 680(2), 682(159), 841(4), 845(26), 871(61), 932(4), 936(4), 940()
在这里,相同的列表按“距离”降序排列:

363(317), 160(194), 682(159), 32(122), 871(61), 845(26), 354(9), 841(4), 932(4), 936(4), 154(3), 157(3), 680(2), 940() 
您需要的-取前5项:

363(317), 160(194), 682(159), 32(122), 871(61)
并在以下项目后“拆分”原始列表:

32(122)                  // split 4
154(3), 157(3), 160(194) // split 2
354(9), 363(317)         // split 1
680(2), 682(159)         // split 3
841(4), 845(26), 871(61) // split 5
932(4), 936(4), 940()
它将在代码中为您提供6个组(您可以剪切5个最大的空格)

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {

        static void Main(string[] args)
        {
            List<int> signals = new List<int>() { 680, 841, 154, 940, 160, 157, 936, 354, 363,  682, 871, 932, 845, 32};

            signals.Sort();

            List<GapData> gapsData = new List<GapData>();

            for(int i = 0; i < signals.Count - 1; i++)
            {
                GapData newGap = new GapData() { Index = i, Span = signals[i + 1] - signals[i] };
                gapsData.Add(newGap);
            }

            gapsData.Sort();

            gapsData = gapsData.Take(5).ToList(); //Keep 5 biggest gaps

            gapsData = gapsData.OrderBy(i => i.Index).ToList(); //sort on index

            List<List<int>> groupedList = new List<List<int>>();

            int index = 0;

            List<int> currentGroup = new List<int>();
            groupedList.Add(currentGroup);

            for(int i = 0; i < signals.Count; i++)
            {
                if (index < 5 && gapsData[index].Index < i)
                {
                    currentGroup = new List<int>();
                    groupedList.Add(currentGroup);
                    index++;
                }
                currentGroup.Add(signals[i]);
            }
        }


        public class GapData:IComparable<GapData>
        {
            public GapData()
            {
            }
            public int Index { get; set; }

            public int CompareTo(GapData other)
            {
                return - Span.CompareTo(other.Span);
            }


            public int Span { get; set; }
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间控制台EAPP1
{
班级计划
{
静态void Main(字符串[]参数)
{
列表信号=新列表(){680、841、154、940、160、157、936、354、363、682、871、932、845、32};
signals.Sort();
List gapsData=新列表();
对于(int i=0;ii.Index).ToList();//按索引排序
List groupedList=新列表();
int指数=0;
List currentGroup=新列表();
groupedList.Add(当前组);
对于(int i=0;i
您能解释一下分组规则吗?你只是成百上千的在做吗?我看不出“每个组的第一个和最后一个ID之间的最小范围”与所需的输出有什么关系。不,数据是分组的,因此每个数据范围都是最小的。例如,如果我获取帖子中列出的数据,如果354在[154,157,160]组中,则我规则的范围必须包括154到354之间的数据(范围为200)。按照原始帖子中的排序方式,[154157160]的范围将是6,[354363]组的范围将是9。我需要有6条规则,当应用时,尽可能过滤我收到的帧。我不能
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {

        static void Main(string[] args)
        {
            List<int> signals = new List<int>() { 680, 841, 154, 940, 160, 157, 936, 354, 363,  682, 871, 932, 845, 32};

            signals.Sort();

            List<GapData> gapsData = new List<GapData>();

            for(int i = 0; i < signals.Count - 1; i++)
            {
                GapData newGap = new GapData() { Index = i, Span = signals[i + 1] - signals[i] };
                gapsData.Add(newGap);
            }

            gapsData.Sort();

            gapsData = gapsData.Take(5).ToList(); //Keep 5 biggest gaps

            gapsData = gapsData.OrderBy(i => i.Index).ToList(); //sort on index

            List<List<int>> groupedList = new List<List<int>>();

            int index = 0;

            List<int> currentGroup = new List<int>();
            groupedList.Add(currentGroup);

            for(int i = 0; i < signals.Count; i++)
            {
                if (index < 5 && gapsData[index].Index < i)
                {
                    currentGroup = new List<int>();
                    groupedList.Add(currentGroup);
                    index++;
                }
                currentGroup.Add(signals[i]);
            }
        }


        public class GapData:IComparable<GapData>
        {
            public GapData()
            {
            }
            public int Index { get; set; }

            public int CompareTo(GapData other)
            {
                return - Span.CompareTo(other.Span);
            }


            public int Span { get; set; }
        }
    }

}