方程组求解 比较有挑战性,盼高手帮忙
有一根料长 6000 mm,现在要分成以下方案
//1589 、560、2376、1600、2100 每根材料的长度
//3 10 2 3 2 根数
求怎么分这6000mm 利用率最高;
如:
//1589 、560、2376、1600、2100 每根材料的长度
//0 2 2 0 0 根数
这个分法的利用率达到98%
我是这样解的:
using System;
namespace ConsoleApplication1
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
////1589 、560、2376、1600、2100
////3 10 2 3 2
int sum1 = 0;
int i = 0, j = 0, m = 0, n = 0, x = 0;
int x1, x2, x3, x4, x5;
for (m = 0; m < 3; m++)
{
for (x = 0; x < 3; x++)
{
for (n = 0; n < 4; n++)
{
//int sum1=1589*i+560*j+2376*m+1600*n+2100*x;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 11; j++)
{
sum1 = 1589*i + 560*j + 2376*m + 1600*n + 2100*x +i*10+j*10+m*10+n*10;
if (sum1 <= 6000)
{
x1 = i;
x2 = j;
x3 = m;
x4 = n;
x5 = x;
Console.Write( "&&&&&&&&&&&&&&&&&&&& ");
Console.Write(string.Format( "\n "));
Console.Write(string.Format( "1589x1:{0}\n ", i));
Console.Write(string.Format( "560x2:{0}\n ", j));
Console.Write(string.Format( "2376x3:{0}\n ", m));
Console.Write(string.Format( "1600x4:{0}\n ", n));
Console.Write(string.Format( "2100x5:{0}\n ", x));
Console.Write(string.Format( "sum1:{0}\n ", (double)sum1));
Console.Write(string.Format( "百分比:{0}%\n ", (double)sum1/(double)6000));
Console.Write( "========== ");
}
else
{
continue;
}
}
}
}
}
}
}
}
}
但这个并不是一个通用的解法,如我们还要分1700(3),1800(2),2500(2) 如按上面的写法就将有8个FOR 了,这根本没有通用性可言;
希望得到更位仁兄的帮助,谢谢
------解决方案--------------------
楼主的结果不是最优的
最优的情况应该是:1 5 0 1 0,这时候总长度是:5989 利用率是:99.8%
代码如下:
class Program
{
static void Main(string[] args)
{
double count;
List <double> unit = new List <double> ();
Console.WriteLine( "输入总长度: ");
count = Convert.ToDouble(Console.ReadLine());
ccount = count;
string s = " ";
while (s != "end ")
{
s = Console.ReadLine();
try
{
double dd = Convert.ToDouble(s);
unit.Add(dd);
}
catch { };
}
List <int> unitTop = new List <int> ();
s = " ";
while (s != "end ")
{
s = Console.ReadLine();
try
{
int nn = Convert.ToInt32(s);
unitTop.Add(nn);
}
catch { }
}
brr = new int[unitTop.Count];
double all = Compute(count, unit.ToArray(), unitTop.ToArray(), 0);
Console.WriteLine(countsave);
for (int i = 0; i < savebrr.Length; i++)
{
Console.Write(savebrr[i] + " ");
}
Console.WriteLine();
}
static double countsave = 0;//保存最大值
static int[] brr;//保存每种型号的根数
static int[] savebrr;//保存在最大值的情况下每种型号的根数
static double ccount = 0;//保存总长度
static double Compute(double count, double[] unit,int[] unitTop,int p)
{
if (p == unit.Length || p == unitTop.Length)
{
#region 判断是否比先前的结果更好
double c = 0;
for (int i = 0; i < brr.Length; i++)
{
c += brr[i] * unit[i];
}
if (count> =0&&ccount> =c&&countsave < c)
{
countsave = c;
savebrr = new int[brr.Length];
for (int ii = 0; ii < savebrr.Length; ii++)
savebrr[ii] = brr[ii];
}
#endregion
return 0;
}
double r = unit[p];
for (int i = 0; i <= unitTop[p]; i++)
{
brr[p] = i;
double compute = r*i+ Compute(count-r*i, unit, unitTop, p+1);
if (count > = compute)
{
continue;
}
else
{
if (i > 0)
{
brr[p] = i - 1;
return r * (i - 1) + Compute(count - r * (i - 1), unit, unitTop, p + 1);
}
}
}
if (p == 0)
return 0;
return r * unitTop[p] + Compute(count, unit, unitTop, p + 1);
}
}