Contagion program, Matrices and Syntax issue - ocaml

I am trying to do the following program:
Write a function onstepcontagion : bool array array -> bool array array = that given a rectangular bool matrix, where true represents an infected square and false represent non-infected square it calculates the next step of infection. Infected squares remain infected indefinitely, non-infected squares become infected if the they are vertically/horizontally adjacent to at least two other infected squares
My code so far:
let printmat matrix =
let n = Array.length matrix in
let n1 = Array.length matrix.(0) in
for i = 0 to n - 1 do
for j = 0 to n1 - 1 do
if matrix.(i).(j) == true then print_string"1"
else print_string"0";
done;
print_string "\n";
done;;
let onstepcontagion matrix =
let n = Array.length matrix in
let n1 = Array.length matrix.(0) in
for i = 0 to n - 1 do
for j = 0 to n1 - 1 do
if (j < n1-1) then
let right = if matrix.(i).(j+1) == true then 1 else 0 in
if (j > 0) then
let left = if matrix.(i).(j-1) == true then 1 else 0 in
if (i < n-1) then
let up = if matrix.(i-1).(j) == true then 1 else 0 in
if (i > 0) then
let down = if matrix.(i+1).(j) == true then 1 else 0 in
let sum = right + left + up + down in
if sum > 1 then matrix.(i).(j) = true
done;
print_string "\n";
done;;
printmat matrix
**Error: Error: This expression has type bool but an expression was expected of type
unit
Characters 1618-1639:
if sum > 1 then matrix.(i).(j) = true **
I have made a C version of the program I want to implement:
#include <stdio.h>
#include <stdlib.h>
void print_mat (int n, int m, int arr[n][m])
{
int i,j;
for (i = 0; i < n; i++){
for (j = 0; j < m; j++)
printf("%d ",arr[i][j]);
printf("\n");
}
printf("\n\n");
}
int main()
{
int n, m, i, j, tmp, changes = 1;
printf("input Mat len\n");
scanf("%d%d",&n,&m);
int arr[n][m];
int cpy[n][m];
for (i = 0; i < n; i++)
for (j = 0; j < m; j++){
scanf("%d",&tmp);
if (tmp == 0)
arr[i][j] = tmp;
else
arr[i][j] = 1;
}
while (changes){
changes = 0;
for (i = 0; i < n; i++){
for (j = 0; j < m; j++)
{
tmp = 0;
if (arr[i][j] != 1){
if (j < m-1)
if (arr[i][j+1] == 1)
tmp++;
if (j > 0)
if (arr[i][j-1] == 1)
tmp++;
if (i < n-1)
if (arr[i+1][j] == 1)
tmp++;
if (i > 0)
if (arr[i-1][j] == 1)
tmp++;
if (tmp > 1){
cpy[i][j] = 1;
changes = 1;
}
}
}
}
if (changes == 1){
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (arr[i][j] == 1 || cpy[i][j] == 1)
arr[i][j] = 1;
printf("\n");
print_mat(n,m, arr);
}
}
return 0;
}

= is the structural equality operator. To set an array element you need to use <-.
Also, you should almost never use == because it tests for physical equality, i.e. that references point to the same address in memory. For comparing bools it doesn't strictly matter, because they're not pointers, but you should get into the habit of using = instead to avoid surprises in the future.

Related

How to find shortest path between every node within K moves?

Lets say I have following graph:
Now what I want is to get shortest path between every node in graph(or have -1 at that place in matrix if it is not possible to get from 1 node to other) , but that path need to have lenght less or same as K.
Now I tried using floyd-warshall algorithm replacing automatically path from 1 node to other if its length is less then K ,but that algorithm did not work on any test cases(not Time limit exceeded but Wrong answer).
This is how I did it:
// N is number of nodes, l is matrix, in l[x][y][0] I have shortest path from x to y and in l[x][y][1] is its lenght
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
//if (this new path is shorter or there is not path yet) and current path lenght is not K(if it already reached max size) and both paths are not -1.
if((l[i][j][0]>l[i][k][0]+l[k][j][0] || l[i][j][0]==-1) && l[i][j][1]<K && l[i][k][0]>-1 && l[k][j][0]>-1){
//change max size
l[i][j][0]=l[i][k][0]+l[k][j][0];
//lenght of that path +=1
l[i][j][1]+=1;
}
}
}
}
for same number(like 3 and 3) I know it is wrong but later when outputing I puted that just print 0.
l[i][j][1]+=1; it's wrong it should actually be l[i][j][1]=l[i][k][1]+l[k][j][1]; but this brakes your solution logic. So i recommend you do like this: count log(K) matrices: i-th matrix means length from j to k in no more than 2^i moves. Look at K in binary and when it-s 1 on i-th place you should recalc your ~current~ matrix with i-th matrix like this (not tested just for show the idea but seems that it would works. maybe should do --K for strict inequality):
#include <iostream>
#include <vector>
int my_log2(int index){
int targetlevel = 0;
while (index >>= 1) ++targetlevel;
return targetlevel;
}
int main(){
int N;
int K;
std::cin >> N >> K;
std::vector < std::vector < std::vector < int > > > dist(my_log2(K), std::vector < std::vector < int > > (N, std::vector < int > (N)));
for (int i = 0; i < N; ++i){
for (int j = 0; j < N; ++j){
// assume weights are positive and -1 if no edge between vertices
// assume that dist[0][i][i] == 0
std::cin >> dist[0][i][j];
}
}
// can be easy rewriten to negative weights with same idea
for (int i = 1; i < my_log2(K); ++i){
for (int j = 0; j < N; ++j){
for (int k = 0; k < N; ++k){
dist[i][j][k] = -1;
for (int l = 0; l < N; ++l){
if (dist[i - 1][j][l] > -1 && dist[i - 1][l][k] > -1 && (dist[i][j][k] == -1 || dist[i][j][k] > dist[i - 1][j][l] + dist[i - 1][l][k])){
dist[i][j][k] = dist[i - 1][j][l] + dist[i - 1][l][k];
}
}
}
}
}
std::vector < std::vector < int > > old_current(N, std::vector < int > (N, -1));
for (int i = 0; i < N; ++i){
old_current[i][i] = 0;
}
for (int i = 0; i < my_log2(K); ++i){
std::vector < std::vector < int > > new_current(N, std::vector < int > (N, -1));
if (((K >> i) & 1) == 1){
for (int j = 0; j < N; ++j){
for (int k = 0; k < N; ++k){
for (int l = 0; l < N; ++l){
if (old_current[j][l] > -1 && dist[i][l][k] > -1 && (new_current[j][k] == -1 || new_current[j][k] > old_current[j][l] + dist[i][l][k])){
new_current[j][k] = old_current[j][l] + dist[i][l][k];
}
if (dist[i][j][l] > -1 && old_current[l][k] > -1 && (new_current[j][k] == -1 || new_current[j][k] > dist[i][j][l] + old_current[l][k])){
new_current[j][k] = dist[i][j][l] + old_current[l][k];
}
}
}
}
}
old_current = new_current;
}
// asnwer is in old_current
}

take 4*4 matrix from user to test if it includes 2*2 sub-matrix have the same value

i just need the user to enter 4*4 matrix of character, the out put will be yes or no according to if there is a 2 * 2 sub-matrix have the same input.
the code is always print false.
the code is:
#include <iostream>
using namespace std;
int main()
{
//input
char color[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
cin >> color[i][j];
}
}
//for testing if there are a squar
// * * * *
// * * # #
// # # * *
// * * # #
// 'yes' as
// * *
// * *
// is a squar of 2*2
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (j != 3) {
if (color[i][j] == color[i][j + 1] == color[i + 1][j] == color[i + 1][j + 1]) {
cout << "yes";
break;
}
else cout << "no";
}
}
}
//for (int i = 0; i < 4; i++) {
//for (int j = 0; j < 4; j++) {
//if (j == 3)
//cout << colors[i][j] <<"\n";
//else
//cout << colors[i][j];
//}
//}
return 0;
}
This condition is wrong:
if (color[i][j] == color[i][j + 1] == color[i + 1][j] == color[i + 1][j + 1]
For simplicity, consider
if (a == b == c)
which is parsed as
if ( (a == b) == c)
The result of a==b is compared to c. The result of a==b is either true or false which can be converted to 1 or 0, respectively.
You would get "yes" printed on the screen when there is a 2x2 submatrix with all elements equal to 1, though it would be for the wrong reasons.
What you actually want is:
if ( a==b && a==c)
Do not ignore your compilers warnings! With the right flags, your code does not compile: https://godbolt.org/z/45oqcTEna.
Moreover, the loop goes outof bounds of the array. You prevent j going out of bounds but when i == 3 then color[i + 1][j] is trying to access an element that does not exist. Instead of iterating till <4 and then excluding j == 3, let the loop only iterate indices that are valid upper left corners of the submatrix:
const size_t size = 4;
const size_t sub_matrix_size = 1;
for (size_t i=0; i < size-sub_matrix_size; ++i) {
for (size_t j=0; j < size-sub_matrix_size; ++j) {
//...

Removing constraint from a model in gurobi c++

I have one constraint set
after some modification I have to remove this constraint:model.addConstr(LHS10_2 <= LHS10_1)set from the model. model.remove() is not working. How can I do it?
Thank for your help.
model.remove(LHS10_2 <= LHS10_1) can not work.
for (i = 1; i <= ULD; i++)
{
for (j = 1; j <= station; j++)
{
GRBLinExpr LHS10_1 = 0;//自載飛航節線
GRBLinExpr LHS10_2 = 0;//他航載飛航節線
for (k = 2; k <= load; k++)
{
if (k == 2 || k == 3 || k == 7)
{
for (l = 1; l <= (node - 2); l++)
{
for (m = 1; m <= Num_FAn[j][k][l]; m++)
{
LHS10_1 += p*X[i][j][k][l][FSAn[j][k][l][m]][FLAn[j][k][l][m]][FNAn[j][k][l][m]];
}
}
}
if (k == 4 || k == 5)
{
for (l = 1; l <= (node - 2); l++)
{
for (m = 1; m <= Num_FAn[j][k][l]; m++)
{
LHS10_2 += X[i][j][k][l][FSAn[j][k][l][m]][FLAn[j][k][l][m]][FNAn[j][k][l][m]];
}
}
}
}
model.addConstr(LHS10_2 <= LHS10_1);
}
}
The method GRBModel::addConstr() returns an GRBConstr object that you should save in a local variable. Then at a later point in time, you can use the GRBModel::remove() method to delete that particular constraint from the model again, i.e., you could do something like
// Array to hold added constraint objects
GRBConstr* c = new GRBConstr[nConstr];
for (int k = 0; k < nConstr, ++k) {
// Create expressions LHS10_2 and LHS10_1 as needed
// [...]
// Add k-th constraint, grap object for later removal from model
c[k] = model.addConstr(LHS10_2 <= LHS10_1);
}
// Do some stuff, optimize, etc.
// [...]
// now delete unwanted constraints from model
for (int k = 0; k < nConstr, ++k) {
model.remove(c[k]);
}

C ignoring incrementation

I tried this but my compiler(Visual Studio 2013) keeps messing up things.
I have a 9 by 9 matrix indexed from 1. It is 0 at the beginig. And starting from element 1:1 I start incrementing the value in the matrix or incrementing x,y, basically moving to the next matrix element.
However, the program ignores my incrementation and the fact that x,y are initially set to 1.
Also it ignores a function call.
Code is commented below.
I am sure this is the source I am compiling!
Restarted laptop and Visual Studio but still doesn't work.
Opened new project, same thing.
Thanks in advance.
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}
You feel that the increment is ignored because the checkSquare function is buggy. It never returned 1 and hence the increment function was never called.
What happens is that you're incrementing the position marked by x and y, that's position [1][1]. Until it reaches 10 nothing interesting happens, you can actually see the top left corner of the matrix increasign to 10, but then the condition to decrement becomes true and you decrement.
See for yourself (prints),
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
printf( "Enter to continue\n" );
getchar();
}
It turns Y = 9, X = 0 and the [1][1] position becomes 0, so you see only zeros because you're not printing the zero indexes.
This process repeats until Y = 1 and X = 0, you increase the position until 10 so that the decrement works again.
When Y = 1, X = 0 and position [0][1] is 10, the decrement call will do x--. Since X is an unsigned int, it will underflow and become 4.2 billion something, which is greater than 10 and the loop ends.
What are you trying to achieve here?
Edit: Something even more amazing happens when you make x and y ints instead of unsigned ints.
Instead of x underflowing it will become -1. Matrix[-1][9]++ strangely increased x by 1 when I ran the code, so x went back to 0. Which means the program loops forever at this point.
The increment function was never called.
It shows matrix and increment when tested online, here are results
1) for C compiler
http://ideone.com/KRLO8w
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}
2) for c++ compiler C++ 4.9.2 (changed return type of main to int)
http://ideone.com/Ey5nG1
In your image starting value of 0, 3 is due to buffer limit of command prompt. As the program never ends, so it terminates abruptly and latest few bytes are stored in buffer and is only shown that much. To see complete output redirect it to a file and open it.
Your output is a bit confusing since the output of the line
printf("%u, %u", x, y);
runs into the output of
print_Matrix();
By adding a newline to the output of the first line, i.e. by using
printf("%u, %u\n", x, y);
you will notice that at some point x gets decremented to 0 and never gets incremented again. Since you never print Matrix[0][y], you never see the non-zero values.
In addition to the change to above printf, if you change print_Matrix to:
void print_Matrix(){
unsigned int i, j;
for (i = 0; i <= 9; i++){
// ^^^ Use 0 instead of 1
for (j = 0; j <= 9; j++)
// ^^^ Use 0 instead of 1
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
you will see the non-zero values.
See working code at http://ideone.com/HlQ4xp.

Regular Matrix in C++

My homework will create a program that check the numbers in an array with a given pattern. Program must take the matrix dimensions and terms in the matrix as arguments from command line. For example program name is myProg.exe and we want to check a 2x3 dimensioned matrix with (maximum dimension limit is 20x20):
1 2 3
4 5 6
Then I will run your program as.
The program will check a special matrix pattern and prints out ACCEPTABLE or NOT MATCH according to the values we put from the console. The Special Pattern: In a row major representation the cells of the matrix must obey this rule. Some terms of the matrix must be sum or product of the neighbor cells. In row major representation the sum and product operations are placed as given in the examples. Sum and Product cells follows each other with one free cells. For Odd rows the sequence starts with free cells and in Even Rows the sequence starts with Sum or Product cell.
My code is here:
#include <iostream>
#include <sstream>
using namespace std;
static int iter = 0;
static unsigned int sat=3, sut=2;
bool ok = false;
int *accepted;
int *array;
string isAcceptable(int mat[]) {
int l, co = 0;
bool operation = false;
int mat2[sat][sut];
for (int i = 0; i < sat; i++) {
for (int j = 0; j < sut; j++) {
mat2[i][j] = mat[co];
co++;
}
}
for (int i = 0; i < sat; i++) {
if (i % 2 == 0)
l = 1;
else
l = 0;
for (int j = l; j < sut; j += 2) {
int totalProduct;
if (!operation) {
totalProduct = 0;
if (j > 0)
totalProduct += mat2[i][j - 1];
if (j < sut - 1)
totalProduct += mat2[i][j + 1];
if (i > 0)
totalProduct += mat2[i - 1][j];
if (i < sat - 1)
totalProduct += mat2[i + 1][j];
} else {
totalProduct = 1;
if (j > 0)
totalProduct *= mat2[i][j - 1];
if (j < sut - 1)
totalProduct *= mat2[i][j + 1];
if (i > 0)
totalProduct *= mat2[i - 1][j];
if (i < sat - 1)
totalProduct *= mat2[i + 1][j];
}
if (mat2[i][j] != totalProduct)
return "NOT MATCH";
operation = !operation;
}
}
return "ACCEPTABLE";
}
void change(int index1, int index2) {
int temp;
temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
iter++;
}
void combine(int mat[], int len) {
if(ok)
return;
array = new int[len];
*array = *mat;
if (len <= sat * sut) {
for (int i = len; i < sat * sut - 1; i++) {
for (int j = i; j < sat * sut; j++) {
combine(array, len + 1);
change(i, j);
if (isAcceptable(array) == ("ACCEPTABLE")) {
int accepted[sat*sut];
*accepted = *array;
ok = true;
return;
}
}
}
} else
return;
}
string isAcceptableCombine(int mat[]) {
combine(mat, 6);
if (ok)
{
cout<< " TRUE Sequense";
return "ACCEPTABLE";
}
else
cout<< " FALSE Sequense";
return "NOT MATCH";
}
int main(int argc, char** argv) {
int matris[] = {1,2,1,4,1,6};
isAcceptableCombine(matris);
}
My code's result is always returning TRUE Sequence.
Where is my mistake?