I need to solve some simple linear integer programming-like problem, I took lp_solve library. The task is to obtain variables' values for some consequtive values of linear function with possible simple (linear) constraints on variables (actually I encountered a problem even without any additional constraints). E.g. I have linear function 4a + 5b. First values I'm interested in are (function value - variables values):
0 - (0, 0); 4 - (1, 0); 5 - (0, 1); 8 - (2, 0); 9 - (1, 1)
The problem is that after getting 8 - (2, 0), lp_solve returns NUMFAILURE code (5) while solving the task and resolves it to 0 - (0, 0)…
If I do not use consequtive calls to 'solve' function and just start from 9 then I got right answer (9 - (1, 1)). Would anyone please explain this? The code is following.
#include <iostream>
#include <cstdio>
#include <lpsolve/lp_lib.h>
# if defined ERROR
# undef ERROR
# endif
# define ERROR() { fprintf(stderr, "Error\n"); exit(1); }
using std::cout;
using std::endl;
void print_res(REAL * vars, int size) {
cout << "(";
for (int i = 0; i < size - 1; ++i) {
cout << round(vars[i]) << ", ";
}
cout << round(vars[size - 1]) << ")";
}
int main()
{
lprec *lp;
int majorversion, minorversion, release, build, min = 0;
lp_solve_version(&majorversion, &minorversion, &release, &build);
const int l = 5; // number of iterations
const int dim = 2; // dimension ot current task
char p_data[] = "4 5"; // objective function: p(a, b) = 4a + 5b
if ((lp=make_lp(0, dim)) == NULL)
ERROR();
set_verbose(lp, CRITICAL);
if (!str_add_constraint(lp, p_data, GE, min)) // p(a, b) >= min
ERROR();
// objective function - p
if (!str_set_obj_fn(lp, p_data))
ERROR();
// work with integer non-negative variables
set_int(lp, 1, TRUE);
set_int(lp, 2, TRUE);
set_lowbo(lp, 1, 0);
set_lowbo(lp, 2, 0);
for (int i = 0; i < l; ++i) {
cout << "Status: " << solve(lp) << endl;
REAL vars[dim];
get_variables(lp, vars);
print_res(vars, dim);
// increase minimum value for p
min = round(get_objective(lp));
cout << ", p = " << min << endl;
if (!set_rh(lp, 1, min + 1))
ERROR();
}
return 0;
}
Related
How can I find the smallest positive real number in a complex vector of size N by 1 in Eigen3? For example, in this case I'd like to find the value 3.64038.
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXd m(4, 4);
m << 1, 0, 1, 1,
0, 2, 0, 1,
0, 2, 1, 0,
2, 1, 2, 1;
cout << m << endl;
cout << m.eigenvalues() << endl;
return 0;
}
Output
1 0 1 1
0 2 0 1
0 2 1 0
2 1 2 1
(3.64038,0)
(-0.444745,0)
(0.902183,1.01932)
(0.902183,-1.01932)
Vector elements that have an imaginary part not equal to 0 should be excluded.
I wrote the following function, but was wondering if there is an approach using Eigen's methods.
double findPositiveRealMin(VectorXcd v)
{
VectorXd v_imag = v.imag();
VectorXd v_real = v.real();
for (int i = 0; i < v.rows(); i++)
{
if (v_imag[i] != 0 | v_real[i] <= 0)
v_real[i] = 1.0e16;
}
return v_real.minCoeff();
}
One option is to create a logical array and then call Eigen::select on it. Inspired by https://forum.kde.org/viewtopic.php?f=74&t=91378
In this case:
Eigen::VectorXcd v = m.eigenvalues();
// minimum positive real value with zero imaginary part
Eigen::Array<bool,Eigen::Dynamic,1> cond1 = (v.imag().array() == 0);
Eigen::Array<bool,Eigen::Dynamic,1> cond2 = (v.real().array() > 0);
double some_big_value = 1e16;
std::cout << (cond1 && cond2).select(v.real(), some_big_value).minCoeff() << std::endl;
... or, as a one-liner:
std::cout << (v.imag().array() == 0 && v.real().array() > 0).select(v.real(), 1e16).minCoeff() << std::endl;
This one-liner uses the ternary operator in combination with Eigen's unaryExpr() method.
std::cout << m.eigenvalues().unaryExpr([](auto a){return a.imag() != 0 || a.real() < 0 ? 1.e16 : a;}).real().minCoeff() << std::endl;
As an exercise, I am trying to create a TicTacToe game in Visual Studio as a console application. First, I created the 3x3 grid with a multidimensional array. I thought an intuitive way to "write" an 'X' or an 'O' in a particular square of the grid would be by having the player input a number 1-9 and that number would map to a particular square. Below is how the numbers would be correspond to the spots in the grid:
1 2 3
4 5 6
7 8 9
Thus, I used std::multimap to map the player input to a square in the grid to practice using maps and multimaps. Since I am new to std::multimap I guess I messed up somewhere: there is no error, the game compiles, but the input does not seem to be mapping correctly to the right square.
I do not know how to fix the bug because I am unfamiliar with maps and multimaps.
*If someone could tell me how to fix the problem using the mapping method I have chosen that would be great!
*I'm also welcoming other and better ideas as to how to approach mapping player input to specific squares!
Sorry for the long code; I don't think I could cut anything more. Thanks for taking the time!
#include <iostream>
#include <map>
using namespace std;
class TTTClass
{
private:
static const int GRID_LENGTH = 3;
char Grid[GRID_LENGTH][GRID_LENGTH] = {' '};
int POInput;
int PXInput;
bool IsInputValid = false;
public:
TTTClass()
{
POInput = 1;
PXInput = 1;
}
void EmptyGrid()
{
for (int RowCounter = 0; RowCounter < GRID_LENGTH; RowCounter++)
{
for (int ColumnCounter = 0; ColumnCounter < GRID_LENGTH; ColumnCounter++)
{
Grid[RowCounter][ColumnCounter] = ' ';
}
}
}
void DisplayGrid()
{
for (int RowCounter = 0; RowCounter < GRID_LENGTH; RowCounter++)
{
std::cout << " ";
for (int ColumnCounter = 0; ColumnCounter < GRID_LENGTH; ColumnCounter++)
{
std::cout << Grid[RowCounter][ColumnCounter];
if (ColumnCounter != GRID_LENGTH - 1) {std::cout << " | ";}
}
if (RowCounter != GRID_LENGTH - 1)
{
std::cout << "\n __|___|__ \n | |\n";
}
}
std::cout << "\n\n";
}
void POTurn()
{
std::multimap<int, int> Gridmm;
Gridmm.insert(std::make_pair(1, 0)); Gridmm.insert(std::make_pair(1, 0));
Gridmm.insert(std::make_pair(2, 0)); Gridmm.insert(std::make_pair(2, 1));
Gridmm.insert(std::make_pair(3, 0)); Gridmm.insert(std::make_pair(3, 2));
Gridmm.insert(std::make_pair(4, 1)); Gridmm.insert(std::make_pair(4, 0));
Gridmm.insert(std::make_pair(5, 1)); Gridmm.insert(std::make_pair(5, 1));
Gridmm.insert(std::make_pair(6, 1)); Gridmm.insert(std::make_pair(6, 2));
Gridmm.insert(std::make_pair(7, 2)); Gridmm.insert(std::make_pair(7, 0));
Gridmm.insert(std::make_pair(8, 2)); Gridmm.insert(std::make_pair(8, 1));
Gridmm.insert(std::make_pair(9, 2)); Gridmm.insert(std::make_pair(9, 2));
do
{
std::cout << "PlayerO, select a square: ";
std::cin >> POInput;
if (POInput < 1 || POInput > 9)
IsInputValid = false;
else
{
std::pair<std::multimap<int, int>::iterator, std::multimap<int, int>::iterator> RepeaterIterator;
RepeaterIterator = Gridmm.equal_range(POInput);
std::multimap<int, int>::iterator itr1 = RepeaterIterator.first;
std::multimap<int, int>::iterator itr2 = RepeaterIterator.second;
Grid[itr1->second][itr2->second] = 'O';
std::cout << "Value at square " << POInput << "/ Coord. " << itr1->second << ", " << itr2->second;
std::cout << " is: " << Grid[itr1->second][itr2->second] << "\n";
IsInputValid = true;
}
} while (IsInputValid == false);
}
void PXTurn()
{
std::multimap<int, int> Gridmm;
Gridmm.insert(std::make_pair(1, 0)); Gridmm.insert(std::make_pair(1, 0));
Gridmm.insert(std::make_pair(2, 0)); Gridmm.insert(std::make_pair(2, 1));
Gridmm.insert(std::make_pair(3, 0)); Gridmm.insert(std::make_pair(3, 2));
Gridmm.insert(std::make_pair(4, 1)); Gridmm.insert(std::make_pair(4, 0));
Gridmm.insert(std::make_pair(5, 1)); Gridmm.insert(std::make_pair(5, 1));
Gridmm.insert(std::make_pair(6, 1)); Gridmm.insert(std::make_pair(6, 2));
Gridmm.insert(std::make_pair(7, 2)); Gridmm.insert(std::make_pair(7, 0));
Gridmm.insert(std::make_pair(8, 2)); Gridmm.insert(std::make_pair(8, 1));
Gridmm.insert(std::make_pair(9, 2)); Gridmm.insert(std::make_pair(9, 2));
do
{
std::cout << "PlayerX, select a square: ";
std::cin >> PXInput;
if (PXInput < 1 || PXInput > 9)
IsInputValid = false;
else
{
std::pair<std::multimap<int, int>::iterator, std::multimap<int, int>::iterator> RepeaterIterator;
RepeaterIterator = Gridmm.equal_range(PXInput);
std::multimap<int, int>::iterator itr1 = RepeaterIterator.first;
std::multimap<int, int>::iterator itr2 = RepeaterIterator.second;
Grid[itr1->second][itr2->second] = 'X';
std::cout << "Value at square " << POInput << "/ Coord. " << itr1->second << ", " << itr2->second;
std::cout << " is: " << Grid[itr1->second][itr2->second] << "\n";
IsInputValid = true;
}
} while (IsInputValid == false);
}
};
int main()
{
TTTClass MyGame;
MyGame.EmptyGrid();
MyGame.DisplayGrid();
MyGame.PXTurn();
MyGame.DisplayGrid();
MyGame.POTurn();
MyGame.DisplayGrid();
return 0;
}
BTW, I know the game only runs through two turns, but problem shows up regardless.
(Too long for a comment and, may be, actually an answer.)
I believe, OP missed the point that the required mapping is int → int × int.
Either the value type has to be e.g. std::pair<int, int> or there are two mappings needed – one to map input to rows and one to map input to columns.
However, there is a very simple linear relation between input index and grid coordinates:
1 -> 0, 0 | 2 -> 0, 1 | 3 -> 0, 2
----------+-----------+----------
4 -> 1, 0 | 5 -> 1, 1 | 6 -> 1, 2
----------+-----------+----------
7 -> 2, 0 | 8 -> 2, 1 | 9 -> 2, 2
I.e. for input int i: int col = (i - 1) % 3, row = (i - 1) / 3;.
This aside: If OP really wants to use a map, then std::map<int, std::pair<int, int> > makes more sense than multimap.
A std::map is a sorted associative container that contains key-value pairs with unique keys. (which you have). Each input index maps to exactly one grid cell and there are no duplicated keys.
It is irrelevant that the value is a pair of ints. It can be rather any object with a minimal requirement of properties:
CopyInsertable
EqualityComparable
Destructible
A std::multimap is an associative container that contains a sorted list of key-value pairs, while permitting multiple entries with the same key. (which you don't need as your keys are unique).
in OPs code:
std::cin >> i;
if (i >= 1 && i <= 9) {
Grid[/* row: */(i - 1) / 3, /* col: */(i - 1) % 3] = mark;
} else {
// harass user
}
Thereby, char mark could have 'X' or 'O' to consider the hint of PaulMcKenzie about code duplication.
It compiles fine, prints the first "start" but it stops right there. Any help is greatly appreciated. I spent several hours trying to figure out whats wrong and tried running it within several different IDEs. I think it fails at the while-loop.
#ifndef TERNARY_SEARCH_H
#define TERNARY_SEARCH_H
#include <cstdlib>
#include <iostream>
template <typename ArrayLike, typename T>
int ternary_search(const ArrayLike& array, const T& value, int low, int high)
{
/*
* low is the lowest possible index, high is the highest possible index
* value is the target value we are searrching for
* array is the ascending order array we are searching
*/
bool found = false;
while(!found)
{
int lowerThirdIndex = (((high - low)/(3)) + low);
int upperThirdIndex = (2*((high - low)/(3)) + low);
// search lower third
if (array[lowerThirdIndex] == value)
{
return lowerThirdIndex;
found = true;
}
else if (array[lowerThirdIndex] > value)
{
high = lowerThirdIndex;
}
else // array[lowerThirdIndex] < value
{
low = lowerThirdIndex;
}
//search upper third
if (array[upperThirdIndex] == value)
{
return upperThirdIndex;
found = true;
}
else if (array[upperThirdIndex] > value)
{
high = upperThirdIndex;
}
else // array[upperThirdIndex] < value
{
low = upperThirdIndex;
}
}
return -1;
}
#endif /* TERNARY_SEARCH_H */
//main.cpp
#include "ternary_search.h"
using namespace std;
int main() {
cout << "start";
int nums[] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90};
for (int i = 0; i <= 90; i += 10) {
if (ternary_search(nums, i, 0, 10) != i / 10) {
std::cout
<< "Searching for " << i << " returned index "
<< ternary_search(nums, i, 0, 10) << " instead of "
<< i / 10 << "." << std::endl;
return 1;
}
// search for something that doesn't exist.
if (ternary_search(nums, i + 1, 0, 10) != -1) {
std::cout
<< "Searching for " << i + 1 << " returned index "
<< ternary_search(nums, i + 1, 0, 10) << " instead of -1."
<< std::endl;
return 1;
}
}
std::cout << "On this small example, your search algorithm seems correct.\n";
return 0;
}
Your ternary_search function doesn't have a means to return when it fails to find the value in the search table. It returns only when it finds an element in the table that exactly matches the value you pass in.
Since the second invocation of the function is called with i+1 -- which is 1 -- which is not a member of your table, your ternary search function never exits.
Working on below algorithm puzzle of finding minimum number of jumps. Posted detailed problem statement and two code versions to resolve this issue. I have did testing and it seems both version works, and my 2nd version is an optimized version of version one code, which makes i starts from i=maxIndex, other than continuous increase, which could save time by not iteration all the slots of the array.
My question is, wondering if my 2nd version code is 100% correct? If anyone found any logical issues, appreciate for pointing out.
Problem Statement
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
First version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
while (end < n - 1) {
step++;
for (;i <= end; i++) {
maxend = max(maxend, i + nums[i]);
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
2nd version code
class Solution {
public:
int jump(vector<int>& nums) {
int i = 0, n = nums.size(), step = 0, end = 0, maxend = 0;
int maxIndex = 0;
while (end < n - 1) {
step++;
for (i=maxIndex;i <= end; i++) {
if ((i + nums[i]) > maxend)
{
maxend = i + nums[i];
maxIndex = i;
}
if (maxend >= n - 1) return step;
}
if(end == maxend) break;
end = maxend;
}
return n == 1 ? 0 : -1;
}
};
thanks in advance,
Lin
The best way is always to test it. A human cannot always think about special cases but a automated test can cover the most of speciale cases. If you think that your first version works well, you can compare the result of the first with the second one. Here an exemple:
/*
* arraySize : array size to use for the test
* min : min jump in the array
* max : max jump in the array
*/
void testJumps(int arraySize, int min, int max){
static int counter = 0;
std::cout << "-----------Test " << counter << "------------" << std::endl;
std::cout << "Array size : " << arraySize << " Minimum Jump : " << min << " Max Jump" << max << std::endl;
//Create vector with random numbers
std::vector<int> vecNumbers(arraySize, 0);
for(unsigned int i = 0; i < vecNumbers.size(); i++)
vecNumbers[i] = rand() % max + min;
//Value of first function
int iVersion1 = jump1(vecNumbers);
//Second fucntion
int iVersion2 = jump2(vecNumbers);
assert(iVersion1 == iVersion2);
std::cout << "Test " << counter << " succeeded" << std::endl;
std::cout << "-----------------------" << std::endl;
counter++;
}
int main()
{
//Two test
testJumps(10, 1, 100);
testJumps(20, 10, 200);
//You can even make a loop of test
//...
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
So, I'm creating a program to create a (sort of) simulation of a melee deathmatch video game (not actually making a video game at the moment, just making simple AIs with goals to kill each other). In order to do this, I am using a tile-based, turn-based system.
Now the introduction is out of the way, here is the specific problem: in one of the arrays I am using, the last value is stored incorrectly in RAM, no matter how many variables in the array. Here is the relevant code:
(I will post all the code I have at the bottom of this, but the problem is in here)
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
int npcTileAttacker[] = { 0, 0, 0, 0, 0};
int s = 0;
while (s < 6)
{
cout << "The value that is being selected from the array is " << s << endl;
cout << npcTileAttacker[s] << endl;
s++;
cout << "The value of s has now been set to " << s << endl;
}
This outputs:
The value that is being selected from the array is 0
0
The value of s has now been set to 1
The value that is being selected from the array is 1
0
The value of s has now been set to 2
The value that is being selected from the array is 2
0
The value of s has now been set to 3
The value that is being selected from the array is 3
0
The value of s has now been set to 4
The value that is being selected from the array is 4
0
The value of s has now been set to 5
The value that is being selected from the array is 5
-858993640
The value of s has now been set to 6
Obviously, this last value from the array is incorrect. What I want to know is why this would be happening.
In addition to this, when the program ends, I get an error message:
"Run-Time Check Failure #2 - Stack around the variable 'npcTileAttacker' was corrupted."
I have tried placing the output values of s and the array piece of code around other arrays in the program, resulting in the same problem occuring.
Here is my full code, if required:
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
int numberOfNPCs = 5;
//Remember whose alive (so we can skip the dead's turns)
int npcAlive[5] = { 1, 1, 1, 1, 1 };
/*This determines what action is going to be carried out on this square. For the moment:
if npcTileActivity[n] = 1;
the goals is death
WARNING! THIS WILL RESULT IN BUGS!!! I need to figure out a way that allows multiple activities on a tile
(maybe apply actions onto NPCs directly, rather than onto their tiles)
*/
int npcTileActivity[] = { 0, 0, 0, 0, 0};
//This tells you who is doing the action on this tile
int npcTileAttacker[5] = { 1, 2, 3, 4, 0 };
int s = 0;
while (s < 6)
{
cout << "The value that is being selected from the array is " << s << endl;
cout << npcTileAttacker[s] << endl;
s++;
cout << "The value of s has now been set to " << s << endl;
}
//This determines whether or not the NPC will fight back. Currently pointless, as this will just kill them.
int npcPacifism[5] = { 0 };
//This is their HP
int npcDefense[5] = {5, 5, 5, 5, 5};
//This is the default damage (presumably this is done with knives)
int npcOffense[5] = {1, 1, 1, 1, 1};
/*This determines what each NPC wants to do.
1 - Kill Target
*/
int npcGoal[5] = {1, 1, 1, 1, 1};
//This is the NPC they are aiming at
int npcTarget[5] = {1, 2, 3, 4, 0};
/*The x coord for their target. In the future:
-I want this to be able to be changed during the sim
-This should be disabled until the NPC can find out where their target is
*/
int npcGoalLocationX[5] = {4, 1, 4, 3, 1};
/* The Y coord for their target
*/
int npcGoalLocationY[5] = {2, 3, 4, 2, 1};
/*Their x coord.
This will change, then the all npcGoalLocations need to be updated
*/
int npcLocationX[5] = {1, 4, 1, 4, 3};
/* Their y coord.
*/
int npcLocationY[5] = {1, 2, 3, 4, 2};
int m = 1;
while (m != 0)
{
int i = 0;
//Loop until every npc has had a turn
while (i < (numberOfNPCs + 1))
{
/*npcGoalLocationY[i] = npcLocationY[npcTarget[i]];
npcGoalLocationY[i] = npcLocationY[npcTarget[i]];*/
if (npcAlive[i] = 1)
{
/* Tile activities:
1 - Kill occupant
*/
if (npcTileActivity[i] = 1)
{
cout << "This shouldn't be the first thing." << endl;
//This gets the attack and defense values for the appropriate acting NPC
int j = 0;
while (j < (numberOfNPCs + 1))
{
if (npcTileAttacker[i] = j)
{
//Defender's HP - Attacker's damage
int rollAttack1 = npcDefense[i] - npcOffense[j];
if (rollAttack1 > 0)
{
npcDefense[i] = rollAttack1;
cout << "NPC " << j << " attacks NPC " << i << endl;
if (npcPacifism[i] = 0)
{
//Defender retaliates
int rollAttack2 = npcDefense[j] - npcOffense[i];
if (rollAttack2 > 0)
{
npcDefense[j] = rollAttack2;
cout << "NPC " << i << " retaliates" << endl;
}else
{
npcAlive[j] = 0;
cout << "NPC " << j << " dies" << endl;
}
}
}else
{
npcAlive[i] = 0;
cout << "NPC " << i << " dies" << endl;
}
}
j++;
}
}else
{
cout << "This should be the first." << endl;
if (npcGoal[i] != 0)
{
if (npcGoalLocationX[i] = npcLocationX[i])
{
if (npcGoalLocationY[i] = npcLocationY[i])
{
//The Tile Activity of the current NPC's target is set to whatever the current NPC's goal is
npcTileActivity[npcTarget[i]] = npcGoal[i];
}
}
if (npcGoalLocationX[i] > npcLocationX[i])
{
npcLocationX[i]++;
}
if (npcGoalLocationX[i] < npcLocationX[i])
{
npcLocationX[i]--;
}
if (npcGoalLocationY[i] > npcLocationY[i])
{
npcLocationY[i]++;
}
if (npcGoalLocationY[i] < npcLocationY[i])
{
npcLocationY[i]--;
}
}
}
}
i++;
}
cin >> m;
}
return 0;
}
Also, I get a problem (around the lines which cout "This should be first" and "This shouldn't be the first thing"): The one which shouldn't be first is first and the one which should be first never even executes. This is probably related to the array error, however.
Thanks for your assistance.
Your condition is off by one:
while (s < 6)
should be
while (s < 5)
The array { 0, 0, 0, 0, 0} has five elements, so valid indexes are 0,1,2,3,4.
Your condition stops when s < 6 is false, so it's still true for s == 5.
Your array has only 5 cells:
int npcTileAttacker[] = { 0, 0, 0, 0, 0};
That is, s should go from 0 to 4, instead of 0 to 5.
The "random" value that you are seeing is in fact whatever value was there on the stack after npcTileAttacker array since you are overflowing that array.
The size of your array is 5. Hence the valid indices are from 0-4. So, npcTileAttacker[5] will always post garbage.
You're out by 1 in your while loop expression.
You'd also be better off using a for loop and not hard coding the length of the array. Try something like this:
int npcTileAttacker[] = { 0, 0, 0, 0, 0};
int npcTileAttackerLength = sizeof(npcTileAttacker)/sizeof(npcTileAttacker[0]);
for(int s=0; s<npcTileAttackerLength; s++)
{
cout << "The value that is being selected from the array is " << s << endl;
cout << npcTileAttacker[s] << endl;
}
This way the length variable will always hold the number of items in the array.