欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net C# 实现任意List的笛卡尔乘积算法代码

程序员文章站 2024-02-12 12:19:34
可以扩展到多个集合的情况。类似的例子有,如果a表示某学校学生的集合,b表示该学校所有课程的集合,则a与b的笛卡尔积表示所有可能的选课情况 复制代码 代码如下:using...
可以扩展到多个集合的情况。类似的例子有,如果a表示某学校学生的集合,b表示该学校所有课程的集合,则a与b的笛卡尔积表示所有可能的选课情况

复制代码 代码如下:

using system;
using system.collections.generic;
using system.diagnostics;
using system.linq;

namespace 算法
{
    public static class 算法
    {
        /// <summary>
        /// 笛卡尔乘积
        /// </summary>
        public static list<list<t>> cartesianproduct<t>(this list<list<t>> lstsplit)
        {
            int count = 1;
            lstsplit.foreach(item => count *= item.count);
            //count = lstsplit.aggregate(1, (result, next) => result * next.count);

            var lstresult = new list<list<t>>();

            for (int i = 0; i < count; ++i)
            {
                var lsttemp = new list<t>();
                int j = 1;
                lstsplit.foreach(item =>
                {
                    j *= item.count;
                    lsttemp.add(item[(i / (count / j)) % item.count]);
                });
                lstresult.add(lsttemp);
            }
            return lstresult;
        }
    }

    class program
    {
        public static void main()
        {
            stringdemo();
            根据sector生成routing的demo();
            根据sector生成routing的demo2();
        }

        /// <summary>
        /// 简单字符串 笛卡尔乘积
        /// </summary>
        private static void stringdemo()
        {
            var lstsource = new list<list<string>>
            {
                new list<string>() { "a","b","c"},
                new list<string>() { "d","e","f"},
                new list<string>() { "g","h","i"},
            };

            var sw = new stopwatch();
            sw.start();
            var lstresult = lstsource.cartesianproduct();
            console.writeline(sw.elapsed);
        }


        private static void 根据sector生成routing的demo()
        {
            //默认允许输入多个bookingclass,表示使用任意一个都可以。
            var lstsectordef = new list<sector>
            {
                new sector{ seqno=1, bookingclass="a/a1/a2"},
                new sector{ seqno=2, bookingclass="b/b1/b2"},
                new sector{ seqno=3, bookingclass="c/c1/c2"},
                //.....数量不定
            };


            var sw = new stopwatch();
            sw.start();

            var lstsectorgroup = new list<list<sector>>();
            lstsectordef.foreach(item =>
            {
                var lstsector = new list<sector>();
                foreach (var bookingclass in item.bookingclass.split('/'))
                {
                    var sector = item.clone();
                    sector.bookingclass = bookingclass;

                    lstsector.add(sector);
                }
                lstsectorgroup.add(lstsector);
            });

            var lstrouting = lstsectorgroup.cartesianproduct();

            console.writeline(sw.elapsed);
        }


        private static void 根据sector生成routing的demo2()
        {
            //默认允许输入多个bookingclass,表示使用任意一个都可以。
            var lstsectordef = new list<sector>
            {
                new sector{ seqno=1, bookingclass="a1/a2/a3"},
                new sector{ seqno=2, bookingclass="b1/b2/b3"},
                new sector{ seqno=3, bookingclass="c1/c2/c3"},
                //.....数量不定
            };

            var sw = new stopwatch();
            sw.start();

            var lsttemp = new list<list<string>>();
            lstsectordef.foreach(item =>
            {
                lsttemp.add(item.bookingclass.split('/').tolist());
            });

            var lstbookingclassgroup = lsttemp.cartesianproduct();

            var lstrouting = new list<list<sector>>();
            for (int i = 0; i < lstbookingclassgroup.count; i++)
            {
                var lstsector = new list<sector>();
                for (int j = 0; j < lstsectordef.count; j++)
                {
                    var sector = lstsectordef[j].clone();
                    sector.bookingclass = lstbookingclassgroup[i][j];
                    lstsector.add(sector);
                }
                lstrouting.add(lstsector);
            }

            console.writeline(sw.elapsed);
        }

 

    }

    [debuggerdisplay("sector:seqno={seqno},bookingclass={bookingclass}")]
    public class sector
    {
        public int seqno { get; set; }
        public string bookingclass { get; set; }

        public sector clone()
        {
            return this.memberwiseclone() as sector;
        }
    }
}