分支定界实施

时间:2011-03-13 05:30:18

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

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

  

建造仓库

     

描述

     

赢得彩票后,你决定   买几个truks(或卡车)。   您的目标是向所有人提供货物   科英布拉的超市。但现在你   必须建立仓库来存储   货物,你必须考虑   可能的位置。理想情况下,   仓库应靠近   超市为了减少   交通费用。但是,你   不能把所有的钱花在建设上   到处都是仓库,所以你必须这样做   做出一个聪明的决定:给予   建造每个仓库的固定成本   在每个可能的位置和   每个人的运输成本   超市从每个位置   未来5年,你想知道在哪里   仓库应该建立以便   总成本(运输和固定   在此期间的费用是最低的。   请注意,至少有一个仓库必须   建成。而且,计算   整体运输成本必须   考虑到所有   超市必须送达。

     

输入

     

每个测试用例都包含信息   关于建筑的固定成本   在给定地点的仓库和   与每个相关的运输成本   位置和超市。首先   每个测试用例的行给出了   a的可能位置的数量   可以建造仓库(n <51)和   超市数量(m <16)。然后,   以下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;
}

2 个答案:

答案 0 :(得分:1)

我不清楚标准的分支机构是否会在这里发挥作用。

BnB通过强制搜索在达到部分解决方案时回溯,只要完整解决方案的任何扩展的成本无法提高到目前为止找到的最佳完整解决方案的成本。这取决于能否说出任何部分解决方案成本的下限,s。

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

答案 1 :(得分:1)

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

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

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

  1. 如果这是添加到解决方案中的最后一个仓库,那么显然会增加总成本,因此不应添加。
  2. 否则,假设这是k的第i个;我在解决方案中添加了仓库。考虑我们通过在最后一个地方而不是第一个地方添加它来获得的解决方案 - 可以添加此仓库然后可能会降低总体成本吗?不,因为对于每个超市s,每个仓库按步骤i + 1 ... k添加要么降低维修成本,要么保持相同。添加仓库可以产生净收益的唯一方法是能够比目前的解决方案更便宜地服务一个或多个超市。如果在添加第一个i-1步骤之后不是这种情况,那么在完整解决方案中添加所有k-1个其他仓库之后肯定不会是这种情况。这意味着在以后添加仓库的净成本总是与在较早时间添加仓库相同或更差。
  3. 这可以修剪搜索树,使得普通递归合理地快速完成。