计算最佳组合

时间:2013-06-21 10:07:12

标签: java android algorithm dynamic-programming linear-programming

我正在设计一个应用程序,其中我需要从一组肥料中选择,最好的组合,即可以提供给定营养素的最少量的肥料。

例如,假设我需要提供23克氮(氮)和23克磷(磷),我有以下两套肥料:

设置1:
肥料N P K(g / 100 Kg)
A 23 23 0
B 18 46 0
C 46 0 0

设置2:
肥料N P K(g / 100 Kg)
D 23 23 0
E 18 46 0
F 16 0 0

在步骤1中:
我们可以选择50公斤肥料B获得23克磷,并选择~30公斤肥料C来获得所需的氮。总重量为80公斤,而不是选择100公斤肥料A. 在步骤2中:
我们最好选择100公斤肥料D而不是选择肥料E和肥料F.

现在,我正在尝试提出一种计算最佳组合的算法。我相信贪婪的方法是行不通的。因此,我尝试在3D矩阵上进行动态编程,以获得N,P,K的所有可能的积分值,但这会导致精度损失。我只有有限的资源 任何人都可以建议任何其他方法吗?
我觉得也许这可以被建模为图形问题,但我不知道如何

这是我写的动态编程的代码:

void evaluateChoices() {
        dp = new int[MAX + 1][MAX + 1][MAX + 1];
        for(int i = 0; i < MAX; i++) {
            for(int j = 0; j < MAX; j++) {
                for(int k = 0; k < MAX; k++) {
                        if(i == 0 && j == 0 && k == 0) {
                            dp[0][0][0] = 0;
                        }
                        else {
                            considerCurrent(i, j, k);
                        }
                }
            }
        }
    }


void considerCurrent(int i, int j, int k) {
    int minyet = Integer.MAX_VALUE;
    for(int choice = 0; choice < numFertilizers; choice++) {
        fertilizer fertilizerOption = fertilizerChoices[choice];
        int amount;
        if(fertilizerOption.N >= fertilizerOption.K && fertilizerOption.N >= fertilizerOption.P) {
            amount = (100 / fertilizerOption.N) * i;
            if(amount == 0) {                               // required amount is amount of N i.e i
                continue;
            }
            if(((j - (fertilizerOption.P / 100)) * amount) >= 0 && ((k - (fertilizerOption.K / 100)) * amount) >= 0) {
                int jIndex = (j - ((fertilizerOption.P / 100) * amount));
                int kIndex = (k - ((fertilizerOption.K / 100) * amount));
                if(dp[0][jIndex][kIndex] + amount < minyet) {
                    dp[i][j][k] = dp[0][jIndex][kIndex] + amount;
                }
            }
        }
        else if(fertilizerOption.P >= fertilizerOption.K && fertilizerOption.P >= fertilizerOption.N) {
            amount = (100 / fertilizerOption.P) * j;
            if(amount == 0) {                               // required amount is amount of P i.e j
                continue;
            }
            if(((i - (fertilizerOption.N / 100)) * amount) >= 0 && ((k - (fertilizerOption.K / 100)) * amount) >= 0) {
                int iIndex = (i - ((fertilizerOption.N / 100) * amount));
                int kIndex = (k - ((fertilizerOption.K / 100) * amount));
                if(dp[iIndex][0][kIndex] + amount < minyet) {
                    dp[i][j][k] = dp[iIndex][0][kIndex] + amount;
                }
            }
        }
        else {
            amount = (100 / fertilizerOption.K) * k;
            if(amount == 0) {                               // required amount is amount of K i.e k
                continue;
            }
            if((i - ((fertilizerOption.N / 100) * amount)) >= 0 && (j - ((fertilizerOption.P / 100) * amount)) >= 0) {
                int iIndex = ((i - (fertilizerOption.N / 100) * amount));
                int jIndex = ((j - (fertilizerOption.P / 100)  * amount));
                if(dp[iIndex][jIndex][0] + amount < minyet) {
                    dp[i][j][k] = dp[iIndex][jIndex][0] + amount;
                }
            }
        }
    }
}


这里i,j,k是N,P,K值 我面临的问题是,当我计算如下指数时:

int jIndex = (j - ((fertilizerOption.P / 100) * amount));

我正在失去精确度,我无法真正帮助它,因为我将它映射到数组索引。

1 个答案:

答案 0 :(得分:3)

这称为线性程序。您正在进行线性优化。 您可以使用Simplex Algorithm来解决此类任务。