开发者

Branch and bound implementation

I've been working on this problem, and I can get some results, but I'm having trouble implementing the branch and bound method here.

Can you guys help me?

Building Warehouses

Description

After winning the lottery, you decide to buy several truks (or lorries). Your goal is to deliver goods to all supermarkets in Coimbra. But now you have to build warehouses to store the goods, and you have to think about possible locations. Ideally, the warehouses should be located close to the supermarkets in order to reduce transportation costs. However, you cannot spend all the money on building warehouses everywhere, so you have to make a clever decision: given the fixed cost of building each warehouse in each possible location and the transportation cost of serving each supermarket from each location in the next 5 years, you want to know where warehouses should be build so that the overall cost (transportation and fixed costs) over that period is minimum. Note that at least one warehouse must be built. Moreover, the computation of the overall transportation cost has to take into account that all supermarkets must be served.

Input

Each test case contains information about the fixed costs of building warehouses at given locations and the transportation cost related to each location and supermarket. The first line of each test case gives the number of possible locations where a warehouse may be built (n<51) and the number of supermarkets (m < 16). Then, each of the following n lines gives the cost of building a warehouse at that location and the transportation costs associated with supplying each of the m supermarkets from that location.

Output

The output is the minimum overall cost of building and operating the warehouses (an integer). Example

Input:

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

Ouput:

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, &am开发者_JAVA百科p;lower);
    printf("%d\n", lower);
    return 0;
}


It's not clear to me that standard branch-and-bound is going to work here.

BnB works by forcing search to backtrack on reaching a partial solution s whenever the cost of any extension of s to a full solution cannot improve on the cost of the best complete solution found so far. This depends on being able to say something about the lower bound on the cost of any partial solution, s.

In this problem, a one-step extension to a partial solution s can either raise the overall cost or lower it (if it makes delivering to the supermarkets cheaper than the cost of building the extra warehouse), which makes the lower bound statement rather difficult to state in a useful way.


Rafe's answer is right -- "plain" B&B won't work here since the score could go up or down. But there is still some structure in the problem that can be exploited.

Any non-empty set of warehouses yields a (possibly non-optimal) solution. The total cost of a given solution is the cost of building all warehouses plus the cost of servicing all supermarkets. Given a set of warehouses, clearly each supermarket should be served by the minimal-cost warehouse for that supermarket. Notice that as you add warehouses to a solution, the cost for servicing a given warehouse either stays the same or decreases.

One thing to notice is that it is never worth adding a warehouse to a solution if doing so increases the total cost. Why?

  1. If this is the last warehouse added to the solution, then clearly it increases the total cost and so should not be added.
  2. Otherwise, suppose this is the ith of k > i warehouses added in the solution. Consider the solution we would get by adding it in last place instead of ith place -- could adding this warehouse then possibly decrease the overall cost? No, because for each supermarket s, each warehouse added in steps i+1 .. k either decreases the cost for servicing s or leaves it the same. The only way that adding a warehouse can produce a net gain is by being able to service one or more supermarkets more cheaply than does the current solution so far. If that is not the case after adding the first i-1 steps, then it certainly won't be the case after adding all k-1 other warehouses in the full solution. That means that the net cost of adding a warehouse at a later time is always the same or worse than adding it at an earlier time.

This may prune the search tree enough that a plain recursion completes reasonably quickly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜