market_split.c 7.82 KB
/*
 * market_split.c
 *
 *  Created on: 17/04/2017
 *      Author: pedro
 *
 *      https://github.com/MiniZinc/minizinc-benchmarks/tree/master/market_split
 *
 *      Market Split problem:
 *      A large company has two divisions D1 and D2. The company supplies retailers with several products.
 *      The goal is to allocate each retailer to either division D1 or D2 so that D1 controls A% of the
 *      company’s market for each product and D2 the remaining (100-A)%.
 */

#include "market_split.h"

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

#include "../config.h"
#include "../constraints/linear.h"
#include "../split.h"
#include "../variables.h"

// s4-07 11s
int prods_s4_07[124] = {
43, 19, 59, 97, 14, 19, 44, 90, 57, 74, 83, 66, 95, 24, 91, 49, 59, 89, 54, 90, 71, 69, 49, 19, 72, 97,  9, 19, 75, 79, 	887 ,
63, 19, 99, 74, 68, 13, 45, 65, 55,  3, 39, 38, 21, 87, 63, 12, 36, 74, 54, 42, 64, 77, 12, 66, 96, 36, 63,  5, 55, 39, 	741 ,
85, 70, 10, 84, 96, 78, 49, 42, 43, 56, 97, 35, 94, 18, 22,  9, 83, 10, 35, 89, 53, 52, 66, 17, 18, 63, 53, 33, 20, 60, 	770 ,
24, 57, 83, 34, 41, 79, 65, 42, 73, 60, 98, 70, 47, 45, 41, 21, 54, 24, 32, 90, 13, 37, 42, 79, 54, 12, 94, 59, 45, 67, 	791 };

// s4-10 7s
int prods_s4_10[124] = {
85, 34, 12, 48, 19,  5, 72, 46, 11, 82, 83, 28, 18, 42, 13, 97, 27, 41, 66, 81,  4, 14, 11, 83, 21, 47, 82,  8, 83, 31, 	647 ,
15, 68, 17, 79, 16, 36, 85, 40, 82, 96, 74, 66, 76, 44, 60, 89, 93, 39, 82, 59, 72, 38, 25, 84, 21, 46, 31,  3,  6, 14, 	778 ,
86, 22, 82,  3,  1, 50, 39, 38, 42, 74, 34, 68, 92, 62, 12, 52,  3, 58, 43, 38, 17, 15, 76, 95, 99, 50, 41, 83, 53, 48, 	738 ,
49, 92, 22, 84, 95, 23, 86, 87, 62, 29, 61, 48, 49, 53, 63, 14, 57, 66, 72, 52,  4, 41, 67, 33, 88, 19, 83, 82,  2, 88, 	835 };

// s5-01
int prods_s5_01[205] = {
84, 56, 81, 19, 36, 26, 40, 62, 84, 69, 42, 86, 10, 88, 66, 43, 98,  1, 34, 33, 75, 40, 80, 66, 32,  0, 36, 18, 11, 69, 70, 47, 77, 51, 66, 66, 77, 58, 80, 14, 	1045 ,
79, 23, 52, 90, 63, 18, 33, 61, 71, 67, 46, 98, 59, 78, 16, 91, 30, 53,  9, 93, 74, 79, 41, 52, 82, 59, 18, 12, 70, 50, 26, 49, 73, 78, 39, 88, 48, 25,  1, 72, 	1083 ,
44, 99, 70,  4, 78, 87, 95,  8, 92,  5,  2, 66, 36, 95, 70, 71,  6, 40, 83, 76, 91, 61, 26, 16, 91, 17,  5, 91, 94,  6, 63, 39,  6, 86, 43, 84, 25, 90, 44, 17, 	1061 ,
95, 98, 83, 84, 45,  6, 55, 52, 46, 38, 80, 37, 51, 58, 54, 42, 76, 59, 33, 70, 17, 97, 61, 23, 35, 56, 59, 60, 47,  4, 77, 94, 54, 12, 78,  0, 18, 33,  4, 17, 	1004 ,
23, 84, 54, 74, 95, 60, 68, 71, 71,  2, 93, 89, 51,  7, 64, 38, 63, 76, 98, 10, 32, 27,  5, 86, 39, 35, 86, 10, 69, 42, 27, 44, 27, 33, 71, 74, 94, 39, 97, 17, 	1072 };

// s5-02
int prods_s5_02[205] = {
90, 48, 36, 47, 54, 19, 38, 78, 32, 25, 59, 63, 23, 20, 63, 89, 53,  0, 38, 31, 30, 46, 65,  4, 61,  6, 34, 93, 20, 81, 18, 10, 30,  6, 10, 84, 77, 48, 14,  9, 	 826 ,
25, 74, 24, 49, 46, 88, 90,  0, 40, 80, 83, 70, 27, 49, 26, 40, 55, 13, 34, 76, 94,  4, 38, 76, 10,  0, 61, 39,  1, 27, 49, 26,  1, 25, 27,  0, 65, 18, 52,  5, 	 803 ,
98, 35, 27, 77, 84, 54, 18, 92, 67,  4, 20, 13, 60, 58, 90, 22, 11,  3, 61, 12, 30, 10, 38, 84, 88, 18, 84, 53, 36, 36, 59, 86, 71, 86, 16,  8, 40, 86,  0, 59, 	 947 ,
90, 20, 73,  2, 30, 15, 24, 41, 18, 85,  5, 48, 48, 96, 32, 36, 14, 68, 89,  2, 56, 48, 88, 28, 87, 56, 88, 27, 42, 40, 39, 84, 60, 64, 86, 42, 79, 10, 36, 97, 	 996 ,
96, 41, 45, 44, 89, 30, 80,  3, 50, 21,  5,  7, 70, 46, 87,  9,  2, 75, 88, 45, 15, 27, 29, 27, 91, 68, 69, 70, 78, 57, 19, 26, 99, 17, 22, 88, 47, 54, 44, 97, 	 988 };

// s5-03
int prods_s5_03[205] = {
59, 76, 99, 90, 14, 94, 72, 85, 16, 45,  4, 22, 79, 24, 85, 34, 34, 29, 85, 81,  3, 24, 85, 72, 93, 91, 14, 16, 61, 73, 87, 21,  1, 86, 63, 67, 33, 35,  4, 49, 	1052 ,
33,  8, 71, 64, 33, 57, 50, 67, 38, 35,  1, 93, 59, 38, 66,  5, 29, 32, 73, 91, 57, 61, 64, 58, 99, 79, 25, 32, 67, 29, 34,  0, 38, 57, 16, 23, 66, 67, 90,  5, 	 955 ,
 2, 91, 98, 14, 81, 16, 71, 11,  0, 44, 54, 57, 57, 18, 15, 57, 49, 92, 41, 16, 22, 27, 16, 12, 85, 33, 35, 51, 52, 77,  8, 54, 21, 59, 20,  2, 27, 91, 13, 28, 	 808 ,
36, 19, 85, 93, 37, 53,  2, 39, 45, 96, 55, 19, 23, 24, 31,  8,  9, 18, 12, 61, 96, 20, 15, 17, 31, 36, 19, 59, 27, 85, 87, 15,  4, 24, 61, 94, 77, 63, 33, 75, 	 851 ,
59, 88, 94, 35, 12, 26, 95, 21, 44,  7, 82, 92, 80, 50,  9, 63, 38, 81, 22, 65, 66, 61, 33, 70, 86, 94, 16, 15,  9, 49, 90, 69, 90, 85, 56, 54, 63, 51, 28, 59, 	1103 };

// s5-04
int prods_s5_04[205] = {
70, 50, 88, 54,  8, 35,  3, 95, 44, 26, 87, 12, 69, 26, 70, 42, 55,  5, 80, 96,  0, 15, 90, 25, 39, 19, 84, 42, 47, 24, 98, 17, 75, 38, 23, 35, 25, 26, 30, 69, 	 918 ,
 4, 70, 82, 25, 96,  4, 19,  3, 62, 99, 99, 14, 66, 89, 39, 57,  8, 24, 51,  7,  0, 49, 24, 75, 88, 99, 62, 13, 25, 93, 83, 81, 63, 17,  6, 11, 21, 77, 15, 83, 	 951 ,
76, 14, 97, 94, 56, 37, 52, 64, 13,  3, 72, 13, 53, 48, 41, 93, 48,  3, 58, 25, 48, 41, 59, 11, 58, 17, 75, 32, 95, 42, 15, 71, 56, 65, 18, 64, 54, 70, 29, 67, 	 973 ,
73, 53, 80, 78, 53, 73, 23, 53, 77, 82, 79, 25, 75, 38, 89, 86,  7, 16, 18,  2, 58, 85, 26, 66,  2, 44, 31, 56, 14, 12, 75, 39, 17, 56, 70, 22, 81, 93, 76, 10, 	1006 ,
27,  7, 36,  3, 45, 77, 89, 52, 45, 59,  7, 55, 44, 33, 21, 99, 77,  4, 55, 91, 16, 31, 82, 85, 39,  4,  8, 20, 98, 84, 31, 77, 91, 19, 80, 88, 48, 21, 92, 45, 	 992 };

// s5-05
int prods_s5_05[205] = {
53, 69, 50, 99, 91, 48, 93,  7, 65,  4, 41, 39, 51, 94, 50, 40, 74, 89, 58, 95, 46, 16,  8, 79, 83, 13, 74, 50,  7, 64,  1, 12, 85, 51, 11, 29, 99, 57, 36, 16, 	1023 ,
61, 30,  7, 64, 24, 57, 56, 50, 46, 14, 45, 45, 83,  6, 24, 18, 71, 50, 20, 30, 67, 21, 42, 52, 72,  6, 33, 23, 63, 70, 39, 76,  0, 46, 40, 76, 56, 97, 26, 54, 	 880 ,
63, 24, 99, 98, 30, 75, 16, 53, 78, 89, 83, 45, 10, 25, 49, 35, 31, 35, 58, 46,  5, 50, 22, 57, 48, 15, 33,  4, 12, 11, 11, 75, 87, 62, 74, 69, 90, 42, 22, 68, 	 949 ,
31,  5, 65, 94, 31, 66, 29, 14,  1, 87, 13,  6, 89, 35, 15, 38, 50, 48, 94, 14, 12,  5, 42, 99, 68, 16, 69, 58, 10, 91, 78, 94, 49, 43, 88, 80,  9, 17, 46, 11, 	 905 ,
56, 59, 69, 46, 47, 85, 36, 49, 85, 30, 64, 49, 88, 58, 49,  8, 74, 70, 18, 36, 13, 96, 30, 62, 91, 18, 94, 52, 87, 41, 15, 96, 52, 37, 94, 51, 22, 30,  1, 59, 	1058 };

/*
 * Solve one of the above Market Split problems
 */
void run_market_split(char* csp_inst_name) {
	int n;
	int k;
	unsigned long result;
	int* prods;
	unsigned int* divs;
	int i;

	 if (!strcmp(csp_inst_name, "s4-07")) {
		k = 30;
		n = 4;
		prods = prods_s4_07;
	} else if (!strcmp(csp_inst_name, "s4-10")) {
		k = 30;
		n = 4;
		prods = prods_s4_10;
	} else if (!strcmp(csp_inst_name, "s5-01")) {
		k = 40;
		n = 5;
		prods = prods_s5_01;
	} else if (!strcmp(csp_inst_name, "s5-02")) {
		k = 40;
		n = 5;
		prods = prods_s5_02;
	} else if (!strcmp(csp_inst_name, "s5-03")) {
		k = 40;
		n = 5;
		prods = prods_s5_03;
	} else if (!strcmp(csp_inst_name, "s5-04")) {
		k = 40;
		n = 5;
		prods = prods_s5_04;
	} else if (!strcmp(csp_inst_name, "s5-05")) {
		k = 40;
		n = 5;
		prods = prods_s5_05;
	} else {
		printf("\n%s Market Split problem is not available. Please select an instance from \"csps/market_split.c\" file.\n", csp_inst_name);
		return;
	}

	divs = malloc((unsigned long)k * sizeof(unsigned int));

	for (i = 0; i < k; i++) {
		divs[i] = v_new_range(0, 1, true);
	}

	for (i = 0; i < n; i++) {
		c_linear(&prods[(unsigned int)i * ((unsigned int)k + 1)], divs, (unsigned int)k, prods[(unsigned int)i * ((unsigned int)k + 1) + (unsigned int)k]);
	}

	if (FINDING_ONE_SOLUTION) {
		printf("\nFinding one solution for %s Market Split problem with %d retailers and %d products per retailer.\n", csp_inst_name, n, k);
	} else {
		printf("\nCounting all the solutions for %s Market Split problem with %d retailers and %d products per retailer.\n", csp_inst_name, n, k);
	}

	// Solve the CSP
	result = solve_CSP();

	if (FINDING_ONE_SOLUTION && result == 1) {
		printf("Solution:\n");
		vs_print_single_val(divs, (unsigned int)k, 0);
		printf("\n");
	} else {
		printf("%lu solution(s) found\n", result);
	}

	free(divs);
}