So, here is the problem.
I am given the lengths of 3 sides of a triangle.
The program calculates the area of the given triangle using determinates.
I assume that one vertex of the triangle is in the (0,0) point and the 2nd one is in the (c,0), where c is the length of the longest side. So what would be the easiest way to get the 3rd vertices coordinates.
I tried cosine theorem to get the line equation the side is going through, but it is a bit off
I have the determination solver program if you need it down here:
float det(int n, float mat[3][3])
{
int d=0;
int c, subi, i, j, subj;
float submat[3][3];
if(n == 2) {
return( (mat[0][0] * mat[1][1]) - (mat[1][0] * mat[0][1]));
}
else{
for(c = 0; c < n; c++){
subi = 0;
for(i = 1; i < n; i++){
subj = 0;
for(j = 0; j < n; j++){
if (j == c){
continue;
}
submat[subi][subj] = mat[i][j];
subj++;
}
subi++;
}
d = d + (pow(-1 ,c) * mat[0][c] * det(n - 1 ,submat));
}
}
return d;
}
.
.
.
ans=det.det(3,coords)*0.5;
Example picture of the triangle constructed in GeoGebra:
Related
There's a matrix, each of its cell contains an integer value (both positive and negative). You're given an initial position in the matrix, now you have to find a path that the sum of all the cells you've crossed is the biggest. You can go up, down, right, left and only cross a cell once.
My solution is using Bellman Ford algorithm: Let's replace all the values by their opposite number, now we've just got a new matrix. Then, I create an undirected graph from the new matrix, each cell is a node, stepping on a cell costs that cell's value - it's the weight. So, I just need to find the shortest path of the graph using Bellman-Ford algorithm. That path will be the longest path of our initial matrix.
Well, there's a problem. The graph contains negative cycles, also has too many nodes and edges. The result, therefore, isn't correct.
This is my code:
Knowing that xd and yd is the initial coordinate of the robot.
void MatrixToEdgelist()
{
int k = 0;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
int x = (i - 1) * n + j;
int y = x + 1;
int z = x + n;
if (j<n)
{
edges.push_back(make_tuple(x, y, a[i][j+1]));
}
if (i<n)
{
edges.push_back(make_tuple(x, z, a[i+1][j]));
}
}
}
void BellmanFord(Robot r){
int x = r.getXd();
int y = r.getYd();
int z = (x-1)*n + y;
int l = n*n;
int distance[100];
int previous[100]{};
int trace[100];
trace[1] = z;
for (int i = 1; i <= l; i++) {
distance[i] = INF;
}
distance[z] = a[x][y];
for (int i = 1; i <= l-1; i++) {
for (auto e : edges) {
int a, b, w;
tie(a, b, w) = e;
//distance[b] = min(distance[b], distance[a]+w);
if (distance[b] < distance[a] + w)// && previous[a] != b)
{
distance[b] = distance[a] + w;
previous[b] = a;
}
}
}
//print result
int Max=INF;
int node;
for (int i=2;i<=l;i++)
{
if (Max < distance[i])
{
Max = distance[i];
node = i;
}
}
if (Max<0)cout << Max << "\n";
else cout << Max << "\n";
vector<int> ans;
int i = node;
ans.push_back(i);
while (i != z)
{
i = previous[i];
ans.push_back(i);
}
for (int i=ans.size()-1;i>=0;i--)
{
int x, y;
if (ans[i] % n == 0)
{
x = ans[i] / n;
y = n;
}
else{
x = ans[i] / n + 1;
y = ans[i] - (( x - 1 ) * n);
}
cout << x << " " << y << "\n";
}
}
Example matrix
The result
Clearly that the distance should have continued to update, but it doesn't. It stops at the final node.
"Let's replace all the values by their opposite number"
Not sure what you mean by an opposite number. Anyway, that is incorrect.
If you have negative weights, then the usual solution is to add the absolute value of the most negative weight to EVERY weight.
Why Bellman-Ford? Dijkstra should be sufficient for this problem. ( By default Dijkstra finds the cheapest path. You find the most expensive by assigning the absolute value of ( the original weight minus the greatest ) to every link. )
double CountSum(double **mat, int R, int C)
{
double sum = 0.0;
for(int i = 0; i < R / 2; i++)
{
for(int j = 0; j < C / 2; j++)
{
sum += mat[i][j];
}
}
return sum;
}
Am I correct do this, or where I have mistakes? Or if you have some piece of advice on how to pass parameters to function, please tell me about that
Assuming R and C are number of rows and number of columns respectively, this code won't work.
If R = 2 then (R - 1) / 2 = 0 so the outer loop won't be executed, because i < 0 is always false.
Don't subtract one, R / 2 would be enough. There are corner cases though, when R and C aren't even.
About parameters: you can add R and C to parameter list instead of i and j. (double **mat, int R, int C) and pass them respectively. From this current code, it looks like they are just global variables. i and j can be declared inside the function.
Code:
double CountSum(double **mat, int R, int C)
{
double sum = 0.0;
for(int i = 0; i < R / 2; i++)
{
for(int j = 0; j < C / 2; j++)
{
sum += mat[i][j];
}
}
return sum;
}
This is the working code, I hope you understand how to use it - pass it an appropriate arguments. R and C being height and width of the matrix or dimensions can be called as well. Note that if R or C or both are odd, then you only get the sum of the smaller part always, if you want the bigger part, you should ceil it, thus use (R + 1) / 2 instead of R / 2 and similar for C.
I'm trying to do a normalization of data for a polinomial interpolation with perceptron, I'm using the following formula:
Where:
xi is a data point (x1, x2…xn).
x̄ is the sample mean.
s is the sample standard deviation.
and Z is my new value of input for the perceptron.
I'm programming in C ++, and plotting graph with freeglut.
My function for normalize:
vector<double> Perceptron::normalizar(double x) {
vector<double> aux;
aux.push_back(1.0);
for (unsigned i = 1; i < pesos.size(); i++) {
double t = (pow(x,i) - means[i]) / devianation[i];
aux.push_back(t);
}
return aux;
}
The problem is: before I did the normalization, the polynomial was converging to the points.
But after normalization, the polynomial is converging to other points, and I do not know where it is converging.
The formula for the polynomial would be as follows (with W being the weights of the perceptron):
So I used a mean formula for each value of x.
See the code:
void Perceptron::mean(Points P) { //P is a struct with all x and y values of the points.
means.clear(); //vector that stores the means
for (unsigned i = 0; i < weights.size(); i++) {
double m = 0;
for (unsigned j = 0; j < P.size(); j++) {
m += pow(P[i].x, i);
}
means.push_back(m / P.size());
}
}
void Perceptron::deviation(Points P) {
deviations.clear(); //vector that stores the deviations
for (unsigned i = 0; i < weights.size(); i++) {
double sd = 0;
for (unsigned j = 0; j < P.size(); j++) {
sd += pow(pow(P[j].x, i) - means[i], 2);
}
deviations.push_back(sqrt(sd / P.size()));
}
}
So I have decided to implement an algorithm based on vectors to solve the Closest pair of points problem (2D). It seems to work with easy cases like
1.2 4.5
2.4 1.2
3.3 1.1
4.4 4.4
7.7 1.1
1.1 2.1
8.6 1.9
3.3 9.0
And the output is correct (for this case it is 0.90554), but somebody has checked my code and said that there is an invalid memory reference somewhere. I've been really struggling with this piece of code but I've give up, there is no way to find what is wrong (bc the cases I try work!).
I would really appreciate if somebody could enlighten me!
Thanks in advance!
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
struct Point { double x, y; };
bool compareX (Point p, Point q) { return p.x < q.x; }
bool compareY (Point p, Point q) { return p.y < q.y; }
float dist(Point p1, Point p2) {
return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
double min_dist (vector<Point> pointsX, vector<Point> pointsY, int n) {
// BASE CASE.
if (n <= 3) {
double min = __DBL_MAX__;
for (int i = 0; i < n; ++i)
for (int j = i +1 ; j < n; ++j)
if (dist(pointsX[i], pointsX[j]) < min)
min = dist(pointsX[i], pointsX[j]);
return min;
}
// Step 1: Find the middle point.
int mid = n/2;
Point mid_point = pointsX[mid];
// Step 2: Divide the set in two equal-sized parts (left and right).
vector<Point> pointsY_left;
vector<Point> pointsY_right;
vector<Point> pointsX_left;
vector<Point> pointsX_right;
for (int i = 0; i < n; ++i) {
if (i < mid and pointsY[i].x <= mid_point.x) pointsY_left.push_back(pointsY[i]);
else pointsY_right.push_back(pointsY[i]);
}
for (int i = 0; i < n; ++i) {
if (i < mid and pointsX[i].x <= mid_point.x) pointsX_left.push_back(pointsX[i]);
else pointsX_right.push_back(pointsX[i]);
}
// Step 3: Calculate the smaller distance at left and right parts recursively.
double d_left = min_dist(pointsX_left, pointsY_left, mid);
double d_right = min_dist(pointsX_right , pointsY_right, n - mid);
// Let d be the minimal of the 2 distances.
double d = min (d_left, d_right);
// Eliminate points that are farther than d <=> Create a strip that contains
// points closer than d.
vector<Point> strip;
for (int i = 0; i < n; ++i) if (abs(pointsY[i].x - mid_point.x) < d) strip.push_back(pointsY[i]);
// Scan the points from the strip and compute the dstances of each point to its 7 neighbours.
// Pick all points one by one and try the next points until the difference
// between y coordinates is smaller than d.
for (int i = 0; i < int(strip.size()); ++i)
for (int j = i + 1; j < int(strip.size()) and (strip[j].y - strip[i].y) < d; ++j)
if (dist (strip[i], strip[j]) < d)
d = dist(strip[i], strip[j]);
return d;
}
double closest(const vector<Point>& points) {
// Initial step: sort points accroding to their coordinates.
vector<Point> pointsX, pointsY;
pointsX = pointsY = points;
sort(pointsX.begin(), pointsX.end(), compareX);
sort(pointsY.begin(), pointsY.end(), compareY);
return min_dist (pointsX, pointsY, int(points.size()));
}
int main() {
cout.setf(ios::fixed);
cout.precision(5);
vector<Point> points;
double x, y;
while (cin >> x >> y) {
Point p = {x, y};
points.push_back(p);
}
cout << closest (points) << endl;
}
Looks like problem is in Step 2. You have two different conditions i < mid and pointsY[i].x <= mid_point.x and i < mid and pointsX[i].x <= mid_point.x, but in the following code you suppose these conditions are equal. Probably you should replace these conditions with just i < mid.
// Step 1: Find the middle point.
int mid = n/2;
Point mid_point = pointsX[mid];
// Step 2: Divide the set in two equal-sized parts (left and right).
vector<Point> pointsY_left;
vector<Point> pointsY_right;
vector<Point> pointsX_left;
vector<Point> pointsX_right;
for (int i = 0; i < n; ++i) {
if (i < mid and pointsY[i].x <= mid_point.x) pointsY_left.push_back(pointsY[i]);
else pointsY_right.push_back(pointsY[i]);
}
for (int i = 0; i < n; ++i) {
if (i < mid and pointsX[i].x <= mid_point.x) pointsX_left.push_back(pointsX[i]);
else pointsX_right.push_back(pointsX[i]);
}
P.S. You can simply use constructor of vector:
vector<Point> pointsY_left( pointsY.cbegin(), pointsY.cbegin() + mid );
vector<Point> pointsY_right( pointsY.cbegin() + mid, pointsY.cend() );
vector<Point> pointsX_left( pointsX.cbegin(), pointsX.cbegin() + mid );
vector<Point> pointsX_right( pointsX.cbegin() + mid, pointsX.cend() );
Logic error problem with the Gaussian Elimination code...This code was from my Numerical Methods text in 1990's. The code is typed in from the book- not producing correct output...
Sample Run:
SOLUTION OF SIMULTANEOUS LINEAR EQUATIONS
USING GAUSSIAN ELIMINATION
This program uses Gaussian Elimination to solve the
system Ax = B, where A is the matrix of known
coefficients, B is the vector of known constants
and x is the column matrix of the unknowns.
Number of equations: 3
Enter elements of matrix [A]
A(1,1) = 0
A(1,2) = -6
A(1,3) = 9
A(2,1) = 7
A(2,2) = 0
A(2,3) = -5
A(3,1) = 5
A(3,2) = -8
A(3,3) = 6
Enter elements of [b] vector
B(1) = -3
B(2) = 3
B(3) = -4
SOLUTION OF SIMULTANEOUS LINEAR EQUATIONS
The solution is
x(1) = 0.000000
x(2) = -1.#IND00
x(3) = -1.#IND00
Determinant = -1.#IND00
Press any key to continue . . .
The code as copied from the text...
//Modified Code from C Numerical Methods Text- June 2009
#include <stdio.h>
#include <math.h>
#define MAXSIZE 20
//function prototype
int gauss (double a[][MAXSIZE], double b[], int n, double *det);
int main(void)
{
double a[MAXSIZE][MAXSIZE], b[MAXSIZE], det;
int i, j, n, retval;
printf("\n \t SOLUTION OF SIMULTANEOUS LINEAR EQUATIONS");
printf("\n \t USING GAUSSIAN ELIMINATION \n");
printf("\n This program uses Gaussian Elimination to solve the");
printf("\n system Ax = B, where A is the matrix of known");
printf("\n coefficients, B is the vector of known constants");
printf("\n and x is the column matrix of the unknowns.");
//get number of equations
n = 0;
while(n <= 0 || n > MAXSIZE)
{
printf("\n Number of equations: ");
scanf ("%d", &n);
}
//read matrix A
printf("\n Enter elements of matrix [A]\n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
printf(" A(%d,%d) = ", i + 1, j + 1);
scanf("%lf", &a[i][j]);
}
//read {B} vector
printf("\n Enter elements of [b] vector\n");
for (i = 0; i < n; i++)
{
printf(" B(%d) = ", i + 1);
scanf("%lf", &b[i]);
}
//call Gauss elimination function
retval = gauss(a, b, n, &det);
//print results
if (retval == 0)
{
printf("\n\t SOLUTION OF SIMULTANEOUS LINEAR EQUATIONS\n");
printf("\n\t The solution is");
for (i = 0; i < n; i++)
printf("\n \t x(%d) = %lf", i + 1, b[i]);
printf("\n \t Determinant = %lf \n", det);
}
else
printf("\n \t SINGULAR MATRIX \n");
return 0;
}
/* Solves the system of equations [A]{x} = {B} using */
/* the Gaussian elimination method with partial pivoting. */
/* Parameters: */
/* n - number of equations */
/* a[n][n] - coefficient matrix */
/* b[n] - right-hand side vector */
/* *det - determinant of [A] */
int gauss (double a[][MAXSIZE], double b[], int n, double *det)
{
double tol, temp, mult;
int npivot, i, j, l, k, flag;
//initialization
*det = 1.0;
tol = 1e-30; //initial tolerance value
npivot = 0;
//mult = 0;
//forward elimination
for (k = 0; k < n; k++)
{
//search for max coefficient in pivot row- a[k][k] pivot element
for (i = k + 1; i < n; i++)
{
if (fabs(a[i][k]) > fabs(a[k][k]))
{
//interchange row with maxium element with pivot row
npivot++;
for (l = 0; l < n; l++)
{
temp = a[i][l];
a[i][l] = a[k][l];
a[k][l] = temp;
}
temp = b[i];
b[i] = b[k];
b[k] = temp;
}
}
//test for singularity
if (fabs(a[k][k]) < tol)
{
//matrix is singular- terminate
flag = 1;
return flag;
}
//compute determinant- the product of the pivot elements
*det = *det * a[k][k];
//eliminate the coefficients of X(I)
for (i = k; i < n; i++)
{
mult = a[i][k] / a[k][k];
b[i] = b[i] - b[k] * mult; //compute constants
for (j = k; j < n; j++) //compute coefficients
a[i][j] = a[i][j] - a[k][j] * mult;
}
}
//adjust the sign of the determinant
if(npivot % 2 == 1)
*det = *det * (-1.0);
//backsubstitution
b[n] = b[n] / a[n][n];
for(i = n - 1; i > 1; i--)
{
for(j = n; j > i + 1; j--)
b[i] = b[i] - a[i][j] * b[j];
b[i] = b[i] / a[i - 1][i];
}
flag = 0;
return flag;
}
The solution should be: 1.058824, 1.823529, 0.882353 with det as -102.000000
Any insight is appreciated...
//eliminate the coefficients of X(I)
for (i = k; i < n; i++)
Should this maybe be
for (i = k + 1; i < n; i++)
The way it is now, I believe this will cause you to divide the pivot row by itself, zeroing it out.
This probably doesn't answer your question in the way you intended, but programming your own numerically-stable matrix algorithms is about as well-advised as do-it-yourself surgery.
There's a very nice library called TNT/JAMA from a reputable source (NIST) which does elementary matrix math in C++. To solve Ax=B, first factor A (the QR decomposition is a good general method, you can use LU but it's less numerically stable), then call solve(B). This works both for square matrices, where it's exact (subject to numerical computation issues), and overdetermined systems, where you get a least-squares answer.