How to formulate x != y in lpsolve? - linear-programming

I'm trying to formulate that the variables x,y,z must all be different and that they accept only the values 1, 2 or 3 (this is, of course, a toy example):
min: x+y+z;
1 <= x <= 3;
1 <= y <= 3;
1 <= z <= 3;
but to make this work I still need either access to boolean operators or to a != operator, which don't seem to exist in lpsolve! How can I go about this? I wanted to do this:
x != y;
x != z;
y != z;
Thanks
EDIT:
Here's my current code:
/* Objective function */
min: 1;
/* Variable bounds */
1 <= x1 <= 4;
1 <= x2 <= 4;
1 <= x3 <= 4;
1 <= x4 <= 4;
x1 + x2 + x3 + x4 = 10;
x1 < x2;
x2 < x3;
x3 < x4;
int x1;
int x2;
int x3;
int x4;
lpsolve is giving me as result:
x1 = 1
x2 = 3
x3 = 3
x4 = 3
which is wrong. Why?

In general I would agree with Michael Laffargue that it is not possible to have something like a < b for real a,b in lpSolve. But for integer expressions that is a bit different.
Maybe we can start with a more simplified problem.
Let us think of two integer variables x and y and a constant M such that
1 <= x <= M and 1<=y<=M.
If x and y may not be equal then x>y or y>x. But as both are integers only one of the following inequalities hold
x+1 <= y
y+1 <= x
We can enforce that only one of the inequalities above holds by introducing a binary variable r such that for x,y, r the following inequalities hold both :
(i) x+1 <= y+ Mr
(ii) y+1 <= x+M-Mr
because if r=0 then (i) x+1 <=y and (ii) is trivial, but if r=1 then (ii) y+1 <= x and (i) is trivial.
When we now apply the solution from above to the problem of the OP, then we can build a linear program with inequalities (i) and (ii) for all pairs of variables from the OP's problem and M=4:
/* Objective function */
min: 1;
/* Variable bounds */
1 <= x1 <= 4;
1 <= x2 <= 4;
1 <= x3 <= 4;
1 <= x4 <= 4;
r_12 <= 1;
r_13 <= 1;
r_14 <= 1;
r_23 <= 1;
r_24 <= 1;
r_34 <= 1;
/* This is done automatically because all x1,..,x4 are different
x1 + x2 + x3 + x4 = 10;
*/
/* Apply (i) and (ii) to all pairs of x1,..x4
(i) x+1 <= y + Mr
(ii) y+1 <= x + M-Mr
*/
x1 + 1 <= x2 + 4 r_12;
x2 + 1 <= x1 + 4 - 4 r_12;
x1 + 1 <= x3 + 4 r_13;
x3 + 1 <= x1 + 4 - 4 r_13;
x1 + 1 <= x4 + 4 r_14;
x4 + 1 <= x4 + 4 - 4 r_14;
x2 + 1 <= x3 + 4 r_23;
x3 + 1 <= x2 + 4 - 4 r_23;
x2 + 1 <= x4 + 4 r_24;
x4 + 1 <= x2 + 4 - 4 r_24;
x3 + 1 <= x4 + 4 r_34;
x4 + 1 <= x3 + 4 - 4 r_34;
/*
x1 < x2;
x2 < x3;
x3 < x4;
*/
int r_12;
int r_13;
int r_14;
int r_23;
int r_24;
int r_34;
int x1;
int x2;
int x3;
int x4;
Solving the MILP above renders a solution with all x1,..,x4 different:
x1=3
x2=1
x3=2
x4=4

Related

Operations of the elements of arrays in a function' c++

Can I operate the elements of an array in a function(in the parameter)?
float f(i, u, v)
{
if (i == 1) {
return (u - v); //example of the returned value
}
if (i == 2) {
return (u + v);
}
}
int main()
{
int i;
float x[3],y1,y2,h;
x[1]=1;//value of the first element of x[m]
x[2]=1;
h=0.01;
for (i = 1; i <= 2; i++) {
y1=h * f(i, x[1], x[2]);
y2=h * f(i, x[1] + y1/2, x[2]+y1/2);
y3=h* f(i,x[1] + y2/2, x[2]+y2/2);
y4=h * f(i,x[1] + y3, x[2]+y3);
x[1]=x[1] + (y1+ 2 * y2 + 2 * y3+2 * y4)/ 6;
x[2]=x[2] + (y1+ 2 * y2 + 2 * y3+2 * y4)/ 6;
cout<<x[1]<<endl;
}
}
with:
x[1] and x[2] are the elements of the array x[m]
How can I operate elements of different arrays in parameter?
I would recommend you to try to compile your code, the compiler will give you some important hints as of what is wrong. Here is the code compiled online.
To make it compile i changed it to this:
#include <iostream>
using namespace std;
float f(int i, float u, float v) {
if (i == 1) {
return (u - v); // example of the returned value
}
// if (i == 2) { // This if-statement is not needed
return (u + v);
// }
}
int main() {
int i;
float x[3] = {0, 1, 1}; // x[0] is unused...?
float y1 = 0;
float y2 = 0;
float y3 = 0;
float y4 = 0;
const float h = 0.01;
for (int i = 1; i <= 2; i++) {
y1 = h * f(i, x[1], x[2]);
y2 = h * f(i, x[1] + y1 / 2, x[2] + y1 / 2);
y3 = h * f(i, x[1] + y2 / 2, x[2] + y2 / 2);
y4 = h * f(i, x[1] + y3, x[2] + y3);
x[1] = x[1] + (y1 + 2 * y2 + 2 * y3 + 2 * y4) / 6;
x[2] = x[2] + (y1 + 2 * y2 + 2 * y3 + 2 * y4) / 6;
cout << x[1] << endl;
}
}
Note the changes
You need to specify the types for the variables in the function f(...)
You need to define all variables before using them (a good rule is to specify everything right before you use it, and add const if not changed.
Remember to zero initialize variables that you are going to add to (y1, y2... etc)
Also I would recommend you to use x1 instead of x1, since you are mixing styles between x and y, and you are not using the zeroeth element. Like this
int main() {
int i;
float x1 = 1;
float x2 = 2;
float y1 = 0;
float y2 = 0;
float y3 = 0;
float y4 = 0;
const float h = 0.01;
for (int i = 1; i <= 2; i++) {
y1 = h * f(i, x1, x2);
y2 = h * f(i, x1 + y1 / 2, x2 + y1 / 2);
y3 = h * f(i, x1 + y2 / 2, x2 + y2 / 2);
y4 = h * f(i, x1 + y3, x2 + y3);
x1 = x1 + (y1 + 2 * y2 + 2 * y3 + 2 * y4) / 6;
x2 = x2 + (y1 + 2 * y2 + 2 * y3 + 2 * y4) / 6;
cout << x1 << endl;
}
}

Issue when Re-writing Matlab code to C++

I am struggling since a couple of months to re-write Matlab code into C++
The bigger part of the work as been already done (fft, ifft, xcorr and binFreq functions have been already written in c++), now I am stuck to one function. the function is supposed to estimate delay between two signals S1 and S2. The function relies on FFT-based cross-correlation.
I am stuck in this line " e = [e, eIter];" where e is a vector with variable length ( e was declared earlier as : "e =[]";)
original function in Matlab:
% ****************************************************************
% estimates delay and scaling factor
% ****************************************************************
function [delay_samples, coeff] = iterDelayEst(s1, s2)
n = numel(s1);
halfN = floor(n/2);
assert(numel(s2) == n, 'signals must have same length');
% ****************************************************************
% constants
% ****************************************************************
% exit if uncertainty below threshold
thr_samples = 1e-7;
% exit after fixed number of iterations
nIter = 25;
% frequency domain representation of signals
fd1 = fft(s1);
fd2 = fft(s2);
% first round: No delay was applied
tau = []; %(1,0) ;
fd2Tau = fd2; % delayed s2 in freq. domain
% frequency corresponding to each FFT bin -0.5..0.5
f = binFreq(n);
% uncertainty plot data
e = [];
% normalization factor
nf = sqrt((fd1 * fd1') * (fd2 * fd2')) / n; % normalizes to 1
%nf = sqrt((fd1 .* conj(fd1)) * (fd2 .* conj(fd2))') / n;
% search window:
% known maximum and two surrounding points
x1 = -1;
x2 = -1;
x3 = -1;
y1 = -1;
y2 = -1;
y3 = -1;
% ****************************************************************
% iteration loop
% ****************************************************************
for count = 1:nIter
% ****************************************************************
% crosscorrelation with time-shifted signal
% ****************************************************************
xcorr = abs(ifft(fd2Tau .* conj(fd1)))/ nf;
% ****************************************************************
% detect peak
% ****************************************************************
if isempty(tau)
% ****************************************************************
% startup
% initialize with three adjacent bins around peak
% ****************************************************************
ix = find(xcorr == max(xcorr));
ix = ix(1); % use any, if multiple bitwise identical peaks
% indices of three bins around peak
ixLow = mod(ix-1-1, n) + 1; % one below
ixMid = ix;
ixHigh = mod(ix-1+1, n) + 1; % one above
% delay corresponding to the three bins
tauLow = mod(ixLow -1 + halfN, n) - halfN;
tauMid = mod(ixMid -1 + halfN, n) - halfN;
tauHigh = mod(ixHigh -1 + halfN, n) - halfN;
% crosscorrelation value for the three bins
xcLow = xcorr(ixLow);
xcMid = xcorr(ixMid);
xcHigh = xcorr(ixHigh);
x1 = tauLow;
x2 = tauMid;
x3 = tauHigh;
y1 = xcLow;
y2 = xcMid;
y3 = xcHigh;
else
% ****************************************************************
% only main peak at first bin is of interest
% ****************************************************************
tauMid = tau;
xcMid = xcorr(1);
if xcMid > y2
% ****************************************************************
% improve midpoint
% ****************************************************************
if tauMid > x2
% midpoint becomes lower point
x1 = x2;
y1 = y2;
else
% midpoint becomes upper point
x3 = x2;
y3 = y2;
end
x2 = tauMid;
y2 = xcMid;
elseif tauMid < x2
% ****************************************************************
% improve low point
% ****************************************************************
assert(tauMid >= x1); % bitwise identical is OK
assert(tauMid > x1 || xcMid > y1); % expect improvement
x1 = tauMid;
y1 = xcMid;
elseif tauMid > x2
% ****************************************************************
% improve high point
% ****************************************************************
assert(tauMid <= x3); % bitwise identical is OK
assert((tauMid < x3) || (xcMid > y3)); % expect improvement
x3 = tauMid;
y3 = xcMid;
else
assert(false, '?? evaluated for existing tau ??');
end
end
% ****************************************************************
% calculate uncertainty (window width)
% ****************************************************************
eIter = abs(x3 - x1);
e = [e, eIter];
if eIter < thr_samples
% disp('threshold reached, exiting');
break;
end
if y1 == y2 || y2 == y3
% reached limit of numerical accuracy on one side
usePoly = 0;
else
% ****************************************************************
% fit 2nd order polynomial and find maximum
% ****************************************************************
num = (x2^2-x1^2)*y3+(x1^2-x3^2)*y2+(x3^2-x2^2)*y1;
denom = (2*x2-2*x1)*y3+(2*x1-2*x3)*y2+(2*x3-2*x2)*y1;
if denom ~= 0
tau = (num / denom);
% is the point within [x1, x3]?
usePoly = ((tau > x1) && (tau < x3));
else
usePoly = 0;
end
end
if ~usePoly
% revert to linear interpolation on the side with the
% less-accurate outer sample
% Note: There is no guarantee that the side with the more accurate
% outer sample is the right one, as the samples aren't
% placed on a regular grid!
% Therefore, iterate to improve the "worse" side, which will
% eventually become the "better side", and iteration converges.
tauLow = (x1 + x2) / 2;
tauHigh = (x2 + x3) / 2;
if y1 < y3
o = [tauLow, tauHigh];
else
o = [tauHigh, tauLow];
end
% don't choose point that is identical to one that is already known
tau = o(1);
if tau == x1 || tau == x2 || tau == x3
tau = o(2);
if tau == x1 || tau == x2 || tau == x3
break;
end
end
end
% ****************************************************************
% advance 2nd signal according to location of maximum
% phase shift in frequency domain - delay in time domain
% ****************************************************************
fd2Tau = fd2 .* exp(2i * pi * f * tau);
end % for
% ****************************************************************
% the delay estimate is the final location of the delay that
% maximized crosscorrelation (center of window).
% ****************************************************************
delay_samples = x2;
% ****************************************************************
% Coefficient: Turn signal 1 into signal 2
% ****************************************************************
coeff = fd2Tau * fd1' ./ (fd1 * fd1');
end
C++ equivalent code I have written so far :
//iterDelayEst.cpp
#include <cstddef>
#include <utility>
#include <numeric>
#include <vector>
std::vector<std::size_t> max_indices(CArray const& y) {
struct acc_t {
std::vector<std::size_t> max_idcs;
double max_value;
std::size_t current_idx;
acc_t&& next() {
++current_idx;
return std::move(*this);
}
acc_t&& next_with_current() {
max_idcs.push_back(current_idx++);
return std::move(*this);
}
acc_t&& next_with(Complex const& c) {
max_value = c.real();
max_idcs.clear();
return next_with_current();
}
};
return std::accumulate(
std::begin(y), std::end(y), acc_t{},
[](acc_t acc, Complex const& c) {
return c.real() < acc.max_value ? acc.next()
: c.real() > acc.max_value ? acc.next_with(c)
: acc.next_with_current();
}
).max_idcs;
}
/****************************************************************************/
void tet(CArray const& y) {
auto const max_idcs = max_indices(y);
std::cout << "The max is " << y[max_idcs.front()] << " at indices [";
auto first = true;
for (auto const idx : max_idcs) {
if (!first) {
std::cout << ", ";
} else {
first = false;
}
std::cout << idx;
}
std::cout << "]\n";
}
/****************xcorr function**************************************************************/
void xcorr( CArray & x){
int i;
int n=32;
fft(x);
x *=x.apply(std::conj);
ifft(x);
for ( i = 0 ; i < n ; i++ ){
cout << "x[" << i <<"] =" << x[i] << endl;
}
}
double iterDelayEst(int n,CArray& x, CArray& y)
{
/***************************constants************************************************
/************************************************************************************/
//exit if uncertainty below threshold
int halfN=std::floor(n/2);
double thr_samples = 1e-7;
Complex eIter;
Complex e;
//exit after fixed number of iterations
double nIter = 25;
fft(x);
fft(y);
//frequency domain representation of signals
typedef std::vector < std::complex < double > > tau;
auto f = binFreq(n);
std::vector<double> e;
Complex nf3(0.0,0.0);
int j;
for ( j = 0 ; j < n ; j++ )
{
auto nf1 = ((x * x.apply(std::conj)) * (y * y.apply(std::conj)));
nf3 += nf1[j];
}
auto nf2 =std::sqrt(nf3);
auto nf =nf2/(double)n;
cout << "nf3" << nf3 <<endl;
cout << "nf2" << nf2 <<endl;
cout << "nf" << nf <<endl;
Complex x1(-1,0);
Complex x2(-1,0);
Complex x3(-1,0);
Complex y1(-1,0);
Complex y2(-1,0);
Complex y3(-1,0);
int i;
/***************************************iteration loop**********************************************
**************************************************************************************************/
//for(i=0; i<nIter; i++)
x = x.apply(std::conj);
y *= x;
ifft(y);
y =std::abs(y);
y=y/nf;
for ( i = 0 ; i < n ; i++ ){
cout << "y[" << i <<"] =" << y[i] << endl;
}
if (tau.empty())
{
tet(y);
Complex ix=y[0]; //use any, if multiple bitwise identical peaks
/***********indices of three bins around peak***********/
Complex ixLow= std::fmod(ix-1-1, n) +1 //one below
Complex ixMid=ix;
Complex ixHigh= std::fmod(ix-1+1, n) +1 //one above
/**********delay corresponding to the three bins*********/
Complex tauLow = std::fmod(ixLow -1 + halfN, n) - halfN;
Complex tauMid = std::fmod(ixMid -1 + halfN, n) - halfN;
Complex tauHigh = std::fmod(ixHigh -1 + halfN, n) - halfN;
/**********crosscorrelation value for the three bins******/
Complex xcLow = xcorr(ixLow);
Complex xcMid = xcorr(ixMid);
Complex xcHigh = xcorr(ixHigh);
x1 = tauLow;
x2 = tauMid;
x3 = tauHigh;
y1 = xcLow;
y2 = xcMid;
y3 = xcHigh;
}
else
{
/**********only main peak at first bin is of interest****/
tauMid =tau;
xcMid = xcorr(1);
if (xcMid > y2){
/**********improve midpoint***************************/
if(tauMid > x2){
//midpoint becomes lower point
x1 = x2;
y1 = y2;
}
else{
//midpoint becomes upper point
x3 = x2;
y3 = y2;
}
x2 = tauMid;
y2 = xcMid;
else if (tauMid < x2){
//improve high point
assert(tauMid >= x1); // bitwise identical is OK
assert(tauMid > x1 || xcMid > y1); //expect improvement
x1 = tauMid;
y1 = xcMid;
}
else if (tauMid > x2){
//improve high point
assert(tauMid <= x3); // bitwise identical is OK
assert((tauMid < x3) || (xcMid > y3)); // expect improvement
x3 = tauMid;
y3 = xcMid;
}
else{
assert(("?? evaluated for existing tau ??", false));
}
}
/*************Calculate uncertainty (Window Width)********************/
eIter =abs(x3-x1);
}
The entire Matlab program can be found here :
https://www.dsprelated.com/showcode/288.php
I will be very grateful for any help
Well, my Matlab training is really far away in time, but assuming that e = [e eIter] means that you append a value to e, then you need use a vector
define your e vector somewhere like this: you already done that in your code. Maybe you copied/pasted some code, I don't know, it looks rather neat.
std::vector<double> e;
However I doubt that will compile since you also have a Complex e declaration in the same scope...
// then in your loop populate it like this
eIter = abs(x3 - x1); // (this is your code)
e.push_back(eIter); // push_back was the method you need
Then you can access elements of e just like a standard C-array:
e[i]
To perform a loop, I use an old-style C++ iteration. I know there is better but my C++ is a bit rusty since 2006. Comments/edits are welcome to improve this:
// replace const_iterator by iterator to be able to modify the values
std::vector<double>::const_iterator it;
for (it = e.begin(); it != e.end(); it++)
{
const double &value = *it; // (remove const to be able to change the value)
...

Unit testing not failing but hanging on subroutine call

I am unit testing the following C++ code using Visual Studio 2015's built in test framework. When I run the test below, no error is thrown (and the code compiles), but the test just hangs. It only does it when the line I have commented out which calls averageGradient is run. Why is this?
float averageGradient(int x1, int x2) {
int i = 0, y1 = 0, y2 = 0;
while (i < graph.size() && (y1 == 0 || y2 == 0)) { //if both y values haven't been solved then keep trying
if (x1 >= graph[i][0] && x1 < graph[i][1]) { // if x1 lies in the first straight line segment
y1 = (graph[i][2] * x1) + graph[i][2]; // then calculate it's y value (y1)
}
else if (x2 >= graph[i][0] && x2 < graph[i][1]) { //try the same thing for x2
y2 = (graph[i][2] * x2) + graph[i][3]; //calculate its y value (y2)
}
else { i++; } //otherwise incriment i to check the next straight line segment
}
float m = (y2 - y1) / (x2 - x1);
return m;
};
Unit Testing:
TEST_METHOD(Average_Gradient) {
int x1 = 683675;
int x2 = x1 + 86400;
//float gradient = averageGradient(x1, x2);
float answer = 0.0000895684639;
//Assert::AreEqual(answer, gradient);
}
There is an infinite loop in your code. This is not related to unit test.
float averageGradient(int x1, int x2) {
int i = 0, y1 = 0, y2 = 0;
while (i < graph.size() && (y1 == 0 || y2 == 0)) // 1
{
if (x1 >= graph[i][0] && x1 < graph[i][1]) // 2
{
y1 = (graph[i][2] * x1) + graph[i][2]; // 3
}
else if (x2 >= graph[i][0] && x2 < graph[i][1]) // 4
{
y2 = (graph[i][2] * x2) + graph[i][3];
}
else { i++; }
}
float m = (y2 - y1) / (x2 - x1);
return m;
};
In the first iteration of your loop, let's assume that condition in line marked with // 2 is true.
You enter line // 3, and change y1. i and y2 are not modified.
Now you go to next iteration.
i hasn't changed so i < graph.size() is still true.
y2 hasn't changed so (y1 == 0 || y2 == 0) is still true.
Thus, you go to line // 2: the condition is true again, as neither x1 nor graph[] values have changed.
Execution enters // 3, y1 is not modified
Execution continues at 3. (infinite loop)
If your first iteration enters // 4 instead of // 2, the same thing happens.
You should be able to easily analyze this just by running your code under debugger.

Algo for finding continuous items in log(N) time

Does anyone have a concise answer for this below? I saw this on career cup. http://www.careercup.com/question?id=4860021380743168
Given a binary representation of an integer say 15 as 1111, find the maximum longest continuous sequence of 0s. The twist is it needs to be done in log N.
For example. 10000101
the answer should be 4, because there are 4 continuous zeroes.
If you have an answer in c++ that would be best for me
Pretty trivial, just go through the binary notation, one linear pass. The binary notation has length log(N), so it will take log(N) time.
Seems like this has been asked before.
However, when I feel the need for bit-twiddling, I reach for my copy of the incomparable Hackers Delight. As it turns out, it contains discussions on finding the longest string of 1 bits, including a "logarithmic" implementation that could be used here on the bit/flipped (not) input:
int fmaxstr0(unsigned x, int *apos) {
// invert bits.
x = ~x;
unsigned x2, x4, x8, x16, y, t;
int s;
if (x == 0) {*apos = 32; return 0;}
x2 = x & (x << 1);
if (x2 == 0) {s = 1; y = x; goto L1;}
x4 = x2 & (x2 << 2);
if (x4 == 0) {s = 2; y = x2; goto L2;}
x8 = x4 & (x4 << 4);
if (x8 == 0) {s = 4; y = x4; goto L4;}
x16 = x8 & (x8 << 8);
if (x16 == 0) {s = 8; y = x8; goto L8;}
if (x == 0xFFFFFFFF) {*apos = 0; return 32;}
s = 16; y = x16;
L16: t = y & (x8 << s);
if (t != 0) {s = s + 8; y = t;}
L8: t = y & (x4 << s);
if (t != 0) {s = s + 4; y = t;}
L4: t = y & (x2 << s);
if (t != 0) {s = s + 2; y = t;}
L2: t = y & (x << s);
if (t != 0) {s = s + 1; y = t;}
L1: *apos = nlz(y);
return s;
}
Have fun!

AntiAliasing routine for downsizing

i'm trying to implement a custom anti-aliasing routine by summing nearest pixels for downsizing an image.
I tried to sum and mean up to 3 pixels-wide but the result is not good, it's as much antialised (edit i mean aliased) as before.
here is the code i used:
h is height
w is width
buf is a buffer containing the values.
out is the output buffer
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
int n = 3;
int x1 = x - n;
int x2 = x + n;
if (x1 < 0) x1 = 0;
if (x2 > w -1) x2 = w - 1;
int y1 = y - n;
int y2 = y + n;
if (y1 < 0) y1 = 0;
if (y2 > h - 1) y2 = h - 1;
double sum = 0;
for (int i = x1; i <= x2; i++)
for (int j = y1; j <= y2; j++)
sum += buf[i][j];
sum = sum / double((x2 - x1 +1) * (y2 - y1 +1));
out[x][y] = sum;
}
What quick routine could i use to do a simple basic anti-aliasing?