Blame view

Debug/src/csps/steiner.c 2.59 KB
0c8ce2b0   Pedro Roque   missing files
1
2
3
4
/*
 * steiner_triples.c
 *
 *  Created on: 26/03/2017
4d26a735   Pedro Roque   Increased recogni...
5
 *      Author: Pedro
0c8ce2b0   Pedro Roque   missing files
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 *      http://www.csplib.org/Problems/prob044/
 *      https://github.com/MiniZinc/minizinc-benchmarks/tree/master/steiner-triples
 *
 *		Steiner Triples:
 *      The following program computes so-called Steiner triplets. These are triplets
 *      of numbers from 1 to n such that any two triplets have at most one element in common.
 */

#include "steiner.h"

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

#include "../config.h"
#include "../constraints/at_most_one.h"
4d26a735   Pedro Roque   Increased recogni...
23
24
25
#include "../constraints/int_le.h"
#include "../constraints/int_lin_var.h"
#include "../constraints/int_lt.h"
0c8ce2b0   Pedro Roque   missing files
26
27
28
29
30
31
#include "../split.h"
#include "../variables.h"

/*
 * Solve an instance of Steiner Triples problems with N numbers
 */
4d26a735   Pedro Roque   Increased recogni...
32
void run_steiner(int *csp_dims) {
0c8ce2b0   Pedro Roque   missing files
33
34
35
	int n = csp_dims[0];
	unsigned long result;
	int n_triples = (n * (n - 1)) / 6;
4d26a735   Pedro Roque   Increased recogni...
36
37
38
39
	unsigned int *sum_vs_id = malloc((unsigned long) n_triples * sizeof(unsigned int));
	int cs[] = { (n + 1) * (n + 1), n + 1, 1 };
	unsigned int *triples = malloc((unsigned long) n_triples * 3 * sizeof(unsigned int));
	int *cards = malloc((unsigned long) n_triples * sizeof(int));
0c8ce2b0   Pedro Roque   missing files
40
41
42
	int i;

	for (i = 0; i < n_triples * 3; i++) {
4d26a735   Pedro Roque   Increased recogni...
43
		triples[i] = v_new_range(0, (unsigned int) n - 1, true);
0c8ce2b0   Pedro Roque   missing files
44
45
46
47
48
49
	}

	for (i = 0; i < n_triples; i++) {
		cards[i] = 3;
	}

4d26a735   Pedro Roque   Increased recogni...
50
	c_at_most_one(triples, cards, (unsigned int) n_triples);
0c8ce2b0   Pedro Roque   missing files
51
52

	for (i = 0; i < n_triples; i++) {
4d26a735   Pedro Roque   Increased recogni...
53
54
55
		c_int_lt(triples[i * 3], triples[i * 3 + 1]);
		c_int_lt(triples[i * 3], triples[i * 3 + 2]);
		c_int_lt(triples[i * 3 + 1], triples[i * 3 + 2]);
0c8ce2b0   Pedro Roque   missing files
56

4d26a735   Pedro Roque   Increased recogni...
57
58
59
		sum_vs_id[i] = v_new_range(0,
				((unsigned int) n + 1) * ((unsigned int) n + 1) * (unsigned int) n + ((unsigned int) n + 1) * ((unsigned int) n - 1) + (unsigned int) n - 2,
				false);
0c8ce2b0   Pedro Roque   missing files
60

4d26a735   Pedro Roque   Increased recogni...
61
		c_int_lin_var(cs, &triples[i * 3], 3, sum_vs_id[i]);
0c8ce2b0   Pedro Roque   missing files
62
63
64
65
	}

	// Symmetry breaking
	for (i = 1; i < n_triples; i++) {
4d26a735   Pedro Roque   Increased recogni...
66
		c_int_le(sum_vs_id[i - 1], sum_vs_id[i]);
0c8ce2b0   Pedro Roque   missing files
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
	}

	if (FINDING_ONE_SOLUTION) {
		printf("\nFinding one solution for Steiner Triples with N=%u.\n", n);
	} else {
		printf("\nCounting all the solutions for Steiner Triples with N=%u.\n", n);
	}

	// Solve the CSP
	result = solve_CSP();

	if (FINDING_ONE_SOLUTION && result == 1) {
		printf("Solution:\n");

		printf("{%u,%u,%u}", v_get_min(triples[0]) + 1, v_get_min(triples[1]) + 1, v_get_min(triples[2]) + 1);
		for (i = 1; i < n_triples; i++) {
			printf(",{%u,%u,%u}", v_get_min(triples[i * 3]) + 1, v_get_min(triples[i * 3 + 1]) + 1, v_get_min(triples[i * 3 + 2]) + 1);
		}
		printf("\n");

	} else {
		printf("%lu solution(s) found\n", result);
	}

	free(triples);
	free(cards);
	free(sum_vs_id);
}