I'm trying to find the "path" to connect two points in a c++ boost polygon.
I have a polygon like that
namespace bgm = bg::model;
using Point = bgm::d2::point_xy<double>;
bgm::polygon<Point> poly;
bg::read_wkt("POLYGON((" + points_poly + "))", poly);
And i have randoms points in the polygon.
And i would like to know if boost c++ have tools to help in a case like that.
It's pretty unclear what the actual question is, so here's what asnwers directly to your question:
Poly poly{{
{-4, 14}, {17.75, 13.99}, {17.75, 7.95}, {10, 8}, {10, 2},
{16, 2}, {16, -8}, {22, -8}, {13.97, -13.17}, {6, -8},
{12, -8}, {12, -2}, {-0.99, -2.06}, {-0.9, -7.95}, {-18, -8},
{-18, 2}, {-10, 2}, {-10, 6}, {-6, 6}, {-6, 2},
{-2, 8}, {-7.05, 8}, {-7.15, 14}, {-4, 14},
}};
Point A{-7.08, 10.07};
Point B{10, 4};
LineString path{A, {4, 10}, {4, 4}, B};
The WKT for those is:
poly: POLYGON((-4 14,17.75 13.99,17.75 7.95,10 8,10 2,16 2,16 -8,22 -8,13.97
-13.17,6 -8,12 -8,12 -2,-0.99 -2.06,-0.9 -7.95,-18 -8,-18 2,-10 2,-10 6,-6 6,
-6 2,-2 8,-7.05 8,-7.15 14,-4 14))
A: POINT(-7.08 10.07)
B: POINT(10 4)
path: LINESTRING(-7.08 10.07,4 10,4 4,10 4)
Turning it into a SVG image:
Live On Coliru
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <iostream>
#include <fstream>
namespace bg = boost::geometry;
namespace bgm = bg::model;
using Point = bgm::d2::point_xy<double>;
using Poly = bgm::polygon<Point>;
using LineString = bgm::linestring<Point>;
int main() {
Poly poly{{
{-4, 14}, {17.75, 13.99}, {17.75, 7.95}, {10, 8}, {10, 2},
{16, 2}, {16, -8}, {22, -8}, {13.97, -13.17}, {6, -8},
{12, -8}, {12, -2}, {-0.99, -2.06}, {-0.9, -7.95}, {-18, -8},
{-18, 2}, {-10, 2}, {-10, 6}, {-6, 6}, {-6, 2},
{-2, 8}, {-7.05, 8}, {-7.15, 14}, {-4, 14},
}};
Point A{-7.08, 10.07};
Point B{10, 4};
LineString path{A, {4, 10}, {4, 4}, B};
std::cout << "poly: " << bg::wkt(poly) << "\n";
std::cout << "A: " << bg::wkt(A) << "\n";
std::cout << "B: " << bg::wkt(B) << "\n";
std::cout << "path: " << bg::wkt(path) << "\n";
{
std::ofstream svg("output.svg");
boost::geometry::svg_mapper<Point> mapper(svg, 400, 400);
mapper.add(poly);
mapper.add(path);
mapper.add(A);
mapper.add(B);
mapper.map(poly, "fill-opacity:0.3;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
mapper.map(path, "fill-opacity:0.05;fill:rgb(255,0,0);stroke:rgb(255,0,0);stroke-width:2");
mapper.map(A, "fill:red;stroke-width:20");
mapper.map(B, "fill:red;stroke-width:20");
mapper.text(A, "A", "");
mapper.text(B, "B", "");
}
}
Printing the WKT (see above) as well as writing output.svg:
Related
I was wondering how one can search for overlaps in a vector of tuples.
For example, I have the vector<tuple<int, int, int>> combo;, and the elements of the vector is:
{10, 101, 1},
{10, 102, 2},
{12, 102, 3},
{14, 90, 4},
{1, 10, 101},
{2, 10, 102},
{3, 12, 102},
{4, 14, 90},
{101, 1, 10},
{102, 2, 10},
{102, 3, 12},
{90, 4, 14}
Here, you can tell that the bottom 8 tuples are just repeats of the first 4, except the integers are reordered in a different way. I want to find the non-overlapping combinations of the elements, not the permutations of the elements.
If the 1st index of the tuple is called left, second if called middle, and third is called right, then in other words, left, middle, and right can overlap with itself, but not with the other 2 indexes.
Convert the elements to a canonical representation. This allows you use a set data structure or similar to identify duplicates.
I'm assuming here you're trying to find permutations that do not result in one of the elements remaining in place, i.e. for values { a, b, c} the matching permutations would be
{ a, b, c }
{ b, c, a }
{ c, a, b }
Furthermore I'm assuming even if multiple values are the same, they could be considered as listed in any order, i.e. { 1, 1, 2 } would match { 1, 2, 1 } even though the first element remains equal, since we could consider the first element to be the second one in the original.
This allows us use the lexicographically minimal alternative that as the canonical representation.
The following code uses std::array<int, 3> for convenience.
#include <array>
#include <iostream>
#include <map>
#include <vector>
using ValueType = std::array<int, 3>;
constexpr ValueType ToCanonical(ValueType const& original)
{
ValueType p1{ original[1], original[2], original[0] };
ValueType p2 { original[2], original[0], original[1] };
return (std::min)({ original, p1, p2 });
}
int main(void) {
std::vector<ValueType> const values
{
{10, 101, 1},
{10, 102, 2},
{12, 102, 3},
{14, 90, 4},
{1, 10, 101},
{2, 10, 102},
{3, 12, 102},
{4, 14, 90},
{101, 1, 10},
{102, 2, 10},
{102, 3, 12},
//{90, 4, 14},
//{10, 101, 1},
//{101, 10, 1},
//{10, 1, 101},
//{1, 101, 10},
//{1, 1, 2},
//{1, 2, 1},
//{2, 1, 1},
};
std::map<ValueType, size_t> indices;
for (size_t i = 0; i != values.size(); ++i)
{
auto insertResult = indices.try_emplace(ToCanonical(values[i]), i);
if (!insertResult.second)
{
std::cout << "The element at index " << i << " is a duplicate of the element at index " << insertResult.first->second << '\n';
}
}
return 0;
}
Hi guys i was looking around some old threads but i can't find anything that works for me. I need to shift second row in my array with cpp 98 from this
int mat[4][4] = {{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}};
to this
int mat[4][4] = {{1, 2, 3, 4},
{5, 6, 7, 8},
{12, 9 , 10, 11},
{13, 14, 15, 16}};
I don't want to print out anything just switching places in array, Thank you
One very easy method is this, first create a temporary array to store the initial values,
int temp[4] = { mat[2][3], mat[2][0], mat[2][1], mat[2][2] };
Then use std::memcpy to copy the data into mat[2],
std::memcpy(mat[2], temp, sizeof(int) * 4);
Bonus: You can use a scope to save some memory. It would be like this,
int mat[4][4] = { {1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16} };
...
{
int temp[4] = { mat[2][3], mat[2][0], mat[2][1], mat[2][2] };
std::memcpy(mat[2], temp, sizeof(int) * 4);
}
I guess that such an algorithm already exists.
I have two (or more, but two is sufficient for this problem) limits, e.g. limit_a=20 limit_b=18. Then I have some (a, b) pairs, e.g.
(5, 5), (3, 3), (4, 2), (1, 7), (3, 2), (5, 9), (7, 4)
The answer should be 5. An example of a solution: (7, 4), (3, 2), (1, 7), (4, 2), (3, 3)
I need to choose as many pairs as possible such that the sum of all "a" elements is less or equal to limit_a and analogously with "b". I thought that it is 2D Knapsack problem, but it isn't.
My best "solution" is to check all permutations of the list of these pairs and check the sums. It's fine for example, like above one, but of course not with bigger one's. My C++ code:
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
int main()
{
int limit_a = 20;
int limit_b = 18;
vector<pair<int, int>> vect;
vect.push_back(make_pair(5, 5));
vect.push_back(make_pair(3, 3));
vect.push_back(make_pair(4, 2));
vect.push_back(make_pair(1, 7));
vect.push_back(make_pair(3, 2));
vect.push_back(make_pair(5, 9));
vect.push_back(make_pair(7, 4));
int how_many_max = 0;
do {
int copy_a = limit_a;
int copy_b = limit_b;
int how_many = 0;
for ( vector<pair<int,int>>::const_iterator it = vect.begin(); it != vect.end(); it++){
copy_a -= it->first;
copy_b -= it->second;
if((copy_a < 0) || (copy_b < 0)) {
break;
}
how_many++;
}
if (how_many > how_many_max) how_many_max = how_many;
} while(next_permutation(vect.begin(), vect.end() ));
cout << how_many_max;
return 0;
}
Example:
int limit_a = 30;
int limit_b = 80;
std::vector<std::pair<int, int>> vect = {{37, 20}, {90, 45}, {76, 33}, {3, 93}, {66, 71}, {48, 21}, {8, 28}, {24, 83}, {99, 13}, {42, 52}, {81, 15}, {2, 38}, {7, 19}, {32, 65}, {70, 85}, {12, 82}, {61, 6}, {60, 31}, {46, 34}, {43, 62}, {41, 78}, {64, 80}, {88, 86}, {77, 16}, {44, 100}, {92, 57}, {40, 53}, {9, 56}, {68, 67}, {23, 11}, {35, 30}, {69, 84}, {75, 27}, {87, 26}, {50, 36}, {79, 73}, {4, 91}, {17, 98}, {51, 29}, {25, 95}, {14, 55}, {10, 58}, {54, 49}, {97, 63}, {59, 72}, {1, 39}, {18, 22}, {94, 74}, {96, 5}, {47, 89}
Should give 3: ({2, 38}, {7, 19}, {18, 22})
It is a 2D knapsack problem, just the profits are all 1. The usual approach of generating subsets interleaved with pruning where a partial subsolution obviously dominates another applies.
Some quick code below, using sorting instead of a merge for convenience.
#include <algorithm>
#include <iostream>
#include <tuple>
#include <utility>
#include <vector>
int main() {
int limit_a = 20;
int limit_b = 18;
std::vector<std::pair<int, int>> vect = {{5, 5}, {3, 3}, {4, 2}, {1, 7},
{3, 2}, {5, 9}, {7, 4}};
limit_a = 30;
limit_b = 80;
vect = {{37, 20}, {90, 45}, {76, 33}, {3, 93}, {66, 71}, {48, 21}, {8, 28},
{24, 83}, {99, 13}, {42, 52}, {81, 15}, {2, 38}, {7, 19}, {32, 65},
{70, 85}, {12, 82}, {61, 6}, {60, 31}, {46, 34}, {43, 62}, {41, 78},
{64, 80}, {88, 86}, {77, 16}, {44, 100}, {92, 57}, {40, 53}, {9, 56},
{68, 67}, {23, 11}, {35, 30}, {69, 84}, {75, 27}, {87, 26}, {50, 36},
{79, 73}, {4, 91}, {17, 98}, {51, 29}, {25, 95}, {14, 55}, {10, 58},
{54, 49}, {97, 63}, {59, 72}, {1, 39}, {18, 22}, {94, 74}, {96, 5},
{47, 89}};
std::vector<std::vector<std::pair<int, int>>> frontier = {
{{limit_a, limit_b}}};
for (auto [a, b] : vect) {
frontier.push_back({});
for (std::size_t how_many = frontier.size() - 1; how_many > 0; how_many--) {
std::vector<std::pair<int, int>> &level = frontier[how_many];
for (auto [residual_a, residual_b] : frontier[how_many - 1]) {
if (residual_a >= a && residual_b >= b)
level.push_back({residual_a - a, residual_b - b});
}
if (level.empty())
continue;
std::sort(level.begin(), level.end(),
std::greater<std::pair<int, int>>());
auto output = level.begin();
auto input = output;
for (++input; input != level.end(); ++input) {
if (std::tie(input->second, input->first) >
std::tie(output->second, output->first))
*++output = *input;
}
level.erase(++output, level.end());
if ((false)) {
for (auto [residual_a, residual_b] : level) {
std::cout << residual_a << ',' << residual_b << ' ';
}
std::cout << '\n';
}
}
}
std::size_t how_many_max = frontier.size() - 1;
while (frontier[how_many_max].empty())
how_many_max--;
std::cout << how_many_max << '\n';
}
In higher dimensions, the pruning gets more complicated. The curse of dimensionality also kicks in because domination relation gets sparser. Integer programming might be a better solution here.
A naive search space for bottom-up dynamic programming seems to be O(n * limit_a * limit_b) but this can get a lot more idiosyncratic, depending on the input, so we could possibly favour a memoised recursion.
function f(pairs, a, b, i=0, memo={}){
if (i == pairs.length)
return 0;
const key = String([i, a, b]);
if (memo.hasOwnProperty(key))
return memo[key];
// Skip this pair
let best = f(pairs, a, b, i+1, memo);
const [l, r] = pairs[i];
// Maybe include this pair
if (l <= a && r <= b)
best = Math.max(best, 1 + f(pairs, a-l, b-r, i+1, memo));
return memo[key] = best;
}
var pairs = [
[5, 5], [3, 3], [4, 2],
[1, 7], [3, 2], [5, 9], [7, 4]
];
console.log(f(pairs, 20, 18));
Is it safe to declare a function as noexcept if it initialises and returns a std::unordered_map<int, string>. As an example:
std::unordered_map<int, std::string> get_raw_num_map() noexcept
{
return std::unordered_map<int, std::string>(
{{1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}, {5, "five"}, {6, "six"}, {7, "seven"}, {8, "eight"},
{9, "nine"}, {10, "ten"}, {11, "eleven"}, {12, "twelve"}, {13, "thirteen"}, {14, "fourteen"}, {15, "fifteen"},
{16, "sixteen"}, {17, "seventeen"}, {18, "eighteen"}, {19, "nineteen"}, {20, "twenty"}, {30, "thirty"},
{40, "forty"}, {50, "fifty"}, {60, "sixty"}, {70, "seventy"}, {80, "eighty"}, {90, "ninety"},
{100, "hundred"}, {1000, "thousand"}});
}
Construction of most collection types in C++ can throw, via allocation failing if nothing else. So a function returning one can also throw, and should not be declared noexcept.
I am making a TicTacToe program and I'm trying to use OOP techniques. Within my 'Board' class I am wanting the program to store each way a set of moves can be won.
I hope this can be demonstrated here:
Board.h
#pragma once
class Board
{
private:
int winningRows[8][3]; //Variable in question
public:
static const char X = 'X'; //Game piece 'X'
static const char O = 'O'; //Game piece 'O'
static const char EMPTY = ' '; //Empty game piece
static const char TIE = 'T'; //Game is tie
static const char NOONE = 'N'; //Nobody has won game yet
static const int numbOfSquares = 9; //Number of squares on the board
int InitializeWinningCombinations();
void FindWinner();
};
Board.cpp
#include "stdafx.h"
#include "Board.h"
int Board::InitializeWinningCombinations()
{
/*
The playing board
0, 1, 2
3, 4, 5
6, 7, 8
*/
//All possible ways player can win game
winningRows[8][3] = {
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
};
//return winnigRows[8][3];
}
void Board::FindWinner()
{
//I am wanting to get the variable here so I can play around with it later.
int winningRows = InitializeWinningCombinations();
}
I could just have the 'winningRows' variable inside the 'FindWinnner' function but from my understanding it is best to abstract as much as possible and have it as a member of the 'Board' class
Thank you for your time.
winningRows[8][3] = {
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
};
Is an attempted array assignment not an initialization and it cannot be done. You can initialize the array in a constructor like
Board() : winningRows{
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
} {}
Live Example
You'd have to change the signature to
int** InitializeWinningCombinations();
Then you could call it as
int** winningRows = InitializeWinningCombinations();