求一C#算法,在线急等!!

xiulinwang123 2017-05-31 09:15:40
各位大侠,本人遇到一个算法问题,如下:
 有一组料盘数量比如是23, 35, 45, 要拆分组合满足 13, 30, 50, 这分别是三个站点的需求数量
我们人脑心算结果是这样,将23拆成16,7, 这样16可以满足13, 35本来就满足30,7+45=52可以满足50
意思就是说将一组数字切分再组合去满足另外一组需求数字,只有一个要求,切分次数最少,因为料盘切分过多会带来工作不便,求C#算法,感谢!!
 
...全文
625 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
MYsce 2017-06-01
  • 打赏
  • 举报
回复
学习学习
  • 打赏
  • 举报
回复
jy251 2017-06-01
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
呵呵,我只给我合作的公司找一些长期的核心产品,小活儿其实说起来容易做起来(维护起来)难。
小活不光是维护麻烦,有些小程序,逻辑非常复杂,且使用的技术更难。
引用 楼主 xiulinwang123 的回复:
各位大侠,本人遇到一个算法问题,如下:  有一组料盘数量比如是23, 35, 45, 要拆分组合满足 13, 30, 50, 这分别是三个站点的需求数量 我们人脑心算结果是这样,将23拆成16,7, 这样16可以满足13, 35本来就满足30,7+45=52可以满足50 意思就是说将一组数字切分再组合去满足另外一组需求数字,只有一个要求,切分次数最少,因为料盘切分过多会带来工作不便,求C#算法,感谢!!  
帮顶,这个真是很麻烦的一种算法,我是没见过这种成型的有名的算法
xiulinwang123 2017-06-01
  • 打赏
  • 举报
回复
引用 23 楼 xuzuning 的回复:
23, 35, 45 13, 30, 50 14, 26, 43 12, 58
没懂您的意思
xiulinwang123 2017-06-01
  • 打赏
  • 举报
回复
引用 22 楼 zanfeng 的回复:
[quote=引用 楼主 xiulinwang123 的回复:] 各位大侠,本人遇到一个算法问题,如下:  有一组料盘数量比如是23, 35, 45, 要拆分组合满足 13, 30, 50, 这分别是三个站点的需求数量 我们人脑心算结果是这样,将23拆成16,7, 这样16可以满足13, 35本来就满足30,7+45=52可以满足50 意思就是说将一组数字切分再组合去满足另外一组需求数字,只有一个要求,切分次数最少,因为料盘切分过多会带来工作不便,求C#算法,感谢!!  
其实这个只要把35拆成30与5不就可以了嘛? 做过玻璃与布,还有数码相纸排版的。要求一整块的料切割成不同的小块。最省料,可能和你这个差不多。[/quote] 是的,现在就是求这一套具体算法
xuzuning 2017-06-01
  • 打赏
  • 举报
回复
我的意思是判断两组数据对应位置的包容情况,以确定是否需要分割
下面给的测试例中已表现出,不同的排列方式,结果是不一样的
        static void Main(string[] args)
{
var a = new List<int>() { 23, 35, 45 };
var b = new List<int>() { 13, 30, 50 };
Console.WriteLine("{0} vs {1} =>", string.Join(",", a), string.Join(",", b));
foreach (var x in AssignALL(a, b))
{
Console.WriteLine(string.Join(",", x));
}

a = new List<int>() { 14, 26, 43 };
b = new List<int>() { 12, 58 };
Console.WriteLine("{0} vs {1} =>", string.Join(",", a), string.Join(",", b));
foreach (var x in AssignALL(a, b))
{
Console.WriteLine(string.Join(",", x));
}
Console.ReadKey();
}
static IEnumerable<List<int>> AssignALL(List<int> a, List<int> b)
{
foreach (var y in Perm(b.ToArray()))
{
foreach (var x in Perm(a.ToArray()))
{
var r = Assign(x.ToList(), y.ToList());
if (r.Count >= x.Length && !r.Contains(-1))
{
Console.Write(" [{0}]:[{1}] ", string.Join(",", x), string.Join(",", y));
yield return r;
}
}
}
}
static List<int> Assign(List<int> a, List<int> b)
{
if (b.Count == 1) return a;
var sa = a.Sum();
var sb = b.Sum();
if (sa < sb) return new List<int>() { -1 };
var res = new List<int>();
if (a[0] >= b[0])
{
if (sa - a[0] >= sb - b[0])
{
res.Add(a[0]);
res.AddRange(Assign(a.Skip(1).ToList(), b.Skip(1).ToList()));
}
else if (sa - (a[0] - b[0]) >= sb - b[0])
{
res.Add(b[0]);
a[0] = a[0] - b[0];
res.AddRange(Assign(a, b.Skip(1).ToList()));
}
}
return res;
}

static void Swap<T>(ref T a, ref T b)
{
T t = a; a = b; b = t;
}
static IEnumerable<int[]> Perm(int[] arr, int pos=0)
{
if (pos == arr.Length) { yield return arr; }
for (int i = pos; i < arr.Length; ++i)
{
Swap(ref arr[i], ref arr[pos]);
foreach (var j in Perm(arr, pos + 1)) yield return j;
Swap(ref arr[i], ref arr[pos]);
}
}


通常看到这种需求,首先想到的是线性规划
但是 状态转移方程 实在是不容易寻找,教程上的例子一看就懂,但换个条件就无从下手了
所以我还是喜欢利用计算机的强大功能,用穷举法来找答案
本人QQ-554433626 2017-05-31
  • 打赏
  • 举报
回复

        private void test()
        {
            int[] param1 = { 23, 35, 45 };
            int[] param2 = { 13, 30, 50 };
            Array.Sort(param1);
            Array.Sort(param2);
            Dictionary<int, int> dic1 = new Dictionary<int, int>();
            Dictionary<int, int> dic2 = new Dictionary<int, int>();
            for (int i = 0; i < param1.Length; i++)
            {
                int item = param1[i] - param2[i];
                if (item > 0)
                    dic1.Add(i, item);
                else
                    dic2.Add(i, item);
            }
            Dictionary<int, int> dic1_SortedByKey = dic1.OrderByDescending(p => p.Value).ToDictionary(p => p.Key, o => o.Value);
            Dictionary<int, int> dic2_SortedByKey = dic2.OrderByDescending(p => p.Value).ToDictionary(p => p.Key, o => o.Value);
            int negative = 0;
            foreach (var items in dic2_SortedByKey)
                negative += -1 * items.Value;
            int positive = 0;
            List<int> list = new List<int>(dic1_SortedByKey.Keys);
            int count = dic1_SortedByKey.Count;
            for (int j = 0; j < dic1_SortedByKey.Count; j++)
            {
                if (positive < negative)
                    positive += dic1_SortedByKey[list[j]];
                else
                    count = j;
            }
            int lastNum = positive - negative;
            Dictionary<int, int> dic3 = new Dictionary<int, int>();
            Dictionary<int, int> dic4 = new Dictionary<int, int>();
            List<int> list1 = new List<int>(dic2_SortedByKey.Keys);
            for (int x = 0; x < count; x++)
            {
                int key = list[x];
                dic3.Add(key, param2[key] - param1[key]);
            }
            int key1 = 0;
            for (int y = 0; y < dic2_SortedByKey.Count; y++)
            {
                key1 = list1[y];
                dic4.Add(key1, param2[key1] - param1[key1]);
            }
            dic4[key1] = dic4[key1] + lastNum;
            var query = dic3.Union(dic4);
            foreach (KeyValuePair<int, int> obj in query)
            {
                Console.WriteLine(param1[obj.Key] + "  " + obj.Value);
            }
        }
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
引用 13 楼 xuzuning 的回复:
对于 23, 35, 45, 要拆分组合满足 13, 30, 50 你说的 23 拆成 16、7 自然是可以的 那么 23 拆成 13,、10 不也一样满足吗? 13 == 13 35 > 30 10+45 > 50
是的,这个例子本身就有很多答案,只要有算法得到一组只需要拆一次即可,拆两次就不太好了
xuzuning 2017-05-31
  • 打赏
  • 举报
回复
对于 23, 35, 45, 要拆分组合满足 13, 30, 50 你说的 23 拆成 16、7 自然是可以的 那么 23 拆成 13,、10 不也一样满足吗? 13 == 13 35 > 30 10+45 > 50
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
引用 10 楼 chenandczh 的回复:
如果是 类似仓库 或者ERP 物料 统计 计算相关的算法,其实 行业内 会有 对应的做法。你这类属于填坑的做法。
这个问题就是仓库发料的问题,我司是SMT制件类的,料盘是原材料最小单位,但经常要将料盘拆分去匹配SMT Slot(料站)的需求量,以前都是人工心算如何拆分,现在大BOSS要求系统计算好拆分规则,直接显示出给作业员,作业员按系统提示作业即可.以上六个数字只是举例,只是想求这一套算的思路,如果不考虑拆的次数,这算法就简单了,难就难在这,怎么拆是最节省工时的
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
引用 5 楼 qq_32661557 的回复:
哇 懂不起 16可以满足13, 35本来就满足30,7+45=52可以满足50 什么意思哦
解释一下,满足就是大于等于它即可
绿领巾童鞋 2017-05-31
  • 打赏
  • 举报
回复
如果是 类似仓库 或者ERP 物料 统计 计算相关的算法,其实 行业内 会有 对应的做法。你这类属于填坑的做法。
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
呵呵,我只给我合作的公司找一些长期的核心产品,小活儿其实说起来容易做起来(维护起来)难。
  • 打赏
  • 举报
回复
呵呵,我只给我合作的公司找一些长期的核心产品,小活儿其实说起来容易做起来(维护起来)难。
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
引用 4 楼 duanzi_peng 的回复:
[quote=引用 2 楼 xiulinwang123 的回复:] 大学学的一些统计学,线性代数早就忘光了 当前工作急遇此难题,未找到思路,只求广大网友协助
你有偿给#1楼 2k,让他帮你写代码了。[/quote] 有发票不
  • 打赏
  • 举报
回复
引用 2 楼 xiulinwang123 的回复:
大学学的一些统计学,线性代数早就忘光了 当前工作急遇此难题,未找到思路,只求广大网友协助
思路就是如此。你说“线性代数”,我估计你没有学过运筹学或者经济统计方面的知识,因为“线性规划”跟“线性代数”不是仅仅差两个字儿的问题。学管理的人最起码地都会用 Excel 的规划功能,你可以找一本管理人员的培训课本,看看他们的关于 Excel 的规划功能的章节,里边就会有实例。然后你的程序就去调用 Excel 算了。
本人QQ-554433626 2017-05-31
  • 打赏
  • 举报
回复
哇 懂不起 16可以满足13, 35本来就满足30,7+45=52可以满足50 什么意思哦
exception92 2017-05-31
  • 打赏
  • 举报
回复
引用 2 楼 xiulinwang123 的回复:
大学学的一些统计学,线性代数早就忘光了 当前工作急遇此难题,未找到思路,只求广大网友协助
你有偿给#1楼 2k,让他帮你写代码了。
  • 打赏
  • 举报
回复
至于说编程,有许多 c#(或者别的语言)的专业的计算学软件包,里边有上千的算法过程,其中总有几个就是线性、非线性规划相关的。例如解决一个企业员工排班问题,解决运输调度问题,解决大的百货公司选址问题,解决广告投放决策问题,解决选什么人当总统的问题.......往往是几百了变量、几百个约束方程、多目标最优化的求解问题,这只要调用一下软件包就行了。 你这个问题使用最笨的模型也不过只有9个变量,6个约束条件,用不了5毫秒就给出结果了。编写为一个“活的”程序,投入产出条件可以随时扩充,就能成为一个“产品”。自己去研究研究吧。
xiulinwang123 2017-05-31
  • 打赏
  • 举报
回复
大学学的一些统计学,线性代数早就忘光了 当前工作急遇此难题,未找到思路,只求广大网友协助
加载更多回复(9)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧