Unable to find the optimal cost of pairing elements of two sets - c

Given two sets of natural number A and B of size n such that each member of A has to be paired to at at most one member of B. There is also cost associated with each pairing i.e if the absolute difference b\l sum of all n-length possible pair permutations of elements of A with B.

The following (crude and far from being optimized and safe -- I used a global variable: horror!) code does the job:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
int factorial(int N) {
int product = 1;
for (int j = 1; j <= N; j++)
product *= j;
return product;
}
// Prints the array
void printArr(int a[], int n)
{
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
// Stores the array
void storeArr(int a[], int n, int counter, int** out)
{
for (int i = 0; i < n; i++) {
out[counter][i] = a[i];
}
}
int get_cost(int a, int b) {
int diff = abs(a - b);
if (diff >= 5 && diff < 10) {
return 0;
}
else if (diff < 5) {
return 1;
}
else {
return 2;
}
}
int cost_perm(int* a, int* b, int n) {
int cost = 0;
for (int i = 0; i < n; ++i) {
cost += get_cost( a[i], b[i] );
}
return cost;
}
// Globals are bad but...
int counter;
// Generating permutation using Heap Algorithm
void heapPermutation(int a[], int size, int n, int** out)
{
// if size becomes 1 then stores the obtained
// permutation
if (size == 1) {
storeArr(a, n, counter++, out);
return;
}
for (int i = 0; i < size; i++) {
heapPermutation(a, size - 1, n, out);
// if size is odd, swap 0th i.e (first) and
// (size-1)th i.e (last) element
if (size % 2 == 1)
SWAP(a[0], a[size - 1], int);
// If size is even, swap ith and
// (size-1)th i.e (last) element
else
SWAP(a[i], a[size - 1], int);
}
}
// Driver code
int main()
{
int a[] = { 169, 165, 161, 131, 145 };
int b[] = { 214, 174, 218, 188, 168 };
int n = sizeof a / sizeof a[0];
int numperm = factorial(n);
int** perm_of_a = calloc(numperm, sizeof(int*));
int** perm_of_b = calloc(numperm, sizeof(int*));
for (int i = 0; i < numperm; ++i) {
perm_of_a[i] = calloc(n, sizeof(int));
perm_of_b[i] = calloc(n, sizeof(int));
}
counter = 0;
heapPermutation(a, n, n, perm_of_a);
counter = 0;
heapPermutation(b, n, n, perm_of_b);
int min_cost = 1000;
int cost;
int mina = 0;
int minb = 0;
for (int i = 0; i < numperm; ++i) {
for (int j = 0; j < numperm; ++j) {
cost = cost_perm(perm_of_a[i], perm_of_b[j], n);
if (cost < min_cost) {
min_cost = cost;
mina = i;
minb = j;
}
}
}
printArr( perm_of_a[mina], n );
printArr( perm_of_b[minb], n );
printf( "%d\n", min_cost );
return 0;
}

You are trying to find one individual pair at each iteration, but you want to minimize the cost over all permutations.
You need to figure out how to generate all permutations of a vector and use code like this:
for permuted_A in all_permutations_of_A
for permuted_B in all_permutations_of_B
cost = cost(permuted_A, permuted_B)
if cost < min_cost
min_cost = cost
min_permuted_A = permuted_A
min_permuted_B = permuted_B
Once you figure out how to enumerate the permutations, the rest will be trivial.

Related

C programming find the second positive number in the second half of an array

My code is this:
#include <stdio.h>
int array_second_positive(int A[], int size) {
int j, i;
for (i = 0; i < size / 2; ++i) {
A[i] = A[0];
for (j = 0; j < size; ++j) {
A[j] = A[j + 1];
}
}
for (i = 0; i < size; ++i) {
int z = 0;
int counter = 0;
while (z < size) {
if (A[z] > 0) {
counter++;
}
if (counter == 2) {
return A[z];
}
z++;
}
}
}
int main(void) {
int size = 6;
int array[] = { 3, -14, 15, 2, 6, 5 };
int result = array_second_positive(array, size);
}
I am trying to find the second positive number in the second half of an array. If we assume array size is even and we have definitely at least two positive number in the second half but I get no results.

iterative permute function in C

I'm trying to write an iterative function that computes all the permutations of an array of numbers given in input.
Here is the code I've written so far.
void permute(int *a, int size){
int j=0, i, h=0, m;
bool flag=true;
int f = factorial(size);
int *arr, *res;
int counter=0;
arr = malloc(f*sizeof(int));
for(i=0; i<f; i++)
arr[i] = 0;
while (j < f) {
if(arr[j]<j)
{
if(j%2 == 0)
{
swap(a[0],a[j]);
} else {
swap(a[arr[j]], a[j]);
}
arr[j]++;
j=0;
} else{
arr[j] = 0;
j++;
}
printf("%d\n",a[j] );
}
}
The code doesn't compute well all the permutations and goes into a long loop. Can someone help me, please? Thanks to everyone.
Your code is close but includes some problems. For instance, the while loop
while (j < f) will assign j to a value out of bound of the array a.
Instead would you please try:
#include <stdio.h>
#include <stdlib.h>
int factorial(int x)
{
int i;
int y = 1;
for (i = 1; i <= x; i++) {
y *= i;
}
return y;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(int *a, int size)
{
int i, j = 0;
int f = factorial(size);
int *arr;
arr = calloc(f, sizeof(int)); // the members are initialized to 0
// print the original array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
while (j < size) {
if (arr[j] < j) {
if (j % 2 == 0) {
swap(a + 0, a + j);
} else {
swap(a + arr[j], a + j);
}
// print the rearranged array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
arr[j]++;
j = 0;
} else {
arr[j] = 0;
j++;
}
}
free(arr);
}
int main()
{
int a[] = {1, 2, 3}; // example
permute(a, sizeof a / sizeof a[0]); // the 2nd argument is the array length
return 0;
}
Output of the example:
1 2 3
2 1 3
3 1 2
1 3 2
2 3 1
3 2 1

Unable to count sort more than eight elements

Here is my code. While choosing values, if I try to put 9 values it dumps garbage value. It has happened while doing quick sort as well
#include <stdio.h>
void printArray(int* A, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", A[i]);
}
printf("\n");
}
int maximum(int A[],int n) {
int i, max = A[0];
for (i = 1; i < n; i++) {
if (A[i] > max) {
max = A[i];
}
}
return max;
}
void countSort(int A[], int n) {
int i, max = maximum(A, n);
int count[max + 1], B[n];
for (i = 0; i < max + 1; i++) {
count[i] = 0;
}
for (i = 0; i < max + 1; i++) {
count[A[i]]++;
}
for (i = 1; i < n; i++) {
count[i] += count[i - 1];
}
for (i = n - 1; i >= 0; i--) {
B[--count[A[i]]] = A[i];
}
for (i = 0; i < n; i++) {
A[i] = B[i];
}
}
int main(){
int A[] = {1, 4, 6, 2, 3, 2, 3, 2, 7};
int n = 9;
printArray(A, n); // Printing the array before sorting
countSort(A, n); // Function to sort the array
printArray(A, n); // Printing the array before sorting
return 0;
}
This code uses the wrong limit:
for(i=0;i<max+1;i++) {
count[A[i]]++;
}
It effectively iterates through the elements of A, which has n elements, not max+1.

I'm having some troubles understanding how pointers work in c

So I try to do the Heap Sort in C for a row of an 2d array
So basically I find the smallest sum of all the rows from the array and I try to sort the elements of that row, for that I'm trying to store the index of the smallest row with a pointer but when I use pointer the programm it's not returning the index but the adress
//funcion to find the smallest row sum
void min_rand(int(*a)[50], int n, int m, int *mi)
{
int min_row = 0;
int i, j;
for (j = 0; j < m; j++)
min_row += a[0][j];
for (i = 0; i < n; i++) {
int sum_row = 0;
for (j = 0; j < m; j++)
sum_row += a[i][j];
if (sum_row < min_row) {
min_row = sum_row;
*mi = i;
}
}
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void heapify_c(int(*a)[50], int n, int i, int mi)
{
int largest = i;
int l = 2 *i + 1;
int r = 2 *i + 2;
if (l < n && a[mi][l] > a[mi][largest])
largest = l;
if (r < n && a[mi][r] > a[mi][largest])
largest = r;
if (largest != i) {
swap(&a[mi][i], &a[mi][largest]);
heapify_c(a, n, largest, mi);
}
}
void heapSort_c(int(*a)[50], int n, int mi)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify_c(a, n, i, mi);
for (int i = n - 1; i > 0; i--) {
swap(&a[mi][0], &a[mi][i]);
heapify_c(a, i, 0, mi);
}
}
int main()
{
int a[50][50];
int n, m, mi;
min_rand(a, n, m, &mi);
heapSort_c(a, n, mi);
return 0;
}
I don't print the sorted elements in the e.g. above but I just want to know if I'm doing something so terrebly wrong cause I did this before with counting sort and it worked without any problems

Local variable loses its value: selection sort algorithm

I previously tested the same variable called "swaps" for bubble sort algorithm and it worked perfectly. Now, with selection sorting, variable loses its value even after incrementing it.
Any help will be very much appreciated.
int list[] = {10, 5, 6, 3, 4, 11, 9, 7, 2};
int min = list[0], pos = 0, temp_max = 0;
// Loop until no swap is needed
for (int j = 0, n = sizeof(list) / sizeof(int); j < n; j++)
{
int swaps = 0,
// Iterate through array to find min value
for (int i = j, y = sizeof(list) / sizeof(int); i < y; i++)
{
if (list[i] < min)
{
min = list[i];
pos = i;
}
}
// Insert min value in left most position and add 1 to swaps, meaning array is not yet sorted
if (pos > j)
{
temp_max = list[j];
list[j] = min;
list[pos] = temp_max;
swaps++;
}
// The error might occur here: "swaps" keeping value 0 after previous if statement ends
printf ("swaps = %d\n", swaps);
// If no swaps ocurred, array is sorted
if (swaps == 0)
{
// Print sorted array and return
}
}
Move the declaration int swaps = 0 outside the for loop.
In other words, change this:
for (int j = 0, n = sizeof(list) / sizeof(int); j < n; j++)
{
int swaps = 0;
...
}
To this:
int swaps = 0;
for (int j = 0, n = sizeof(list) / sizeof(int); j < n; j++)
{
...
}
I want to thank you all very much. I have solved the problem with your help. Turns out the error had to do with the variable scope (where it was declared). Follow below the working code.
int main (void)
{
//Declare list to be sorted and other variables
int list[] = {9, 5, 7, 8, 4, 3, 2, 1, 6};
int minValPos = 0, maxTempVal = list[0];
for (int j = 0, siz = sizeof (list) / sizeof (int); j < siz; j++)
{
int swaps = 0, minVal = list[j];
// Look for min value after each j iteration
for (int i = j; i < siz; i++)
{
// Find minimum value (minVal) and store its position (minValPos)
if (list[i] < minVal)
{
minVal = list[i];
minValPos = i;
}
}
// Once with MinVal pinpointed, proceed to swap with jth item
if (minValPos > j)
{
maxTempVal = list[j];
list[j] = minVal;
list[minValPos] = maxTempVal;
swaps++;
}
// When array did not need any swaps, it means it is sorted
if (swaps == 0)
{
for (int r = 0; r < siz; r++)
{
printf ("Position [%d] = %d\n", r, list[r]);
}
}
}
}
That means your if statement is not becoming true in the meantime.
min should be set in each loop of j.
min=list[j] in for(j=...){min=list[j]; ... }
And also pos=j
Adding to the other answers, which will fix the problem specifically with your code, you can also approach the selection sort algorithm like this.
Steps to writing this algorithm for an array:
1. Write a helper function to find the index of the biggest element in the array:
size_t index_of_largest(int list[], size_t n) {
size_t i, biggest;
biggest = 0;
for (i = 0; i < n; i++) {
if (list[i] > list[biggest]) {
biggest = i;
}
}
return biggest;
}
2. Iterate over i=n to i=1, and find the biggest value between list[0] and list[i-1]. After this element is found, swap it into the last position. The function could look like this:
void sort_list(int list[], size_t n) {
size_t i, biggest;
for (i = n; i > 0; i--) {
biggest = index_of_largest(list, i);
int_swap(&list[biggest], &list[i-1]); /* swapping function */
}
}
3. Considering these ideas, you can write a simple version of the algorithm like this:
#include <stdio.h>
void sort_list(int list[], size_t n);
size_t index_of_largest(int list[], size_t n);
void print_array(int list[], size_t n);
void int_swap(int *x, int *y);
int main(void) {
int list[] = {10, 5, 6, 3, 4, 11, 9, 7, 2};
size_t n = sizeof list / sizeof *list;
printf("Before: ");
print_array(list, n);
sort_list(list, n);
printf("After: ");
print_array(list, n);
return 0;
}
void sort_list(int list[], size_t n) {
size_t i, biggest;
for (i = n; i > 0; i--) {
biggest = index_of_largest(list, i);
int_swap(&list[biggest], &list[i-1]);
}
}
size_t index_of_largest(int list[], size_t n) {
size_t i, biggest;
biggest = 0;
for (i = 0; i < n; i++) {
if (list[i] > list[biggest]) {
biggest = i;
}
}
return biggest;
}
void print_array(int list[], size_t n) {
size_t i;
for (i = 0; i < n; i++) {
printf("%d ", list[i]);
}
printf("\n");
}
void int_swap(int *x, int *y) {
int temp;
temp = *x;
*x = *y;
*y = temp;
}
Output:
Before: 10 5 6 3 4 11 9 7 2
After: 2 3 4 5 6 7 9 10 11
Compiled with:
gcc -Wall -Wextra -o progname progname.c

Resources