计算成本和重量限制内的最佳项目组合

时间:2015-11-22 14:48:08

标签: c arrays

我试图帮助我的姐姐完成大学的计算机编程工作(我在爱尔兰的高中同等学历)。我以前用Python和Java编程但很少用C.项目必须用C语言完成。

基本上,您会获得许多物品。每件商品都有重量,价值和成本。我们的想法是在保持重量限制和预算的同时计算物品的最佳可能值。

我已经编写了代码,但它不起作用。每次运行时,输出都是一个随机的数字数组,重量和成本值为零...

我认为问题与realloc功能有关,但我不知道如何使用它。我本质上想要制作一个我可以改变长度的数组。我不认为realloc是为此设计的......任何建议或解决方案都会有很大的帮助...

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

int check(int finalList[], int value, int current,int limit, int weight, int tempw, int budget, int cost, int tempc, int Clist[], int x);

int main()
{
    int nlist[5] = {1,2,3,4,5};
    int values[5] = {4,5,7,2,9};
    int weights[5] = {1,4,8,2,9};
    int costs[5]= {3,6,2,1,8};
    int n = 5;
    int x,i,j,k,l,m,p=0;
    int value=0, cost= 0, weight = 0,tempv=0, tempw = 0, tempc = 0;
    int budget = 45;
    int limit = 12;
    int finalList[n];

    for(x=0;x<n;x++)
    {
        for(i=0;i<n;i++)
        { 
            int list[x+1];
            list[0] = nlist[i];
            tempv = values[i];
            tempw = weights[i];
            tempc = costs[i];

            for(j=0;j<x;j++)
            {
                for(k=0;k<n;k++)
                {
                    list[0]=nlist[i];
                    tempv = values[i];
                    tempw = weights[i];
                    tempc = costs[i];
                    m = p;

                    for(l=0;l<x;l++)
                    {
                        if(m==i)
                        {
                            m++;
                            p++;
                        }

                        list[l] = nlist[m];
                        tempv = tempv + values[m];
                        tempw = tempw + weights[m];
                        tempc = tempc + costs[m];
                        check(finalList, value,tempv, limit, weight, tempw, budget, cost, tempc, list,x);
                    }

                    p++;
                }
            }
            check(finalList, value,tempv,limit, weight, tempw, budget, cost, tempc, list,x);
        }
    }

    printf("\nMost efficient item list:" );
    for(i=0;i<n;i++)
    {
        printf("%d", finalList[i]);
    }
    printf("\nWeight: %d", weight);
    printf("\nCost: %d", cost);
}


int check(int finalList[], int value, int current,int limit, int weight, int tempw, int budget, int cost, int tempc, int Clist[], int x)
{
    if(tempw<=limit)
    {
        if(tempc<=budget)
        {
            if (current>value)
            {
                finalList = realloc(finalList, 1*(x+1));
                finalList= Clist;
                value = current;
                weight = tempw;
                cost = tempc;
            }

        }
    }
    return finalList,value,weight,cost;
}

2 个答案:

答案 0 :(得分:0)

在函数check()中:

  • 您丢弃了finalListvalueweight的价值。
  • return finalList,value,weight,cost;相当于return cost;
  • cost的值也被丢弃,因为未使用返回值。

使用指针是在函数之间传递多个信息的一种方法。

此外,m变得过大而nlist[m]等导致超出范围的访问。

不知道计算,这段代码至少打印的东西不是零而不是压碎。

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

void check(int **finalList, int *value, int current,int limit, int *weight, int tempw, int budget, int *cost, int tempc, int Clist[], int x);

int main(void)
{
    int nlist[5] = {1,2,3,4,5};
    int values[5] = {4,5,7,2,9};
    int weights[5] = {1,4,8,2,9};
    int costs[5]= {3,6,2,1,8};
    int n = 5;
    int x,i,j,k,l,m,p=0;
    int value=0, cost= 0, weight = 0,tempv=0, tempw = 0, tempc = 0;
    int budget = 45;
    int limit = 12;
    int *finalList = calloc(n, sizeof(int));

    for(x=0;x<n;x++)
    {
        for(i=0;i<n;i++)
        { 
            int list[x+1];
            for(j=0;j<=x;j++) list[j] = 0; /* initialize the list */
            list[0] = nlist[i];
            tempv = values[i];
            tempw = weights[i];
            tempc = costs[i];

            for(j=0;j<x;j++)
            {
                for(k=0;k<n;k++)
                {
                    list[0]=nlist[i];
                    tempv = values[i];
                    tempw = weights[i];
                    tempc = costs[i];
                    m = p;

                    for(l=0;l<x;l++)
                    {
                        if(m==i)
                        {
                            m++;
                            p++;
                        }

                        if(m<5)
                        {
                            list[l] = nlist[m];
                            tempv = tempv + values[m];
                            tempw = tempw + weights[m];
                            tempc = tempc + costs[m];
                        }
                        check(&finalList, &value,tempv, limit, &weight, tempw, budget, &cost, tempc, list,x);
                    }

                    p++;
                }
            }
            check(&finalList, &value,tempv,limit, &weight, tempw, budget, &cost, tempc, list,x);
        }
    }

    printf("\nMost efficient item list:" );
    for(i=0;i<n;i++)
    {
        printf("%d", finalList[i]);
    }
    printf("\nWeight: %d", weight);
    printf("\nCost: %d", cost);
    free(finalList);
    return 0;
}


void check(int **finalList, int *value, int current,int limit, int *weight, int tempw, int budget, int *cost, int tempc, int Clist[], int x)
{
    if(tempw<=limit)
    {
        if(tempc<=budget)
        {
            if (current>*value)
            {
                *finalList = realloc(*finalList, sizeof(int)*(x+1));
                if(*finalList == 0)
                {
                    perror("realloc");
                    exit(1);
                }
                memcpy(*finalList, Clist, sizeof(int)*(x+1));
                *value = current;
                *weight = tempw;
                *cost = tempc;
            }

        }
    }
}

答案 1 :(得分:0)

首先,我将尝试向您展示具有适当数据结构和小功能的面向对象原则如何帮助使代码更易读,更容易发现错误。

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

const int MAX_COST = 45;
const int MAX_WEIGHT = 12;

const int VALUES[5] = {4, 5, 7, 2, 9};
const int WEIGHTS[5] = {1, 4, 8, 2, 9};
const int COSTS[5] = {3, 6, 2, 1, 8};

typedef struct
{
    // total over all items in the subset
    int value;
    int weight;
    int cost;

    // subset of items
    int indices[5];
    int num_indices;
} candidate;

void candidate_init (candidate *c)
{
    c->value = 0;
    c->weight = 0;
    c->cost = 0;
    c->num_indices = 0;
}

void candidate_print (const candidate *c)
{
    printf ("items:  ");
    for (int i = 0; i < c->num_indices; i++) {
        printf ("%d, ", c->indices[i]);
    }
    putchar ('\n');

    printf ("value:  %d\n", c->value);
    printf ("weight: %d\n", c->weight);
    printf ("cost:   %d\n", c->cost);
};

void candidate_add_item (candidate *c, int i)
{
    c->value += VALUES[i];
    c->weight += WEIGHTS[i];
    c->cost += COSTS[i];

    c->indices[c->num_indices++] = i;
}

int candidate_is_ok (const candidate *c)
{
    return ((c->weight <= MAX_WEIGHT) && (c->cost <= MAX_COST));
}

理论上你不需要使用realloc(),因为你可以静态地分配一个足够大的候选数组来保存5个元素的所有子集,即32个子集。这个数字随着元素数量的增加而变大,因此动态分配可能是一个好主意。为了便于说明,我将为您提供一个解决方案,允许您在编译时选择静态和动态分配。

#if 0
// STATIC                                               

candidate candidates[32]; // 32 == pow (2, 5)
int num_candidates;

void candidates_init ()
{
    num_candidates = 0;
}

void candidates_insert (candidate *c)
{
    candidates[num_candidates++] = *c;
}

void candidates_end ()
{
}

#else
// DYNAMIC                                                                      

candidate * candidates;
int num_candidates;

void candidates_init ()
{
    candidates = NULL;
    num_candidates = 0;
}

void candidates_insert (candidate *c)
{
    candidates = realloc (candidates,
                          (num_candidates + 1) * sizeof(candidate));
    candidates[num_candidates++] = *c;
}

void candidates_end ()
{
    free (candidates);
}
#endif

现在的主要代码,应该很容易理解:

int main ()
{
    candidates_init ();

    // insert empty candidate                                                   
    {
        candidate c;
        candidate_init (&c);
        candidates_insert (&c);
    }

    // generate all valid candidates                                            
    for (int i = 0; i < 5; i++) {
        int n = num_candidates;
        for (int j = 0; j < n; j++) {
            candidate c = candidates[j];
            candidate_add_item (&c, i);
            if (candidate_is_ok (&c)) {
                candidates_insert (&c);
            }
        }
    }

    // find candidate with maximum value                                        
    int max_value = 0;
    int max_i = 0;

    for (int i = 0; i < num_candidates; i++) {
        if (candidates[i].value > max_value) {
            max_value = candidates[i].value;
            max_i = i;
        }
    }

    // print solution                                                           
    candidate_print (&candidates[max_i]);

    candidates_end ();
}