How can I make a variation limits, do not exceed a specific value - linear-programming

Now I am facing a problem that making a variation does not exceed a specific value.
I will describe in details below.
using CP;
int a = 4;
int b = 3;
int c = 5;
range arange = 1..a;
range brange = 1..b;
range crange = 1..c;
dvar boolean x[a][b][c];
dvar int y[b][c] in 1..4;
In this case, I'm trying to calculate
y[b][c+1] = x[a][b][c] - 1 + y[b][c];
However, all y[e][t] are in 1 to 4.
I mean
if y[b][c] >= 4, then y[b][c] == 4, and if y[b][c] <= 1, then y[b][c] == 1
like that.
So, Now I trying to do this
y[b][c+1] == max(min(x[a][b][c] -1 + y[b][c], 4), 1);
but it doesn't work.

Use minl and maxl instead:
y[b][c+1] == maxl(minl(2 * x[a][b][c] -1 + y[b][c], 4), 1);

Related

Zero Subsequences problem - What's wrong with my C++ solution?

Problem Statement:
Given an array arr of n integers, count the number of non-empty subsequences of the given array such that their product of maximum element and minimum element is zero. Since this number can be huge, compute it modulo 10 ^ 9 + 7
A subsequence of an array is defined as the sequence obtained by deleting several elements from the array (possible none) without changing the order of the remaining elements.
Example
Given n = 3, arr = [1, 0, – 2].
There are 7 subsequences of arr that are-
[1], minimum = 1, maximum =1 , min * max = 1 .
[1,0] minimum = 0, maximum=1, min * max=0
[ 1,0, – 2], minimum = – 2, maximum =1, min* max = -2.
[0], minimum = 0, maximum =0, min * max=0
[0,-2],minimum=-2,maximum=0, min* max=0,
[1, -2] minimum=-2, maximum=1,min* max=-2
[- 2] minimum =-2 maximum = – 2 , min* max = 4.
There are 3 subsequences whose minimum * maximum = 0 that are
[1, 0], [0], [0, – 2] . Hence the answer is 3.
I tried to come up with a solution, by counting the number of zeroes, positive numbers and negative numbers and then adding possible subsequences(2^n, per count) to an empty variable.
My answer is way off though, it's 10 when the expected answer is 3. Can someone please point out my mistake?
#include<bits/stdc++.h>
using namespace std;
#define int long long
int zeroSubs(vector<int> arr){
int x = 0, y = 0, z = 0, ans = 0;
for(int i = 0; i < arr.size(); i++){
if(arr[i] == 0) z++;
else if(arr[i] < 0) x++;
else y++;
}
ans += ((int)pow(2, z))*((int)pow(2, x));
ans += ((int)pow(2, y))*((int)pow(2, z));
ans += ((int)pow(2, z));
return ans;
}
int32_t main()
{
//directly passed the sample test case as an array
cout<<zeroSubs({1, 0, -2});
return 0;
}
ans += ((1<<z)-1)*((1<<x)-1);
ans += ((1<<y)-1)*((1<<z)-1);
ans += ((1<<z)-1);
Made this slight change in the logic, thanks a lot to everyone for the valuable feedback. It works now.

I have a variable and an matrix and how to move the elements right?

I have a matrix which is 3*3 for example, and I have a variable = 10.
This variable represents the first element of the new array. I need to store the last element as well in a new variable.
I need to move the matrix left to right, right to left, up to down, and down to up, by shifting the elements and getting the last element.
For example the default matrix:
[[0,1,2]
[3,4,5]
[6,7,8]]
Shifting the the first row with variable=5
[[5,0,1]
[3,4,5]
[6,7,8]]
and then I get back 2 the second result.
Another example shift from up to down the last column with variable=6:
[[5,0,6]
[3,4,2]
[6,7,5]]
and then I get back 8.
Here is a snippet of my c++ code, but I can accept every language.
#include <iostream>
using namespace std;
int main()
{
int ar[3][3] = {
{0, 1, 2} ,
{3, 4, 5} ,
{6, 7, 8}
};
int x=0;
for (int i = 0; i < 2; i++) {
int temp = x[i];
x[i]=x[i+1];
x[i]=tmp;
}
return 0;
}
We can generalize the directions in such a manner that the same code would handle all of the cases. The example below is a proof-of-concept, yet, it was not actually tested, because I lack a C++ env at the moment. But, if it turns out to be some problem with it, then it should be fairly easy to fix it, so if it does not work yet, then please provide example inputs and outputs.
int index = 0; //It can be something between 0 and 2
int isRow = 1; //It can be 1 if it's a row to be shifted and 0 if it's a column to be shifted
int direction = 1; //It can be -1 if it's to the left/up (depending on the value of isRow) and 1 if it's right/down
int output; //The element we need to store at the end
int input = 10; // The element we need to append
int i;
for (i = 0; i <= 2; i++) {
if (i == 0) output = ar[isRow ? index : (2 - (direction + 1) + direction * i)][isRow ? (2 - (direction + 1) + (direction * i)) : index];
else ar[isRow ? index : (2 - (direction + 1) + direction * i)][isRow ? (2 - (direction + 1) + (direction * (i - 1))) = ar[isRow ? index : (2 - (direction + 1) + direction * i)][isRow ? (2 - (direction + 1) + (direction * (i - 1)));
}

Maximum difference between sum of even and odd position elements: How to memoize the brute-force approach?

I have the following code for a problem.
The problem is: Maximize the absolute difference between the sum of elements at the even and odd positions of an array. To do so, you may delete as many elements you want.
I did it by brute-force by using backtracking. My logic is that, for each index I have 2 options:
a) either delete it (in this case, I put it in a set)
b) don't delete it (in this case, I removed the index from the set and backtracked).
I took the local maximum of two cases and updated the global maximum value appropriately.
void maxAns(vector<int> &arr, int index, set<int> &removed, int &res)
{
if (index<0)
return;
int k=0;
int s3=0,s4=0;
for (int i=0;i<arr.size();i++)
{
if (i!=index)
{
set<int>::iterator it=removed.find(i);
if (it==removed.end())
{
if( k%2==0)
s3+=arr[i];
else
s4+=arr[i];
k++;
}
}
else //don't delete the element
{
if (k%2==0)
s3+=arr[i];
else
s4+=arr[i];
k++;
}
}
k=0;
int s1=0, s2=0;
for (int i=0;i<arr.size();i++)
{
if (i!=index)
{
set<int>::iterator it=removed.find(i);
if (it==removed.end())
{
if (k%2==0)
s1+=arr[i];
else
s2+=arr[i];
k++;
}
}
else //delete the element
{
//add index into the removed set
removed.insert(index);
}
}
//delete the index element
int t1=abs(s1-s2);
maxAns(arr,index-1,removed,res);
//don't delete the index element, and then backtrack
set<int>::iterator itr=removed.find(index);
removed.erase(itr);
int t2=abs(s3-s4);
maxAns(arr,index-1,removed,res);
//choose the max value
res=max(res,max(t1,t2));
}
Please suggest how to memoize this solution as I think it's quite inefficient. Feel free to share any interesting approach.
Hint: divide and conquer. Consider that a fixed length list as a left part of a larger list, maximised (or minimised) for the actual, rather than abdolute difference and depending on the parity of its length, would pair better with a right part that does not depend on the parity of its length.
[0,3] ++ [0,3] -> diff -3 -3 = -6
[0,3] ++ [9,13,1] -> diff -3 -3 = -6
We can also easily create base cases for max_actual_diff and min_actual_diff of lists with lengths 1 and 2. Note that the best choice for those might include ommiting one or more of those few elements.
JavaScript code:
function max_diff(A, el, er, memo){
if (memo[['mx', el, er]])
return memo[['mx', el, er]]
if (er == el)
return memo[['mx', el, er]] = [A[el], 1, 0, 0]
var best = [A[el], 1, 0, 0]
if (er == el + 1){
if (A[el] - A[er] > best[2]){
best[2] = A[el] - A[er]
best[3] = 2
}
if (A[er] > best[0]){
best[0] = A[er]
best[1] = 1
}
return memo[['mx', el, er]] = best
}
const mid = el + ((er - el) >> 1)
const left = max_diff(A, el, mid, memo)
const right_min = min_diff(A, mid + 1, er, memo)
const right_max = max_diff(A, mid + 1, er, memo)
// Best odd = odd + even
if (left[0] - right_min[2] > best[0]){
best[0] = left[0] - right_min[2]
best[1] = left[1] + right_min[3]
}
// Best odd = even + odd
if (left[2] + right_max[0] > best[0]){
best[0] = left[2] + right_max[0]
best[1] = left[3] + right_max[1]
}
// Best even = odd + odd
if (left[0] - right_min[0] > best[2]){
best[2] = left[0] - right_min[0]
best[3] = left[1] + right_min[1]
}
// Best even = even + even
if (left[2] + right_max[2] > best[2]){
best[2] = left[2] + right_max[2]
best[3] = left[3] + right_max[3]
}
return memo[['mx', el, er]] = best
}
function min_diff(A, el, er, memo){
if (memo[['mn', el, er]])
return memo[['mn', el, er]]
if (er == el)
return memo[['mn', el, er]] = [A[el], 1, 0, 0]
var best = [A[el], 1, 0, 0]
if (er == el + 1){
if (A[el] - A[er] < best[2]){
best[2] = A[el] - A[er]
best[3] = 2
}
if (A[er] < best[0]){
best[0] = A[er]
best[1] = 1
}
return memo[['mn', el, er]] = best
}
const mid = el + ((er - el) >> 1)
const left = min_diff(A, el, mid, memo)
const right_min = min_diff(A, mid + 1, er, memo)
const right_max = max_diff(A, mid + 1, er, memo)
// Best odd = odd + even
if (left[0] - right_max[2] < best[0]){
best[0] = left[0] - right_max[2]
best[1] = left[1] + right_max[3]
}
// Best odd = even + odd
if (left[2] + right_min[0] < best[0]){
best[0] = left[2] + right_min[0]
best[1] = left[3] + right_min[1]
}
// Best even = odd + odd
if (left[0] - right_max[0] < best[2]){
best[2] = left[0] - right_max[0]
best[3] = left[1] + right_max[1]
}
// Best even = even + even
if (left[2] + right_min[2] < best[2]){
best[2] = left[2] + right_min[2]
best[3] = left[3] + right_min[3]
}
return memo[['mn', el, er]] = best
}
var memo = {}
var A = [1, 2, 3, 4, 5]
console.log(`A: ${ JSON.stringify(A) }`)
console.log(
JSON.stringify(max_diff(A, 0, A.length-1, memo)) + ' // [odd max, len, even max, len]')
console.log(
JSON.stringify(min_diff(A, 0, A.length-1, memo)) + ' // [odd min, len, even min, len]')
console.log('\nmemo:\n' + JSON.stringify(memo))
Maximize the absolute difference between the sum of elements at the odd and even positions of an array. To do so, you may delete as many elements as you want.
Example
A = [9, 5, 2, 9, 4]
Ans = 16 => [9, 2, 9] = 9-2+9
A = [8, 6, 2, 7, 7, 2, 7]
Ans = 18 => [8, 2, 7, 2, 7] = 8-2+7-2+7
Hint:
At the position "i+1", Let the maximum and minimum possible difference for all the subsequences of subarray A[i+1,n] be Max, Min respectively
Hence at position "i", the maximum and minimum possible difference for all the subsequences of subarray A[i, n] can be calculated as
Include the current element arr[i]
Don't Include the current element arr[I]
Max = MAX(Max, arr[i] - Min)
Min = MIN(Min, arr[i] - Max)
Explanation:
A = 9, 5, 2, 9, 4
Max = 16, 12, 9, 9, 4
Min = -7, -7, -7, 0, 0
Final Answer: Max(Max[0], Min[0]) = Max(16, -7) = 16
Time Complexity: O(n)
Space Complexity: O(1) * As Just 2 variables Max, Min were used*
Let's say we always add the values at even positions and we always rest the values at odd positions. Now, we will iterate from 1 to 𝑛n and make choices: keep the element or delete it; the thing is that when we keep an element, we need to know if it is at an even position or an odd position, so we will do Dynamic Programming:
𝑑𝑝[𝑖][0]dp[i][0]: max possible sum using the elements in 𝑎1,𝑎2,…,𝑎𝑖a1,a2,…,ai and the resulting array is of even length.
𝑑𝑝[𝑖][1]dp[i][1]: same as above, but now the resulting array is of odd length.
Transitions are: keep it or delete it.
𝑑𝑝[𝑖][𝑟]=max(𝑑𝑝[𝑖−1][𝑟],𝑑𝑝[𝑖−1][!𝑟]+𝑎[𝑖]∗((𝑟==0)?1:−1)dp[i][r]=max(dp[i−1][r],dp[i−1][!r]+a[i]∗((r==0)?1:−1);
Now it's when someone says: Wait minute, you are always adding at even positions and resting at odd positions, what if it's of the other way. Well, for this, perform again the DP but adding at odd positions and resting at even positions. You stay with the maximum of both solutions

Random generation code translated from R fails in C++

I am working on code implementing random generation algorithm for sampling from tails of normal distribution proposed by Christian Robert. The problem is that while code in R worked properly, then after translating it to C++ if fails. I can't see any reason for that and I'd be grateful for explaining me what went wrong and why.
Notice that the code below is far from elegant and efficient, it is simplified to make reproducible example.
Here is the function in R:
rtnormR <- function(mean = 0, sd = 1, lower = -Inf, upper = Inf) {
lower <- (lower - mean) / sd
upper <- (upper - mean) / sd
if (lower < upper && lower >= 0) {
while (TRUE) {
astar <- (lower + sqrt(lower^2 + 4)) / 2
z <- rexp(1, astar) + lower
u <- runif(1)
if ((u <= exp(-(z - astar)^2 / 2)) && (z <= upper)) break
}
} else {
z <- NaN
}
z*sd + mean
}
and here C++ version:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double rtnormCpp(double mean, double sd, double lower, double upper) {
double z_lower = (lower - mean) / sd;
double z_upper = (upper - mean) / sd;
bool stop = false;
double astar, z, u;
if (z_lower < z_upper && z_lower >= 0) {
while (!stop) {
astar = (z_lower + std::sqrt(std::pow(z_lower, 2) + 4)) / 2;
z = R::exp_rand() * astar + z_lower;
u = R::unif_rand();
if ((u <= std::exp(-std::pow(z-astar, 2) / 2)) && (z <= z_upper))
stop = true;
}
} else {
z = NAN;
}
return z*sd + mean;
}
Now compare the samples obtained using both functions (they are compared to dtnorm function from msm library):
xx = seq(-6, 6, by = 0.001)
hist(replicate(5000, rtnormR(mean = 0, sd = 1, lower = 3, upper = 5)), freq= FALSE, ylab = "", xlab = "", main = "rtnormR")
lines(xx, msm::dtnorm(xx, mean = 0, sd = 1, lower = 3, upper = 5), col = "red")
hist(replicate(5000, rtnormCpp(mean = 0, sd = 1, lower = 3, upper = 5)), freq= FALSE, ylab = "", xlab = "", main = "rtnormCpp")
lines(xx, msm::dtnorm(xx, mean = 0, sd = 1, lower = 3, upper = 5), col = "red")
As you can see, rtnormCpp returns biased samples. Do you have any ideas why?
While one can use either scale or rate in rexp(), the default parameterization is rate - so rexp(1,astar) has a mean of 1/astar, not astar.
If you change the relevant line of C++ code to
z = R::exp_rand() / astar + z_lower;
everything seems to work fine.

performance of log10 function returning an int

Today I needed a cheap log10 function, of which I only used the int part. Assuming the result is floored, so the log10 of 999 would be 2. Would it be beneficial writing a function myself? And if so, which way would be the best to go. Assuming the code would not be optimized.
The alternatives to log10 I've though of;
use a for loop dividing or multiplying by 10;
use a string parser(probably extremely expensive);
using an integer log2() function multiplying by a constant.
Thank you on beforehand:)
The operation can be done in (fast) constant time on any architecture that has a count-leading-zeros or similar instruction (which is most architectures). Here's a C snippet I have sitting around to compute the number of digits in base ten, which is essentially the same task (assumes a gcc-like compiler and 32-bit int):
unsigned int baseTwoDigits(unsigned int x) {
return x ? 32 - __builtin_clz(x) : 0;
}
static unsigned int baseTenDigits(unsigned int x) {
static const unsigned char guess[33] = {
0, 0, 0, 0, 1, 1, 1, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 5, 5, 5,
6, 6, 6, 6, 7, 7, 7, 8, 8, 8,
9, 9, 9
};
static const unsigned int tenToThe[] = {
1, 10, 100, 1000, 10000, 100000,
1000000, 10000000, 100000000, 1000000000,
};
unsigned int digits = guess[baseTwoDigits(x)];
return digits + (x >= tenToThe[digits]);
}
GCC and clang compile this down to ~10 instructions on x86. With care, one can make it faster still in assembly.
The key insight is to use the (extremely cheap) base-two logarithm to get a fast estimate of the base-ten logarithm; at that point we only need to compare against a single power of ten to decide if we need to adjust the guess. This is much more efficient than searching through multiple powers of ten to find the right one.
If the inputs are overwhelmingly biased to one- and two-digit numbers, a linear scan is sometimes faster; for all other input distributions, this implementation tends to win quite handily.
One way to do it would be loop with subtracting powers of 10. This powers could be computed and stored in table. Here example in python:
table = [10**i for i in range(1, 10)]
# [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]
def fast_log10(n):
for i, k in enumerate(table):
if n - k < 0:
return i
Usage example:
>>> fast_log10(1)
0
>>> fast_log10(10)
1
>>> fast_log10(100)
2
>>> fast_log10(999)
2
fast_log10(1000)
3
Also you may use binary search with this table. Then algorithm complexity would be only O(lg(n)), where n is number of digits.
Here example with binary search in C:
long int table[] = {10, 100, 1000, 10000, 1000000};
#define TABLE_LENGHT sizeof(table) / sizeof(long int)
int bisect_log10(long int n, int s, int e) {
int a = (e - s) / 2 + s;
if(s >= e)
return s;
if((table[a] - n) <= 0)
return bisect_log10(n, a + 1, e);
else
return bisect_log10(n, s, a);
}
int fast_log10(long int n){
return bisect_log10(n, 0, TABLE_LENGHT);
}
Note for small numbers this method would slower then upper method.
Full code here.
Well, there's the old standby - the "poor man's log function".
(If you want to handle more than 63 integer digits, change the first "if" to a "while".)
n = 1;
if (v >= 1e32){n += 32; v /= 1e32;}
if (v >= 1e16){n += 16; v /= 1e16;}
if (v >= 1e8){n += 8; v /= 1e8;}
if (v >= 1e4){n += 4; v /= 1e4;}
if (v >= 1e2){n += 2; v /= 1e2;}
if (v >= 1e1){n += 1; v /= 1e1;}
so if you feed in 123456.7, here's how it goes:
n = 1;
if (v >= 1e32) no
if (v >= 1e16) no
if (v >= 1e8) no
if (v >= 1e4) yes, so n = 5, v = 12.34567
if (v >= 1e2) no
if (v >= 1e1) yes, so n = 6, v = 1.234567
so result is n = 6
Here's a variation that uses multiplication, rather than division:
int n = 1;
double d = 1, temp;
temp = d * 1e32; if (v >= temp){n += 32; d = temp;}
temp = d * 1e16; if (v >= temp){n += 16; d = temp;}
temp = d * 1e8; if (v >= temp){n += 8; d = temp;}
temp = d * 1e4; if (v >= temp){n += 4; d = temp;}
temp = d * 1e2; if (v >= temp){n += 2; d = temp;}
temp = d * 1e1; if (v >= temp){n += 1; d = temp;}
and an execution looks like this
v = 123456.7
n = 1
d = 1
temp = 1e32, if (v >= 1e32) no
temp = 1e16, if (v >= 1e16) no
temp = 1e8, if (v >= 1e8) no
temp = 1e4, if (v >= 1e4) yes, so n = 5, d = 1e4;
temp = 1e6, if (v >= 1e6) no
temp = 1e5, if (v >= 1e5) yes, so n = 6, d = 1e5;
If you want to have a faster log function you need to approximate their result. E.g. the exp function can be approximated using a 'short' taylor approximation. You can find example approximations for exp, log, root and power here
edit:
You can find a short performance comparsion here
Because an unsigned < or >= test is done simply by subtracting and checking the carry flag, it is possible to put both arrays (guess and negated tenToThe) in a single 64-bit value, combine both array lookups into one, and use the carry from 32-bit addition to adjust the guess. The high 32 bits of guess[n] provide the value of log10(2^n*2-1), while the low 32 bits contain -10^log10(2^n*2-1).
static unsigned int baseTwoDigits(unsigned int x) {
return x ? 32 - __builtin_clz(x) : 0;
}
unsigned int baseTenDigits(unsigned int x) {
static uint64_t guess[33] = {
/* 1 */ 0, 0, 0,
/* 8 */ (1ull<<32)-10, (1ull<<32)-10, (1ull<<32)-10,
/* 64 */ (2ull<<32)-100, (2ull<<32)-100, (2ull<<32)-100,
/* 512 */ (3ull<<32)-1000, (3ull<<32)-1000, (3ull<<32)-1000,
(3ull<<32)-1000,
/* 8192 */ (4ull<<32)-10000, (4ull<<32)-10000, (4ull<<32)-10000,
/* 65536 */ (5ull<<32)-100000, (5ull<<32)-100000, (5ull<<32)-100000,
/* 524288 */ (6ull<<32)-1000000, (6ull<<32)-1000000, (6ull<<32)-1000000,
(6ull<<32)-1000000,
/* 8388608 */ (7ull<<32)-10000000, (7ull<<32)-10000000,
(7ull<<32)-10000000,
/* 67108864 */ (8ull<<32)-100000000, (8ull<<32)-100000000,
(8ull<<32)-100000000,
/* 536870912 */ (9ull<<32)-1000000000, (9ull<<32)-1000000000,
(9ull<<32)-1000000000,
};
uint64_t adjust = guess[baseTwoDigits(x)];
return (adjust + x) >> 32;
}
Without any specifications, I will just give a general answer:
The log function will be pretty efficient in most languages as it is such a basic function.
The fact that you are only interested in integers could give you some leverage, but probably this is not enough to easily beat the builtin standard solutions.
One of the few things that I can think of to be faster than a builtin function is a table lookup, so if you are only interested in the numbers upto 10000 for instance, you could simply create a table that you could use to lookup any of these values when you need them.
Obviously this solution will not scale well, but it may be just what you need.
Sidenote: If you are importing the data for example, it may actually be faster to look at the string diecty length (rather than first converting the string to a number and than looking at the value of the string). Of course this will require the input to be stored in just the right format, otherwise it won't gain you anything.