I have following struct,
struct cube
{
int index l , b , h;
bool operator<(const cube & c2) const
{
if (l == c2.l && b == c2.b && h == c2.h)
return index < c2.index;
if (l == c2.l && b == c2.b)
return h < c2.h;
if (l == c2.l )
return b < c2.b;
return l < c2.l;
}
bool operator==(const cube c2)
{
return index != c2.index && l == c2.l && b == c2.b;
}
};
Now I want to apply upper_bound on vector of this struct as per condition in == operator.
However , it is still returning me those iterators where index are same
int pos2 = upper_bound(v.begin(),v.end(),v[i]) - v.begin();
i.e v[i].index is equal to v[pos2].index
It's possible that for two cube instances foo and bar that foo < bar is true when foo == bar is also true. You could fix that by writing index == c2.index && l == c2.l && b == c2.b as the returned expression in operator==.
This contradiction is the root cause of your issues, although note that std::upper_bound does itself only require that operator< is implemented appropriately; which yours is.
Isn't index more of a property of a collection of cubes rather than a given cube? That is, it shouldn't appear in the cube class?
Related
The model is optimizing the costs of Machines in Cell layout design
regarding the duplication and subcontracting.
Mod Const. is,
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
SC[i][j][k] == 0;
INT[i][j][k] == 0;
}
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (V[i][j][k] == 1 && A[k][i] >= ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 0;
SC[i][j][k] == 1;
INT[i][j][k] == 1;}
U , V are extracted in previous steps, A, D, S are input data.
The variables reqd. are DN, SC and INT.
Errors are those expressions are cannot be extracted, U, V are unbounded,
Please help in this regard,
Since U and V are decision variables, you should not write:
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
Instead write:
((U[i][j][k] == 1) && (A[k][i] <= -1+((D[k][j]*S[k][j])*52)))
=> (DN[i][j][k] == 1);
How do I check the equality between four variables? This is for a 3D tic-tac-toe game.
if (b[0][0] == b[1][0] == b[2][0] == p) { line += 1; }
This doesn't work as equivalent is left-to-right. I don't want to do either of the below:
if (b[0][0] == p && b[1][0] == p && b[2][0] == p) { line += 1; }
if ((b[0][0] == b[1][0]) && (b[1][0] == b[2][0]) && (b[2][0] == p)) { line += 1; }
All variables are integers, as I know with bools I can just use &&. Is there a better way? I considered:
if ((b[0][0] + b[1][0] + b[2][0]) == (3 * p)) { line += 1; }
Since p will be one of three values (0 for neither X or O, 1 for X, 2 for O), it would need only changing the value of O to 4 or something impossible to achieve with three 1s, 0s, or combinations thereof. But it lacks finesse.
Since 3 out of 4 variables in the question belong to one object, you can create a method to wrap it all. Something like bool isValid(int *A, int val) {...} and then use it in your statement like if (isValid(b, p)) {...}. The name is arbitrary since the wider context is not given.
Now that you've mentioned tic-tac-toe, things change a bit. Ultimately you'll be checking each column for the same value and each row for the same value. That doesn't require a long if ... else if... ladder. Instead, write a function to check a row:
bool row_matches(board b, int row, int value) {
for (int col = 0; col < 3; ++col)
if (b[row][col] != value)
return false;
return true;
}
and write a similar function for columns. Diagonals are even simpler.
How c++ set/map checks the equality of keys ?
for example in this example :
struct A
{
int id , val;
A( int _val = 0 , int _id = 0 )
{ val = _val , id = _id; }
bool friend operator < ( const A &x , const A &y )
{
return x.val < y.val;
}
};
set< A > s;
because we haven't written the == operator ?
it checks if (!(x < y) && !(y < x))
operator== is not used by std::set. Elements a and b are considered equal iff !(a < b) && !(b < a)
Note: A set is probably inappropriate if you define equality in a different sense than ordering. Equality in set essentially means the two element will have the same place in sorted sequence of items.
I have the following code:
bool s = true;
for (...; ...; ...) {
// code that defines A, B, C, D
// and w, x, y, z
if (!(A < w) && s == true) {
s = false;
}
if (!(B < x) && s == true) {
s = false;
}
if (!(C < y) && s == true) {
s = false;
}
if (!(D < z) && s == true) {
s = false;
}
}
This code is working well. However, I want to, for several (unimportant) reasons, change the code so that I can initiate s = false; and set it to true inside the if-statement. It tried the following:
bool s = false;
for (...; ...; ...) {
// code that defines A, B, C, D
// and w, x, y, z
if (A >= w && s == false) {
s = true;
}
if (B >= x && s == false) {
s = true;
}
if (C >= y && s == false) {
s = true;
}
if (D >= z && s == false) {
s = true;
}
}
However, this is not working properly as the code above is working. I know thought wrong somewhere in the logic, but I can't figure out where. Does anbyone see my probably obvious error?
EDIT: Added three more if-statemets. Missed them since they were commented away.
De Morgan's laws says, you should also change && to || .
!(A < x) is the same as A >= x so your function hasn't reversed the logic at all. You need to use A < x.
I probably wouldn't bother checking the current state of s in the loop. Either you're flipping it or your not. And unless there's some reason to continue through the loop, I'd probably break after flipping s.
I found the answer on Wikipedias page on De Morgan's laws. The correct code for my problem is:
bool s = false;
for (...; ...; ...) {
// code that defines A, B, C, D
// and w, x, y, z
if (!(A >= w || s == false)) {
s = true;
}
if (!(B >= x || s == false)) {
s = true;
}
if (!(C >= y || s == false)) {
s = true;
}
if (!(D >= z || s == false)) {
s = true;
}
}
Thanks #EJP for the tip!
The part of the loop body that sets s is logically equivalent to this:
if(A >= w || B >= x || C >= y || D >= z)
s = false;
Which, abstracting the condition, is equivalent to this:
s &= some_function(A, B, C, D, w, x, y, z);
You want to change it to this:
s |= some_other_function(A, B, C, D, w, x, y, z);
In the first case, s is true after the loop if some_function returns false on every iteration of the loop. In the second true, s is true after the loop if some_other_function returns true on any iteration of the loop.
some_other_function can only ever return true if some_function would return true on any iteration. But some_other_function only has access to the values from the current iteration. Therefore a valid some_other_function cannot exist.
This is assuming s must have the same value after the loop in both cases. Otherwise, you could trivially swap true and false in all the places relating to s.
I am trying to use the std::set to contain a struct of three member variables.
struct blah{
int a,b,c;
bool operator < ( const blah& blo ) const{
return ( a < blo.a || (a == blo.a && (b != blo.b || c != blo.c ) ) );
}
};
But I keep getting an error that my operator < is invalid. What is wrong with my approach?
struct blah {
int a,b,c;
blah(int aa,int bb,int cc){ a=aa; b=bb; c=cc; }
bool operator < ( const blah& blo ) const{
return ( a < blo.a
|| (a == blo.a && b < blo.b )
|| (a == blo.a && b == blo.b && c < blo.c )
);
}
};
int main() {
std::set<blah> st;
st.insert(blah(1,2,3));
st.insert(blah(1,1,1));
st.insert(blah(1,3,2));
return 0;
}
After altering the code following #paxdiablo code, this worked well. Thanks y'all!
That code compiles fine for me in the following complete program:
#include <iostream>
struct blah {
int a,b,c;
bool operator < ( const blah& blo ) const{
return ( a < blo.a || (a == blo.a && (b != blo.b || c != blo.c ) ) );
}
};
int main (void) {
blah x, y;
x.a=2; x.b=2; x.c=2;
y.a=2; y.b=2; y.c=2;
if (x < y) std::cout << "x<y\n";
if (y < x) std::cout << "x>y\n";
if (!(y < x) && !(x < y)) std::cout << "x=y\n";
return 0;
}
Changing the fields of x and y outputs different messages.
But I see one major problem with the function. It can tell you that both x < y and y < x, in the situation where the two a fields are identical but the b fields differ between the two. If you set both a fields to 1 and set the b fields to 2 and 1, you see:
x<y
y<x
That's not going to end well :-)
The fact that what you're getting is a debug assertion (something specifically built to catch runtime errors in mostly debug code) leads me to believe that the runtime libraries may explicitly be checking for incorrect operator< overloads by detecting that latter case (ie, both x < y and y < x are true).
You should really fix that because it will cause all sorts of problems with collections where (for example) you need to keep things sorted.
By way of example, let's say you wanted to use a, b and c as keys in that priority. A function to do that would contain something like:
// Check primary key.
if (a < blo.a) return true;
if (a > blo.a) return false;
// Primary key equal here, use secondary key.
if (b < blo.b) return true;
if (b > blo.b) return false;
// Primary and secondary keys equal here, use tertiary key.
return (c < blo.c);