Cod sursa(job #2908007)

Utilizator BadBoyRADULICEA Constantin Dumitru Petre BadBoy Data 1 iunie 2022 02:07:06
Problema Problema rucsacului Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.39 kb
#ifndef __RUCSAC_C__
#define __RUCSAC_C__

#include<stdio.h>
#include<string.h>
#include <time.h>
#include <vector>
#include <iostream>
#include <fstream>

#ifndef min(X, Y)
#define min(X, Y) (((X) < (Y)) ? (X) : (Y))
#endif // !MIN

#ifndef max(X, Y)
#define max(X, Y) (((X) > (Y)) ? (X) : (Y))
#endif // !MAX

/*
* 2. Rezolvati problema discreta a rucsacului pentru valori mici ale lui N (<=15) folosind backtracking si comparati
* timpii de executie intre Backtracking si Greedy. Comparati de asemenea "calitatea" solutiei oferite de greedy, 
* considerand solutia oferita de backtracking ca referinta. Reprezentati grafic datele pentru valori ale lui N de la 5 la 15.
* N : vector of objects
* G : Max weight
* W : weight (greutate)
* P : Profit
*/
typedef struct obiect_rucsac
{
	int greutate;
	int profit;
}obiect_rucsac;

static void load_sack(int* W, int* n, std::vector<obiect_rucsac> *obiecte)
{
	std::ifstream fin("rucsac.in");
	int tmp;
	fin >> (*n);
	fin >> (*W);
	obiecte->resize(*n);
	for (int i = 0; i < *n; i++)
	{
		fin >> (*obiecte)[i].greutate;
		fin >> (*obiecte)[i].profit;
	}
	fin.close();
}

// Returns the maximum value that can be
// put in a knapsack of capacity W
static int knapSack_backtracking(int W, obiect_rucsac obiecte[], int n)
{
    // Base Case
    if (n == 0 || W == 0) return 0;

    // If weight of the nth item is more than
    // Knapsack capacity W, then this item cannot
    // be included in the optimal solution
    if (obiecte[n - 1].greutate > W) {
        return knapSack_backtracking(W, obiecte, n - 1);
    }

    // Return the maximum of two cases:
    // (1) nth item included
    // (2) not included
    else {
        return max(obiecte[n - 1].profit + knapSack_backtracking(W - obiecte[n - 1].greutate, obiecte, n - 1), knapSack_backtracking(W, obiecte, n - 1));
    }
        
}

//#define N_ELEM 17
//static int test_rucsac_backtracking()
//{
//	obiect_rucsac _Multime[] = {{4, 7}, {5, 2},{9, 3}, {1, 3},{7, 8},
//								{4, 8}, {2, 3}, {2, 3} ,{1, 5}, {1, 1},
//								{11, 20}, {7, 9}, {10, 4}, {12, 10}, {8, 12},
//								{13, 22}, {23, 222} };
//
//	int msec = 0, i, sum=0, val;
//	clock_t before, difference;
//	for (int n = 5; n <= N_ELEM; n++)
//	{
//		for (int g = 0; g < 100; g++)
//		{
//			sum = 0;
//			int ff = knapSack_backtracking(g, _Multime, n);
//			for (i = 0; i < 10; i++)
//			{
//				randomize(_Multime, n, sizeof(obiect_rucsac));
//				before = clock();
//				val = knapSack_backtracking(g, _Multime, n);
//				if (ff != val) printf("Error g:%d n:%d val:%d gg:%d\n", g, n, val, ff);
//				difference = clock() - before;
//				sum += difference;
//			}
//			msec = sum * 1000 / CLOCKS_PER_SEC / (i);
//			printf("%d;%d;%d;%d\n",  n, g,val, msec);
//		}
//
//	}
//
//	return 0;
//}

int main()
{
	int n, g;
	std::vector<obiect_rucsac> _Multime;
	std::ofstream fout("rucsac.out");

	load_sack(&g, &n, &_Multime);
	int ff = knapSack_backtracking(g, _Multime.data(), n);
	fout << ff;
	return 0;
}
/*===========================================================================================================================*/
#define N_ELEM 17
#define WEIGHT 100

static int knapSack_greedy(int W, obiect_rucsac _Multime[N_ELEM], int K[N_ELEM + 1][WEIGHT + 1], int n)
{
    int i, w;

    for (i = 0; i <= n; i++)
    {
        for (w = 0; w <= W; w++)
        {
            if (i == 0 || w == 0) K[i][w] = 0;
            else if (_Multime[i - 1].greutate <= w) K[i][w] = max(_Multime[i - 1].profit + K[i - 1][w - _Multime[i - 1].greutate], K[i - 1][w]);
            else K[i][w] = K[i - 1][w];
        }
    }

    //// stores the result of Knapsack
    int res = K[n][W];
	return res;
}


//static int test_rucsac_greedy()
//{
//	obiect_rucsac _Multime[] = { {4, 7}, {5, 2},{9, 3}, {1, 3},{7, 8},
//								{4, 8}, {2, 3}, {2, 3} ,{1, 5}, {1, 1},
//								{11, 20}, {7, 9}, {10, 4}, {12, 10}, {8, 12},
//								{13, 22}, {23, 222} };
//	int K[N_ELEM + 1][WEIGHT + 1];
//	int msec = 0, i, sum = 0, val;
//	clock_t before, difference;
//
//	for (int n = 5; n <= N_ELEM; n++)
//	{
//		for (int g = 0; g < WEIGHT; g++)
//		{
//			sum = 0;
//			int ff = knapSack_greedy(g, _Multime, K, n);
//			for (i = 0; i < 10; i++)
//			{
//				randomize(_Multime, n, sizeof(obiect_rucsac));
//				before = clock();
//				val = knapSack_greedy(g, _Multime, K, n);
//				if (ff != val) printf("Error g:%d n:%d val:%d gg:%d\n", g, n, val, ff);
//				difference = clock() - before;
//				sum += difference;
//			}
//			msec = sum * 1000 / CLOCKS_PER_SEC / (i);
//
//			printf("%d;%d;%d;%d\n", n, g, val, msec);
//		}
//
//	}
//}
/*===========================================================================================================================*/


// Comparison function to sort Item according to val/weight ratio
static int cmp_obj(const void *_a, const void *_b)
{
	obiect_rucsac *a, *b;
	a = (obiect_rucsac*)_a;
	b = (obiect_rucsac*)_b;

    double r1 = (double)a->profit / (double)a->greutate;
    double r2 = (double)b->profit / (double)b->greutate;
    if (r1 > r2) return 1;
    else if (r1 < r2) return -1;
    else return 0;
}

// Main greedy function to solve problem
static double knapSack_fractional(int W, obiect_rucsac arr[], int n)
{
    //sorting Item in base of ratio
    qsort(arr, n, sizeof(obiect_rucsac), cmp_obj);

    double finalvalue = 0.0; // Result (value in Knapsack)

    for (int i = 0; i < n; i++) {
        // If adding Item doesent overflow, add it completely
        if (arr[i].greutate <= W) {
            W -= arr[i].greutate;
            finalvalue += arr[i].profit;
        }
        else {      // add part of iteam
            finalvalue += arr[i].profit * ((double)W / (double)arr[i].greutate);
            break;
        }
    }
    return finalvalue;
}

// Driver code
static int test_rucsac_fractional()
{
    int W = 50; //    Weight of knapsack
    obiect_rucsac _Multime[] = { {4, 7}, {5, 2},{9, 3}, {1, 3},{7, 8},
                            {4, 8}, {2, 3}, {2, 3} ,{1, 5}, {1, 1},
                            {11, 20}, {7, 9}, {10, 4}, {12, 10}, {8, 12},
                            {13, 22}, {23, 222} };

    int n = sizeof(_Multime) / sizeof(_Multime[0]);

    // Function call
    printf("Valoarea maxima: %f\n", knapSack_fractional(W, _Multime, n));
    return 0;
}
#endif // !__RUCSAC_C__