Two-bit branch prediction should give higher percentage - branch-prediction

I have small program that is supposed to calculate percentage of successfull predicition of a 2-bit branch predictor. I have it all done but my output isn't what I have expected, the percantage stops at about 91% instead of what I think should be at 98% or 99%. I think the problem might be with how apply the mask to the address. Can some one look at my code and verify if that is the issue.
The program iterates through a file that has a branch history of a run of the gcc compiler consisting of about 1792 addresses and a single digit column with 1 for a branch taken and a 0 for a branch not taken.
static void twoBitPredictor_v1(StreamWriter sw)
{
uint hxZero = 0x000000000;
uint uMask1 = 0x00000000;
int nCorrectPrediction = 0;
uint uSize2;
int nSize;
int nTotalReads;
int nTableMin = 2;
int nTableMax = 16;
int nTaken = 0;
uint[] uArrBt1;
sw.WriteLine("\n\nTwo-Bit Predictor Results Ver. 1\n");
sw.WriteLine("-------------------------\n");
sw.WriteLine("Total" + "\t" + "Correct");
sw.WriteLine("Reads" + "\t" + "Prediction" + "\t" + "Percentage");
System.Console.WriteLine("\n\nTwo-Bit Predictor Results Ver. 1\n");
System.Console.WriteLine("-------------------------\n");
System.Console.WriteLine("Total" + "\t" + "Correct");
System.Console.WriteLine("Reads" + "\t" + "Prediction" + "\t" + "Percentage");
for (int _i = nTableMin; _i <= nTableMax; _i++)
{
StreamReader sr2 = new StreamReader(#"C:\Temp\gccHist.txt");
nSize = _i;
uSize2 = (uint)(Math.Pow(2, nSize));
uArrBt1 = new uint[2 * uSize2];
for (int i = 0; i < uSize2; i++)
uArrBt1[i] = hxZero;
nCorrectPrediction = 0;
nTotalReads = 0;
while (!sr2.EndOfStream)
{
String[] strLineRead = sr2.ReadLine().Split(',');
uint uBRAddress = Convert.ToUInt32(strLineRead[0], 16);
uint bBranchTaken = Convert.ToUInt32(strLineRead[2]);
>>>>> In the line below is where I think lies the problem but not sure how to correct it.
uMask1 = uBRAddress & (0xffffffff >> 32 - nSize);
int _mask = Convert.ToInt32(uMask1);
nTaken = Convert.ToInt32(uArrBt1[2 * _mask]);
switch (Convert.ToInt32(uArrBt1[_mask]))
{
case 0:
if (bBranchTaken == 0) // Branch Not Taken
nCorrectPrediction++;
else
uArrBt1[_mask] = 1;
break;
case 1:
if (bBranchTaken == 0)
{
uArrBt1[_mask] = 0;
nCorrectPrediction++;
}
else
uArrBt1[_mask] = 3;
break;
case 2:
if (bBranchTaken == 0)
{
uArrBt1[_mask] = 3;
nCorrectPrediction++;
}
else
uArrBt1[_mask] = 0;
break;
case 3:
if (bBranchTaken == 0)
uArrBt1[_mask] = 2;
else
nCorrectPrediction++;
break;
}
nTotalReads++;
}
sr2.Close();
double percentage = ((double)nCorrectPrediction / (double)nTotalReads) * 100;
sw.WriteLine(nTotalReads + "\t" + nCorrectPrediction + "\t\t" + Math.Round(percentage, 2) + "%");
System.Console.WriteLine(nTotalReads + "\t" + nCorrectPrediction + "\t\t" + Math.Round(percentage, 2) + "%");
}
}
Here is the output:
Two-Bit Predictor Results Ver. 1
-------------------------
Total Correct
Reads Prediction Percentage
1792 997 55.64%
1792 997 55.64%
1792 1520 84.82%
1792 1522 84.93%
1792 1521 84.88%
1792 1639 91.46%
1792 1651 92.13%
1792 1649 92.02%
1792 1649 92.02%
1792 1648 91.96%
1792 1646 91.85%
1792 1646 91.85%
1792 1646 91.85%
1792 1646 91.85%
1792 1646 91.85%

Related

Multithreaded Nagel–Schreckenberg model (traffic simulation) with OpenMP

I'm trying to write a multithreaded Nagel–Schreckenberg model simulation in c language and have some problems when a thread accesses the data which wasn't calculated yet.
Here is a working code which only parallelizes velocity calculation per line:
#define L 3000 // number of cells in row
#define num_iters 3000 // number of iterations
#define density 0.48 // how many positives
#define vmax 2
#define p 0.2
for (int i = 0; i < num_iters - 1; i++)
{
int temp[L] = {0};
#pragma omp parallel for
for (int x = 0; x < L; x++)
{
if (iterations[i][x] > -1)
{
int vi = iterations[i][x]; // velocity of previews iteration
int d = 1; // index of the next vehicle
while (iterations[i][(x + d) % L] < 0)
d++;
int vtemp = min(min(vi + 1, d - 1), vmax); // increase speed, but avoid hitting the next car
int v = r2() < p ? max(vtemp - 1, 0) : vtemp; // stop the vehicle with probability p
temp[x] = v;
}
}
for (int x = 0; x < L; x++) // write the velocities to the next line
{
if (iterations[i][x] > -1)
{
int v = temp[x];
iterations[i + 1][(x + v) % L] = v;
}
}
}
This works fine, but it's not fast enough. I'm trying to use convolution to increase the performance, but it can't read neighbor thread's data half of the time because it wasn't calculated yet. Here is the code I used:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
#define L 4000 // number of cells in row
#define num_iters 4000 // number of iterations
#define density 0.48 // how many positives
#define vmax 2
#define p 0.2
#define BLOCKS_Y 4
#define BLOCKS_X 4
#define BLOCKSIZEY (L / BLOCKS_Y)
#define BLOCKSIZEX (L / BLOCKS_X)
time_t t;
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
void shuffle(int *array, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
double r2()
{
return (double)rand() / (double)RAND_MAX;
}
void writeImage(int *iterations[], char filename[])
{
int h = L;
int w = num_iters;
FILE *f;
unsigned char *img = NULL;
int filesize = 54 + 3 * w * h;
img = (unsigned char *)malloc(3 * w * h);
memset(img, 0, 3 * w * h);
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
int x = i;
int y = (h - 1) - j;
int color = iterations[i][j] == 0 ? 0 : 255;
img[(x + y * w) * 3 + 2] = (unsigned char)(color);
img[(x + y * w) * 3 + 1] = (unsigned char)(color);
img[(x + y * w) * 3 + 0] = (unsigned char)(color);
}
}
unsigned char bmpfileheader[14] = {'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0};
unsigned char bmpinfoheader[40] = {40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0};
unsigned char bmppad[3] = {0, 0, 0};
bmpfileheader[2] = (unsigned char)(filesize);
bmpfileheader[3] = (unsigned char)(filesize >> 8);
bmpfileheader[4] = (unsigned char)(filesize >> 16);
bmpfileheader[5] = (unsigned char)(filesize >> 24);
bmpinfoheader[4] = (unsigned char)(w);
bmpinfoheader[5] = (unsigned char)(w >> 8);
bmpinfoheader[6] = (unsigned char)(w >> 16);
bmpinfoheader[7] = (unsigned char)(w >> 24);
bmpinfoheader[8] = (unsigned char)(h);
bmpinfoheader[9] = (unsigned char)(h >> 8);
bmpinfoheader[10] = (unsigned char)(h >> 16);
bmpinfoheader[11] = (unsigned char)(h >> 24);
f = fopen(filename, "wb");
fwrite(bmpfileheader, 1, 14, f);
fwrite(bmpinfoheader, 1, 40, f);
for (int i = 0; i < h; i++)
{
fwrite(img + (w * (h - i - 1) * 3), 3, w, f);
fwrite(bmppad, 1, (4 - (w * 3) % 4) % 4, f);
}
free(img);
fclose(f);
}
void simulation()
{
printf("L=%d, num_iters=%d\n", L, num_iters);
int z = 0;
z++;
int current_index = 0;
int success_moves = 0;
const int cars_num = (int)(density * L);
int **iterations = (int **)malloc(num_iters * sizeof(int *));
for (int i = 0; i < num_iters; i++)
iterations[i] = (int *)malloc(L * sizeof(int));
for (int i = 0; i < L; i++)
{
iterations[0][i] = i <= cars_num ? 0 : -1;
}
shuffle(iterations[0], L);
for (int i = 0; i < num_iters - 1; i++)
for (int x = 0; x < L; x++)
iterations[i + 1][x] = -1;
double *randoms = (double *)malloc(L * num_iters * sizeof(double));
for (int i = 0; i < L * num_iters; i++) {
randoms[i] = r2();
}
#pragma omp parallel for collapse(2)
for (int blocky = 0; blocky < BLOCKS_Y; blocky++)
{
for (int blockx = 0; blockx < BLOCKS_X; blockx++)
{
int ystart = blocky * BLOCKSIZEY;
int yend = ystart + BLOCKSIZEY;
int xstart = blockx * BLOCKSIZEX;
int xend = xstart + BLOCKSIZEX;
for (int y = ystart; y < yend; y++)
{
for (int x = xstart; x < xend; x++)
{
if (iterations[y][x] > -1)
{
int vi = iterations[y][x];
int d = 1;
int start = (x + d) % L;
int i;
for (i = start; i < L && iterations[y][i] < 0; ++i);
d += i - start;
if (i == L)
{
for (i = 0; i < start && iterations[y][i] < 0; ++i);
d += i;
}
int vtemp = min(min(vi + 1, d - 1), vmax);
int v = randoms[x * y] < p ? max(vtemp - 1, 0) : vtemp;
iterations[y + 1][(x + v) % L] = v;
}
}
}
}
}
if (L <= 4000)
writeImage(iterations, "img.bmp");
free(iterations);
}
void main() {
srand((unsigned)time(&t));
simulation();
}
As you can see, as the second block gets calculated the first one didn't probably calculate yet which produces that empty space.
I think it's possible to solve this with the convolution, but I'm just doing something wrong and I'm not sure what. If you could give any advice on how to fix this problem, I would really appreciate it.
There is a race condition in the second code because iterations can be read by a thread and written by another. More specifically, iterations[y + 1][(x + v) % L] = v set a value that another thread should read when checking iterations[y][x] or iterations[y][(x + d) % L] when two threads are working on consecutive y values (of two consecutive blocky values).
Moreover, the r2 function have to be thread-safe. It appears to be a random number generator (RNG), but such random function is generally implemented using global variables that are often not thread-safe. One simple and efficient solution is to use thread_local variables instead. An alternative solution is to explicitly pass in parameter a mutable state to the random function. The latter is a good practice when you design parallel applications since it makes visible the mutation of an internal state and it provides way to better control the determinism of the RNG.
Besides this, please note that modulus are generally expensive, especially if L is not a compile-time constant. You can remove some of them by pre-computing the remainder before a loop or splitting a loop so to perform checks only near the boundaries. Here is an (untested) example for the while:
int start = (x + d) % L;
int i;
for(i=start ; i < L && iterations[y][i] < 0 ; ++i);
d += i - start;
if(i == L) {
for(i=0 ; i < start && iterations[y][i] < 0 ; ++i);
d += i;
}
Finally, please note that the blocks should be divisible by 4. Otherwise, the current code is not valid (a min/max clamping is likely needed).

CS50 Pset4 Sepia Filter, where is the bug? The code doesn't pass the CS50 tests

So this is the code I have for Pset4 for the Sepia filter...it's heading in the right direction but I've been trying to figure out why it isn't passing the tests. Cannot filter a simple 3 x 3 image or complex 3 x 3 image or the 4 x 4 image. Trying to figure out where the bug is, any tips would be wonderful!
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// get values of each colour in the image
int red = image[i][j].rgbtRed;
int blue = image[i][j].rgbtBlue;
int green = image[i][j].rgbtGreen;
// find average of the pixel RBG colors
float average = (round(red) + round(blue) + round(green)) / 3;
average = round(average);
//puts the value average into the pixel colors
image[i][j].rgbtRed = average;
image[i][j].rgbtBlue = average;
image[i][j].rgbtGreen = average;
}
}
return;
}
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//gets the values of each color in the image
int red = image[i][j].rgbtRed;
int blue = image[i][j].rgbtBlue;
int green = image[i][j].rgbtGreen;
// gets the sepia value of the pixels
int sepiaRed = round(0.393 * red + 0.769 * green + 0.189 * blue);
int sepiaGreen = round(0.349 * red + 0.686 * green + 0.168 * blue);
int sepiaBlue = round(0.272 * red + 0.534 * green + 0.131 * blue);
if (sepiaRed >= 256)
{
sepiaRed = 255;
}
if (sepiaGreen >= 256)
{
sepiaGreen = 255;
}
if (sepiaBlue >= 256)
{
sepiaBlue= 255;
}
image[i][j].rgbtRed = sepiaRed;
image[i][j].rgbtBlue = sepiaBlue;
image[i][j].rgbtGreen = sepiaGreen;
}
return;
}
}
I'm not sure, without seeing more of the code. But shouldn't these three ifs at the end be placed before you save their values to the image? Like this:
...
if (sepiaRed >= 256)
{
sepiaRed = 255;
}
if (sepiaGreen >= 256)
{
sepiaGreen = 255;
}
if (sepiaBlue >= 256)
{
sepiaBlue = 255;
}
image[i][j].rgbtRed = sepiaRed;
image[i][j].rgbtBlue = sepiaBlue;
image[i][j].rgbtGreen = sepiaGreen;
...
First You check if calculated values are not higher than 255. Then save these values to the image.
Also you should replace 'else if' with 'if' to check all 3 values not up to one. And then edit value of sepiaRed, sepiaBlue, sepiaGreen not red, blue, green.
I'm not sure if I get right what that function suppose to do.
you have to use the math function round(), mine just working fine.
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//gets the values of each color in the image
int red = image[i][j].rgbtRed;
int blue = image[i][j].rgbtBlue;
int green = image[i][j].rgbtGreen;
// gets the sepia value of the pixels
int sepiaRed = round(0.393 * red + 0.769 * green + 0.189 * blue) ;
int sepiaGreen = round(0.349 * red + 0.686 * green + 0.168 * blue) ;
int sepiaBlue = round(0.272 * red + 0.534 * green + 0.131 * blue) ;
if (sepiaRed >= 256)
{
sepiaRed = 255;
}
if (sepiaGreen >= 256)
{
sepiaGreen = 255;
}
if (sepiaBlue >= 256)
{
sepiaBlue= 255;
}
image[i][j].rgbtRed = sepiaRed;
image[i][j].rgbtBlue = sepiaBlue;
image[i][j].rgbtGreen = sepiaGreen;
}
}

Groovy Turkish tax number verification

I need to calculate Turkish Tax number via Groovy.. Basically it's 10 digit number..
Here is the math behind it..
First 9 digit number (d), last 10 digit control ( c )value
Tr tax number = d1 d2 d3 d4 d5 d6 d7 d8 d9 c1
So d1..d9 >> d[i]
p[i] = (d[i] + 10 — i) mod 10
p[i] = 9 => q[i] = 9
p[i] != 9 => q[i] = (p[i] * 2^(10 — i)) mod 9
c1 = (10 — (Σ q[i] mod 10)) mod 10
Let’s say tax number : 018273645x
p[1] = ( d[1] + 10–1 ) mod 10 = (0 + 10–1) mod 10 = 9
p[2] = ( d[2] + 10–2) mod 10 = (1 + 10–2) mod 10 = 9
p[3] = ( d[3] + 10–3 ) mod 10 = (8 + 10–3) mod 10 = 5
p[4] = ( d[4] + 10–4 ) mod 10 = (2 + 10–4) mod 10 = 8
p[5] = ( d[5] + 10–5 ) mod 10 = (7 + 10–5) mod 10 = 2
p[6] = ( d[6] + 10–6 ) mod 10 = (3 + 10–6) mod 10 = 7
p[7] = ( d[7] + 10–7 ) mod 10 = (6 + 10–7) mod 10 = 9
p[8] = ( d[8] + 10–8 ) mod 10 = (4 + 10–8) mod 10 = 6
p[9] = ( d[9] + 10–9 ) mod 10 = (5 + 10–9) mod 10 = 6
q[1] = 9
q[2] = 9
q[3] = (p[3] * 2^(10–3)) mod 9 = (5 * 2⁷) mod 9 = 1
q[4] = (p[4] * 2^(10–4)) mod 9 = (8 * 2⁶) mod 9 = 8
q[5] = (p[5] * 2^(10–5)) mod 9 = (2 * 2⁵) mod 9 = 1
q[6] = (p[6] * 2^(10–6)) mod 9 = (7 * 2⁴) mod 9 = 4
q[7] = 9
q[8] = (p[8] * 2^(10–8)) mod 9 = (6 * 2²) mod 9 = 6
q[9] = (p[9] * 2^(10–9)) mod 9 = (6 * 2¹) mod 9 = 3
i = 1..9 >> Σ q[i] = 9 + 9 + 1 + 8 + 1 + 4 + 9 + 6 + 3 = 50
c1 = (10 — (Σ q[i] mod 10)) mod 10 = (10–50 mod 10) mod 10
c1 = (10–0) mod 10 = 0
So it would be >> 0182736450
Here is my code.
boolean isTurkishVID(String idnum) {
d=idnum;
int v1 = 0;
int v2 = 0;
int v3 = 0;
int v4 = 0;
int v5 = 0;
int v6 = 0;
int v7 = 0;
int v8 = 0;
int v9 = 0;
int v11 = 0;
int v22 = 0;
int v33 = 0;
int v44 = 0;
int v55 = 0;
int v66 = 0;
int v77 = 0;
int v88 = 0;
int v99 = 0;
int v_last_digit = 0;
int total = 0;
if (d.size()==10) {
v1 = (d[0].toInteger() + 9) % 10;
v2 = (d[1].toInteger() + 8) % 10;
v3 = (d[2].toInteger() + 7) % 10;
v4 = (d[3].toInteger() + 6) % 10;
v5 = (d[4].toInteger() + 5) % 10;
v6 = (d[5].toInteger() + 4) % 10;
v7 = (d[6].toInteger() + 3) % 10;
v8 = (d[7].toInteger() + 2) % 10;
v9 = (d[8].toInteger() + 1) % 10;
v11 = (v1 * 512) % 9;
v22 = (v2 * 256) % 9;
v33 = (v3 * 128) % 9;
v44 = (v4 * 64) % 9;
v55 = (v5 * 32) % 9;
v66 = (v6 * 16) % 9;
v77 = (v7 * 8) % 9;
v88 = (v8 * 4) % 9;
v99 = (v9 * 2) % 9;
if (v1 != 0 && v11 == 0) v11 = 9;
if (v2 != 0 && v22 == 0) v22 = 9;
if (v3 != 0 && v33 == 0) v33 = 9;
if (v4 != 0 && v44 == 0) v44 = 9;
if (v5 != 0 && v55 == 0) v55 = 9;
if (v6 != 0 && v66 == 0) v66 = 9;
if (v7 != 0 && v77 == 0) v77 = 9;
if (v8 != 0 && v88 == 0) v88 = 9;
if (v9 != 0 && v99 == 0) v99 = 9;
total = v11 + v22 + v33 + v44 + v55 + v66 + v77 + v88 + v99;
if (total % 10 == 0) total = 0;
else total = (10 - (total % 10));
if (total == v_last_digit) {
return true;
} else return false;
} else return false;
}
It returns error when I use it like
isTurkishVI("1234567891");
Returns;
groovy.lang.MissingMethodException: No signature of method: ConsoleScript20.isTurkishVI() is applicable for argument types: (java.lang.Integer) values: [1234567891]
Possible solutions: isTurkishVID(java.lang.String)
at ConsoleScript20.run(ConsoleScript20:74)

Calculate Values of Variables Found in an Interval with Java

I am trying to find the values x and y may take so the following inequalities hold:
1/24 < 1/15*y < 1/10*x < 2/24 < 2/15*y < 3/24
Is there a way to formulate such a problem in Java?
Constraint Programming would probably solve such a problem but is there an alternative way?
If Constraint Programming is the only way, how does this look like?
The following is what I tried with constraint programming using or-tools. How to formulate strict inequalities?
MPSolver solver = new MPSolver(
"SimpleMipProgram", MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
// [END solver]
// [START variables]
double infinity = java.lang.Double.POSITIVE_INFINITY;
// x and y are float/double variables.
MPVariable x = solver.makeNumVar(0,1,"x"); //makeIntVar(0.0, infinity, "x");
MPVariable y = solver.makeNumVar(0,1,"y"); //makeIntVar(0.0, infinity, "y");
System.out.println("Number of variables = " + solver.numVariables());
// [END variables]
// [START constraints]
// x + 7 * y <= 17.5.
/*MPConstraint c0 = solver.makeConstraint(-1, 17.5, "c0");
c0.setCoefficient(x, 1);
c0.setCoefficient(y, 7);
// x <= 3.5.
MPConstraint c1 = solver.makeConstraint(-infinity, 3.5, "c1");
c1.setCoefficient(x, 1);
c1.setCoefficient(y, 0);*/
// 1/24 < 1/15*y ---> -1/15 * y < -1/24
MPConstraint c0 = solver.makeConstraint(-1000,-1/24.0,"c0");
c0.setCoefficient(y,-1/15.0);
// 1/15*y < 1/10*x ---> 1/15*y - 1/10*x < 0
MPConstraint c1 = solver.makeConstraint(-1000,0,"c1");
c1.setCoefficient(y,1/15.0);
c1.setCoefficient(x,-1/10.0);
// 1/10*x < 2/24 ---> 1/10*x < 2/24
MPConstraint c2 = solver.makeConstraint(-1000,2/24.0,"c2");
c2.setCoefficient(x,1/10.0);
// 2/24 < 2/15*y ---> -2/15*y < -2/24
MPConstraint c3 = solver.makeConstraint(-1000, -2/24.0);
c3.setCoefficient(y,-2/15.0);
// 2/15*y < 3/24 ---> 2/15*y < 3/24
MPConstraint c4 = solver.makeConstraint(-1000,3/24.0);
c4.setCoefficient(y,2/15.0);
Here is a working code using the integer solver
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from ortools.sat.python import cp_model
model = cp_model.CpModel()
scale = 1000
x = model.NewIntVar(0, scale, 'x')
y = model.NewIntVar(0, scale, 'y')
# 1/24 < 1/15*y < 1/10*x < 2/24 < 2/15*y < 3/24
model.Add(5 * scale < 8 * y)
model.Add(8 * y < 12 * x)
model.Add(12 * x < 10 * scale)
model.Add(10 * scale < 16 * y)
model.Add(16 * y < 15 * scale)
solver = cp_model.CpSolver()
solver.parameters.log_search_progress = True
status = solver.Solve(model)
if status == cp_model.FEASIBLE:
print('x =', solver.Value(x) * 1.0 / scale)
print('y =', solver.Value(y) * 1.0 / scale)
With scale = 1000, it outputs:
x = 0.418
y = 0.626
With scale = 100, it outputs:
x = 0.43
y = 0.63
With scale = 10, it outputs
x = 0.5
y = 0.7
I found the solution by writing down a loop that produces random values until all the statements are fulfilled.
Now I am interested in how wolfram alpha solves such problems so quickly.
public class inequalities {
private static double x;
private static double y;
private static double Ratio3 = 1/24.0;
private static double Ratio2 = 1/15.0;
private static double Ratio1 = 1/10.0;
public static void main(String[] args) {
x = Math.random();
y = Math.random();
boolean loop = true;
while (loop) {
loop = calculatingTheInequalities();
if (loop) {
x = Math.random();
y = Math.random();
}
}
System.out.println("x value: " + x);
System.out.println("y value: " + y);
}
public static boolean calculatingTheInequalities() {
if (Ratio3<Ratio2*y && Ratio2*y<Ratio1*x &&
Ratio1*x<2*Ratio3 && 2*Ratio3<2*Ratio2*y &&
2*Ratio2*y<3*Ratio3) {
return false;
} else {
return true;
}
/*if (Ratio3 < Ratio2 *y) {
if (Ratio2 *y < Ratio1 *x) {
if (Ratio1 *x<2* Ratio3) {
if (2* Ratio3 < 2* Ratio2 *y) {
if (2* Ratio2 *y < 3* Ratio3) {
return false;
} else {
return true;
}
} else {
return true;
}
} else {
return true;
}
} else {
return true;
}
} else {
return true;
}*/
}
}

Flipping algorithm

I have a string s containing different types of brackets : () and [] . How can I balance a string of this type with the minimum possible number of reversals ? I can replace any bracket with any other one.
For example : Cost for [)(] is 2, it becomes [()]. Cost for [](( is 1, it becomes []() . [(]) is not balanced.
A more complex example : )[)([)())] can be turned to ([])[(())] in 4 changes, but can also be turned to [()(()())] in 3 steps, which is the least number of modifications to make it balanced.
How can I solve the problem ?
First approach I came with is O(n^3) dynamic programming.
Let match(i, j) be the number of replaces you have to make in order to make s[i] and s[j] as () or []. So match(i, j) can be either 0, 1 or 2.
Consider dp[i][j] = the minimum cost to balance the subsequence from i to j in your brackets array. Now you will define dp[i][i + 1] as:
dp[i][i + 1] = match(i, i + 1)
Now the general rule is that we take the overall minimum between dp[i + 1][j - 1] + match(i, j) and min(dp[i][j], dp[i][p] + dp[p + 1][j]) for any i < p < j. Obviously, the result will be held in dp[1][n]. There is a C++ solution (I'll also upload a python program in about 15 minutes when I'll be done with it - not so strong with python :P).
#include <iostream>
#include <string>
using namespace std;
int dp[100][100];
string s;
int n;
int match(char a, char b) {
if (a == '(' && b == ')') {
return 0;
}
if (a == '[' && b == ']') {
return 0;
}
if ((a == ')' || a == ']') && (b == '(' || b == '[')) {
return 2;
}
return 1;
}
int main() {
cin >> s;
n = s.length();
s = " " + s;
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) {
dp[i][j] = 0x3f3f3f3f;
}
}
for (int i = 1; i < n; ++i) {
dp[i][i + 1] = match(s[i], s[i + 1]);
}
for (int k = 3; k <= n; k += 2) {
for (int i = 1; i + k <= n; ++i) {
int j = i + k;
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]));
for (int p = i + 1; p <= j; p += 2) {
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j]);
}
}
}
cout << dp[1][n] << '\n';
/*for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cout << dp[i][j] << ' ';
}
cout << '\n';
}*/
return 0;
}
Edit:
Here you go Python :)
s = input()
n = len(s)
inf = 0x3f3f3f3f
def match(x, y):
if x == '(' and y == ')':
return 0
if x == '[' and y == ']':
return 0
if (x == ')' or x == ']') and (y == '(' or y == '['):
return 2
return 1
# dp[i][j] = min. cost for balancing a[i], a[i + 1], ..., a[j]
dp = [[inf for j in range(n)] for i in range(n)]
for i in range(n - 1):
dp[i][i + 1] = match(s[i], s[i + 1])
for k in range(3, n, 2):
i = 0
while i + k < n:
j = i + k
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]))
for p in range(i + 1, j, 2):
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j])
i += 1
print(dp[0][n - 1])
#for i in range(n):
# for j in range(n):
# print(dp[i][j], end = ' ')
# print()

Resources