【问题标题】:Branch and bound implementation分支绑定实现
【发布时间】:2011-03-13 05:30:17
【问题描述】:

我一直在研究这个问题,我可以得到一些结果,但是我在这里实现分支和绑定方法时遇到了麻烦。
你们能帮帮我吗?

建造仓库

说明

中奖后,你决定 购买几辆卡车(或卡车)。 您的目标是向所有人交付货物 科英布拉的超市。但现在你 必须建造仓库来存放 货,你要考虑 可能的位置。理想情况下, 仓库应靠近 超市为了减少 交通费用。然而,你 不能把所有的钱都花在建筑上 到处都是仓库,所以你必须 做出明智的决定:鉴于 建造每个仓库的固定成本 在每个可能的位置和 服务每个人的运输成本 超市从各个位置 未来5年,你想知道在哪里 应建造仓库,以便 总成本(运输和固定 成本)在那个时期是最低的。 请注意,至少一个仓库必须 被建造。此外,计算 总运输成本必须 考虑到所有 超市必须提供服务。

输入

每个测试用例都包含信息 关于建筑的固定成本 指定地点的仓库和 与每个相关的运输成本 位置和超市。首先 每个测试用例的行给出 可能的位置数量 可以建造仓库(n

输出

输出是最小的总成本 建设和运营 仓库(整数)。示例

输入:

4 5

10 8 6 10 8 10

9 1 2 10 4 8

10 6 4 2 1 5

1 10 4 6 9 3

输出:

26

http://pastebin.com/apXCMdxy

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

struct set {
    int *nodes;
    int position;
    int size;
    int capacity;
};

int locations;
int supermarkets;





void calc_custo(int **matrix, struct set *set, int *lower){


    int i;
    int last;
    int cost;
    int t;
    int j;
    int *mins;
    struct set *new_set;
    new_set = malloc(sizeof(struct set));
    new_set->nodes = malloc(new_set->capacity * sizeof(int));

    mins = malloc((supermarkets + 1) * sizeof(int));
    /*
    for (i = 0; i < set->size; i ++) {
        printf("%d ", set->nodes[i]);
    }
    printf("\n");*/
    for(j = 0; j < supermarkets + 1; j++) {
        mins[j] = INT_MAX;
    }   

    cost = 0;
    for(i = 0; i < set->size; i ++) {
        t = set->nodes[i];
        cost += matrix[t][0];
         for(j = 1; j < supermarkets + 1; j++) {
             if (mins[j] > matrix[t][j]) {
                 mins[j] = matrix[t][j];
             }

         }
    }

    for(j = 1; j < supermarkets + 1; j++) {
        cost += mins[j];
    }

    free(mins);

    memcpy(new_set, set, sizeof(struct set));
    memcpy(new_set->nodes, set->nodes, set->capacity * sizeof(int));

    if (cost < *lower) {
        *lower = cost;

    }

    if (set->position < set->capacity) {
        set->nodes[set->size] = set->position;
        set->size++;
        set->position++;
        calc_custo(matrix, set, lower);

    }

    if (new_set->position < new_set->capacity) {
        new_set->nodes[new_set->size - 1] = new_set->position;
        new_set->position++;
        calc_custo(matrix, new_set, lower);
    }

}


int main (int argc, const char* argv[])
{


    int t;
    int i, j;
    int lower;
    int **matrix;

    /*allocat matrix*/

    scanf("%d", &locations);
    scanf("%d", &supermarkets);

    matrix = malloc(locations * sizeof(int*));
    for (i = 0; i < locations; i++){
        matrix[i] = malloc((supermarkets + 1) * sizeof(int));

    }

    struct set *set;
    set = malloc(sizeof(struct set));
    set->nodes = malloc(locations * sizeof(int));
    set->size = 1;
    set->position = 1;
    set->capacity = locations;
    set->nodes[0] = 0;

    for (i = 0; i < locations; i++) {
        for (j = 0; j < supermarkets + 1; j++) {
            scanf("%d", &t);
            matrix[i][j] = t;
        }
    }
    lower = INT_MAX;
    calc_custo(matrix, set, &lower);
    printf("%d\n", lower);
    return 0;
}

【问题讨论】:

  • 我认为没有人会检查您的所有代码。我真的不明白问题出在哪里。

标签: algorithm dynamic-programming branch-and-bound


【解决方案1】:

我不清楚标准的分支定界是否可以在这里工作。

BnB 的工作方式是强制搜索在达到部分解决方案 s 时回溯,只要将 s 扩展到完整解决方案的成本无法提高迄今为止找到的最佳完整解决方案的成本。这取决于能否说明任何部分解决方案的成本下限,s。

在这个问题中,对部分解决方案 s 的一步扩展可以提高或降低总体成本(如果它使运送到超市的成本低于建造额外仓库的成本),这使得下限陈述很难以有用的方式陈述。

【讨论】:

    【解决方案2】:

    Rafe's answer 是对的——“普通”的 B&B 在这里行不通,因为分数可能会上升或下降。但问题中仍有一些结构可以利用。

    任何非空的仓库集都会产生(可能不是最优的)解决方案。给定解决方案的总成本是建造所有仓库的成本加上服务所有超市的成本。给定一组仓库,显然每个超市都应该由该超市的最低成本仓库提供服务。请注意,当您将仓库添加到解决方案时,为给定仓库提供服务的成本要么保持不变,要么降低。

    需要注意的一点是,如果这样做会增加总成本,那么永远不值得将仓库添加到解决方案中。为什么?

    1. 如果这是添加到解决方案中的最后一个仓库,那么显然它会增加总成本,因此不应添加。
    2. 否则,假设这是解决方案中添加的 k > i 个仓库中的第 i 个。考虑我们通过将它添加到最后而不是第 i 位来获得的解决方案 - 添加这个仓库 then 可能会降低总体成本吗?不,因为对于每个超市 s,在步骤 i+1 .. k 中添加的每个仓库要么降低了服务 s 的成本,要么保持不变。增加一个仓库可以产生净收益的唯一方法是能够比目前的解决方案更便宜地为一个或多个超市提供服务。如果在添加前 i-1 个步骤后不是这样,那么在完整解决方案中添加所有 k-1 个其他仓库后肯定不会是这样。这意味着稍后添加仓库的净成本始终与之前添加仓库相同或更差。

    这可能会修剪搜索树,以使普通递归相当快地完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 2023-04-01
      • 2012-02-12
      • 2021-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多