您的位置:首页 > 其它

生成最佳的配料配置算法

2011-08-28 22:10 148 查看
1.题目

求解数学题目,题目的背景:求最佳的优化分配,即在一个烧煤厂中有很多配料,每个配料有不同的成分(如含碳10%,含水20%,含镁30%。。。)。共有配料15种左右,每种配料含量在0——100个单位之间。最后汇总后,每种成份的总含量都有范围限定(如总含碳量在15%到20%之间。。。)。求最优解(每种配料价格不同,最后求出总价最低的解法)。

2.计算后效果

只需配置一个文本文件,把各个配料的价格、最大、最小比例、名称等信息填进去,运行我的程序,就可以弹出一个对话框,显示各个配料的最佳比例的详细信息,包括该比例下的总价格以及各个配料的配置比例。 该程序还可以检查进行异常检查,在最大比例是否大于对小比例、最小比例之和大于100%,最大比例之和小于100%的情况下提示异常信息。



3.使用方法

根据需要修改如下配置信息:

[SourceType]

TotalNum = 10

[Source1]

SourceName = Source01

SourceContanPerMax = 30

SourceContanPerMin = 15

Price = 30

[Source2]

SourceName = Source02

SourceContanPerMax = 30

SourceContanPerMin = 1

Price = 10

[Source3]

SourceName = Source03

SourceContanPerMax = 30

SourceContanPerMin = 15

Price = 10

[Source4]

SourceName = Source04

SourceContanPerMax = 30

SourceContanPerMin = 15

Price = 100

[Source5]

SourceName = Source05

SourceContanPerMax = 30

SourceContanPerMin = 15

Price = 10

[Source6]

SourceName = Source06

SourceContanPerMax = 30

SourceContanPerMin = 15

Price = 8

[Source7]

SourceName = Source07

SourceContanPerMax = 30

SourceContanPerMin = 3

Price = 5

[Source8]

SourceName = Source08

SourceContanPerMax = 30

SourceContanPerMin = 2

Price = 10

[Source9]

SourceName = Source09

SourceContanPerMax = 20

SourceContanPerMin = 2

Price = 1

[Source10]

SourceName = Source10

SourceContanPerMax = 30

SourceContanPerMin = 2

Price = 8

[Source11]

SourceName = Source11

SourceContanPerMax = 30

SourceContanPerMin = 2

Price = 30

4.算法实现

public class Source {

public String SourceName = "";

public int MaxPer = 0;

public int MinPer = 0;

public int Price = 0;

public int usedPercent = 0;

}

public class MixJudger {

/** 配置文件名 */

private static final String strFileName = "data/config.ini";

public static void main(String[] args) {

String strSectionName = "SourceType";

String strKeyName = "TotalNum";

String strSourTypeNum = "";

int nSourTypeNum = 0;

HashMap hmSource = new HashMap();

try {

strSourTypeNum = ProfileStringMgr.getInstace().getProfileString(strFileName, strSectionName, strKeyName, "0");

nSourTypeNum = Integer.parseInt(strSourTypeNum);

String tempSection = "";

//String tempKey = "";

String tempValue = "";

for(int i = 0; i < nSourTypeNum; i++){

Source tmpSur = new Source();

strSectionName = "Source" + String.valueOf(i + 1);

strKeyName = "SourceName";

tempValue = ProfileStringMgr.getInstace().getProfileString(strFileName, strSectionName, strKeyName, "0");

tmpSur.SourceName = tempValue;

//

strKeyName = "SourceContanPerMax";

tempValue = ProfileStringMgr.getInstace().getProfileString(strFileName, strSectionName, strKeyName, "0");

tmpSur.MaxPer = Integer.parseInt(tempValue);

strKeyName = "SourceContanPerMin";

tempValue = ProfileStringMgr.getInstace().getProfileString(strFileName, strSectionName, strKeyName, "0");

tmpSur.MinPer = Integer.parseInt(tempValue);

strKeyName = "Price";

tempValue = ProfileStringMgr.getInstace().getProfileString(strFileName, strSectionName, strKeyName, "0");

tmpSur.Price = Integer.parseInt(tempValue);

hmSource.put(i, tmpSur);

}

int SouceNum = hmSource.size();

int totalPercent = 0;

// 限定配料的个数

if(SouceNum > 10){

JOptionPane.showMessageDialog(null, "对不起该演示版本的配料个数不能超过10个",

"占海提示", JOptionPane.INFORMATION_MESSAGE);

return;

}

// 检查下最大值是否都大于最小值,不然报错

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

if(tmpSur.MaxPer < tmpSur.MinPer){

JOptionPane.showMessageDialog(null, "配料名:" + tmpSur.SourceName + "的最大比例之小于最小比例,请检查数据是否正确",

"占海提示", JOptionPane.INFORMATION_MESSAGE);

return;

}

}

// 检查下如果都取最大会不会不到100%

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

totalPercent = totalPercent + tmpSur.MaxPer;

}

if(totalPercent < 100){

JOptionPane.showMessageDialog(null, "各个配料的最大比例之和仍小于100%,请检查数据是否正确",

"占海提示", JOptionPane.INFORMATION_MESSAGE);

return;

}

// 先获得最小percent

totalPercent = 0;

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

totalPercent = totalPercent + tmpSur.MinPer;

tmpSur.usedPercent = tmpSur.MinPer;

hmSource.put(i, tmpSur);

}

if(totalPercent > 100){

JOptionPane.showMessageDialog(null, "各个配料的最小比例之和已大于100%,请检查数据是否正确",

"占海提示", JOptionPane.INFORMATION_MESSAGE);

return;

}

// 开始计算

while(totalPercent < 100){

// 遍历一遍找到价格最少的配料

int minPrice = 100000000;

int minPirceIndex = 0;

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

if(tmpSur.usedPercent == tmpSur.MaxPer){

continue;

}

if(minPrice > tmpSur.Price){

minPrice = tmpSur.Price;

minPirceIndex = i;

}

}

// 进行更新比例

Source tmpSur = (Source) hmSource.get(minPirceIndex);

tmpSur.usedPercent++;

totalPercent++;

hmSource.put(minPirceIndex, tmpSur);

}

// 计算出总钱数

int totalMoney = 0;

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

totalMoney = totalMoney + tmpSur.usedPercent + tmpSur.Price;

}

// 显示的详细信息

StringBuffer sb = new StringBuffer();

sb.append("各个配料的总钱数为" + totalMoney).append(", 详细信息如下:").append("\n");

for (int i = 0; i < SouceNum; i++){

Source tmpSur = (Source) hmSource.get(i);

sb.append("配料名称:").append(tmpSur.SourceName).append("使用比例:").append(tmpSur.usedPercent).append(",单价:").append(tmpSur.Price).append("\n");

totalMoney = totalMoney + tmpSur.usedPercent + tmpSur.Price;

}

System.out.print(sb.toString());

JOptionPane.showMessageDialog(null, sb.toString(),

"占海提示", JOptionPane.INFORMATION_MESSAGE);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: