I have a problem with deallocating a 3 dimensional vector in c++, I get the error "CTR detected that the application wrote to memory after end of heap buffer".
Can somebody tell me what I am doing wrong? Thank you in advance.
Allocation:
count = new int**[w];
for (int i = 0; i < w; ++i)
{
count[i] = new int*[h];
for (int j = 0; j < h; ++j)
{
count[i][j] = new int[120];
for (int k = 20; k < 120; ++k)
{
count[i][j][k] = 0;
}
}
}
Deallocation:
for (int i = 0; i < w; ++i)
{
for (int j = 0; j < h; ++j)
{
delete [] count[i][j];
}
delete [] count[i];
}
delete [] count;
count = NULL;
This is my entire code:
#include <filesystem>
#include <stdexcept>
#include "pch.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace std;
using namespace cv;
class cerc {
int raza;
int a;
int b;
public:
cerc()
{
a = 0;
b = 0;
raza = 0;
}
inline cerc(int raza, int a, int b)
{
this->a = a;
this->b = b;
this->raza = raza;
}
inline cerc(cerc& c)
{
a = c.a;
b = c.b;
raza = c.raza;
}
void print()
{
std::cout << " (" << (int)this->a << ", " << (int)this->b << ", " << (int)this->raza << ") ";
}
inline bool operator==(const cerc& other) const
{
if (this->a == other.a && this->b == other.b && this->raza == other.raza)
return true;
else return false;
}
inline bool egal(int raza, int a, int b) const
{
if (this->a == a && this->b == b && this->raza == raza)
return true;
else return false;
}
inline void copy(cerc &c2)
{
this->raza = c2.raza;
this->a = c2.a;
this->b = c2.b;
}
inline void copy(int raza, int a, int b)
{
this->a = a;
this->raza = raza;
this->b = b;
}
const int getA()
{
return a;
}
const int getB()
{
return b;
}
const int getRaza()
{
return raza;
}
};
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
void createVector(int*** count, Mat img, int w, int h)
{
int a = 0;
int b = 0;
int r = 0;
int wminus = 5 * (w / 6);
int hminus = 5 * (h / 6);
int wstart = w / 6;
int hstart = h / 6;
int x, y;
for (x = wstart; x < wminus; x++)
for (y = hstart; y < hminus; y++)
{
if (((Scalar)(img.at<uchar>(Point(x, y)))).val[0] == 255)
{
for (a = wstart; a < wminus; a += 1)
for (b = hstart; b < hminus; b += 1)
{
r = (int)sqrt((b - y)*(b - y) + (a - x)*(a - x));
if (r >= 20 && r <= 120)
count[a][b][r]++;
}
}
}
}
void cercFinal(cerc &cercMax, int***count, int w, int h)
{
int wminus = 5 * (w / 6);
int hminus = 5 * (h / 6);
int wstart = w / 6;
int hstart = h / 6;
int maxNr = count[0][0][0];
for (int i = wstart; i < wminus; i += 1)
for (int j = hstart; j < hminus; j += 1)
for (int k = 20; k < 60; k++)
if (maxNr < count[i][j][k])
{
maxNr = count[i][j][k];
cercMax.copy(k, i, j);
}
cout << maxNr;
}
void cercFinalSecund(cerc &SecondCircle, cerc &FirstCircle, int***count, int w, int h)
{
int wminus = 3 * (w / 4);
int hminus = 3 * (h / 4);
int wstart = w / 4;
int hstart = h / 4;
int minIrisRay = (int)(FirstCircle.getRaza() * 1.5);
int maxIrisRay = FirstCircle.getRaza() * 4;
int maxNr = count[0][0][0];
for (int i = wstart; i < wminus; i += 1)
for (int j = hstart; j < hminus; j += 1)
for (int k = 40; k < 120; k++)
{
if (k >= minIrisRay && k <= maxIrisRay)
{
if (maxNr < count[i][j][k] && !(cerc(k, i, j) == FirstCircle) && abs(j - FirstCircle.getB()) < 2 && abs(i - FirstCircle.getA()) < 2)
{
maxNr = count[i][j][k];
SecondCircle.copy(k, i, j);
}
}
}
}
int main()
{
Mat imgCanny;
Mat imgBlur;
int ***count;
for (int i = 10; i < 50; i++)
{
Mat_<uchar> img = imread("C://Users//Maria//Downloads//CASIA-IrisV2//CASIA-IrisV2//device1//00" + std::to_string(i) + "//00" + std::to_string(i) + "_000.bmp", IMREAD_GRAYSCALE);
//img.convertTo(img, -1, 4, 0);
//int t = img.at<uchar>(1, 2).val[0];
int w = img.size().width;
int h = img.size().height;
medianBlur(img, imgBlur, 15);
//GaussianBlur(img, imgBlur, Size(8, 8), 0);
Canny(imgBlur, imgCanny, 30, 40);
//imshow("canny", imgCanny);
int m = min(w, h);
count = new int**[w];
for (int i = 0; i < w; ++i)
{
count[i] = new int*[h];
for (int j = 0; j < h; ++j)
{
count[i][j] = new int[120];
for (int k = 20; k < 120; ++k)
{
count[i][j][k] = 0;
}
}
}
createVector(count, imgCanny, w, h);
cerc final(0, 0, 0);
cerc finalSecund(0, 0, 0);
cercFinal(final, count, w, h);
cercFinalSecund(finalSecund, final, count, w, h);
cout << endl << "cerc=";
final.print();
Point p(final.getA(), final.getB());
Mat imgColor = imread("C://Users//Maria//Downloads//CASIA-IrisV2//CASIA-IrisV2//device1//00" + std::to_string(i) + "//00" + std::to_string(i) + "_000.bmp", IMREAD_COLOR);
circle(imgColor, p, final.getRaza(), Scalar(255, 0, 0), 4, 8, 0);
Point ps(finalSecund.getA(), finalSecund.getB());
cout << endl << "cerc=";
finalSecund.print();
circle(imgColor, ps, finalSecund.getRaza(), Scalar(255, 0, 0), 4, 8, 0);
imshow("iris", imgColor);
for (int i = 0; i < w; ++i)
{
for (int j = 0; j < h; ++j)
{
delete [] count[i][j];
}
delete [] count[i];
}
delete [] count;
count = NULL;
waitKey(0);
}
return 0;
}
If I delete the line count[a][b][r]++; the deallocation works fine. Is anything wrong with this statement?
Related
I'm very new to C++ and only coded in python before, but python is too slow for my purposes now. I did a mergesort algorithm in python and it worked. But now I translated it into C++ and I got a bunch of errors in my IDE. What are my errors?
#include <iostream>
using namespace std;
int *sort(int lenght, int lis[]) {
int units = lenght;
int umt;
int tiles = 1;
while (units > 1) {
bool whole = true;
umt = units % 2;
if (umt = 1) {
units++;
whole = false;
}
units = units / 2;
tiles = tiles * 2;
if (whole) {
int buffd[units];
int add_l = 0;
int add_r = 0;
int prod_l = 0;
int prod_r = prod_l + tiles / 2;
for (int k = 0; k < units; k++) {
int buffd[units];
int add_l = 0;
int add_r = 0;
int prod_l = k * tiles;
int prod_r = prod_l + tiles / 2;
for (int f = 0; f < tiles; f++) {
if (lis[prod_l + add_l] <= lis[prod_r + add_r]) {
buffd[f] = lis[prod_l + add_l];
add_l++;
if (add_l = tiles / 2) {
for (int e = f; e < tiles; e++) {
buffd[e] = lis[prod_r + add_r + e];
}
f = tiles;
}
} else {
buffd[f] = lis[prod_r + add_r];
add_r++;
if (add_r = tiles / 2) {
for (int e = f; e < tiles; e++) {
buffd[e] = lis[prod_l + add_l + e];
}
f = tiles;
}
}
}
for (int i = prod_l; i < prod_l + tiles; i++) {
lis[i] = buffd[i - prod_l];
}
}
} else {
int buffd[units];
int add_l = 0;
int add_r = 0;
int prod_l = 0;
int prod_r = prod_l + tiles / 2;
for (int k = 0; k < units - 1; k++) {
int buffd[units];
int add_l = 0;
int add_r = 0;
int prod_l = k * tiles;
int prod_r = prod_l + tiles / 2;
for (int f = 0; f < tiles; f++) {
if (lis[prod_l + add_l] <= lis[prod_r + add_r]) {
buffd[f] = lis[prod_l + add_l];
add_l++;
if (add_l = tiles / 2) {
for (int e = f; e < tiles; e++) {
buffd[e] = lis[prod_r + add_r + e];
}
f = tiles;
}
} else {
buffd[f] = lis[prod_r + add_r];
add_r++;
if (add_r = tiles / 2) {
for (int e = f; e < tiles; e++) {
buffd[e] = lis[prod_l + add_l + e];
}
f = tiles;
}
}
}
}
for (int i = prod_l; i < prod_l + tiles; i++) {
lis[i] = buffd[i - prod_l];
}
}
}
return lis;
}
int main() {
int to_sort[8] = { 23, 1, 654, 2, 4, 87, 3, 1 };
cout << "sortiert: ";
int *sorted;
sorted = sort(8, to_sort);
for (int p = 0; p < 8; p++) {
cout << sorted[p] << " ";
}
return 0;
}
The errors are in German and I have no idea why, the rest of the IDE is in English. Does anyone know how to set that to English, I'm using Clion from JetBrains.
There are some major problems in your code:
comparisons must use == instead of =, which is the assignment operator.
the redundant definitions for buffd, add_l, add_r, prod_l and prod_r should me removed.
variable length array definitions such as int buffd[units] are not supported by many C++ compilers. These are extensions for compatibility with C90 optional features, likely to cause stack overflow for large arrays. You should allocate these arrays or use std::vector.
these local arrays are declared with a incorrect size: it should be int buffd[tiles];, not int buffd[units]. Undefined behavior ensues.
the last for loop is outside the body of the previous loop, which is incorrect.
you do not increment f before copying the remaining elements from the other slice when either add_l or add_r equals tiles / 2.
your non-recursive algorithm cannot succeed in the general case, I got it to work for array lengths that are powers of 2, and it is quite surprising that it may come as a translation from your python version. There are much simpler ways to program mergesort in python, and in C++ too.
With some extra work, I simplified your code and got it to work for the general case:
#include <iostream>
using namespace std;
int *sort(int length, int lis[]) {
for (int tile = 1; tile < length; tile += tile) {
int tiles = tile + tile;
int *buffd = new int[tiles];
for (int prod_l = 0; prod_l < length; prod_l += tiles) {
int add_l = 0;
int max_l = tile;
int add_r = 0;
int max_r = tile;
int prod_r = prod_l + max_l;
int f = 0;
if (prod_r >= length)
break;
if (prod_r + max_r > length)
max_r = length - prod_r;
for (;;) {
if (lis[prod_l + add_l] <= lis[prod_r + add_r]) {
buffd[f++] = lis[prod_l + add_l++];
if (add_l == max_l) {
while (add_r < max_r) {
buffd[f++] = lis[prod_r + add_r++];
}
break;
}
} else {
buffd[f++] = lis[prod_r + add_r++];
if (add_r == max_r) {
while (add_l < max_l) {
buffd[f++] = lis[prod_l + add_l++];
}
break;
}
}
}
for (int i = 0; i < f; i++) {
lis[prod_l + i] = buffd[i];
}
}
delete[] buffd;
}
return lis;
}
int main() {
int to_sort[8] = { 23, 1, 654, 2, 4, 87, 3, 1 };
for (int i = 1; i < 8; i++) {
cout << "sortiert: ";
int *sorted = sort(i, to_sort);
for (int p = 0; p < i; p++) {
cout << sorted[p] << " ";
}
cout << endl;
}
return 0;
}
Here is a classic top-down recursive implementation for reference:
void mergesort(int lis[], int lo, int hi, int *tmp) {
if (hi - lo >= 2) {
int mid = (hi - lo) / 2;
mergesort(lis, lo, lo + mid, tmp);
mergesort(lis, lo + mid, hi, tmp);
for (int i = 0; i < mid; i++)
tmp[i] = lis[lo + i];
for (int i = 0, j = lo + mid, k = lo; i < mid;) {
if (j >= hi || tmp[i] <= lis[j])
lis[k++] = tmp[i++];
else
lis[k++] = lis[j++];
}
}
}
int *mergesort(int length, int lis[]) {
int *tmp = new int[length / 2];
mergesort(lis, 0, length, tmp);
delete[] tmp;
return lis;
}
so I was doing this code in which you scan a number then that number pairs of numerical strings example
5
5 5
6 6
7 7
8 8
and the program should then output
25
36
49
64
81
which is the first number *the second number
but mine outputs
25
61 //25+36
110 //110+49
174 //110+64
the reason is that in my code I keep each multiplication in an array called arr2 which I declared globally and since I don't reset all values back to 0 it keeps adding up but the problem is don't know how to reset all of its values back to 0 since when I tried it would not let me
code in which I did not try to reset the array which works the way I already mentioned
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<long long> vi;
typedef pair<long long, long long> pi;
typedef vector<pi> vpi;
#define FOR(i, a, b) for (ll i = ll(a); i < ll(b); i++)
#define ROF(i, a, b) for (ll i = ll(a); i >= ll(b); i--)
#define f first
#define s second
#define pb emplace_back
#define mp make_pair
#define SQ(a) (a) * (a)
#define all(a) (a).begin(), (a).end()
int arr[9999];
int multiply(string a, string b, int n)
{
int r = 0, j = 0;
int x = int(b[0] - 48);
for (int i = n - 1; i >= 0; i--) {
int mult = 0, y = int(a[i] - 48);
mult = x * y + r;
arr[j] = mult % 10;
r = (mult - mult % 10) / 10;
j++;
}
if (r != 0) {
arr[j] = r;
return n + 1;
}
else {
return n;
}
}
int arr2[9999] = { 0 }, u = 0; //here I declared it
int suma(int w, int f)
{
int b[w];
int r = 0;
int s = 0, j = 0;
w = w + f;
for (int i = f; i < w; i++) {
s = arr2[i] + arr[i - f] + r;
arr2[i] = s % 10;
r = (s - s % 10) / 10;
j++;
}
if (r != 0) {
if (w >= u) {
arr2[j] = r;
j++;
}
else {
while (r != 0) {
s = arr2[j] + arr[j - f] + r;
arr2[j] = s % 10;
r = (s - s % 10) / 10;
j++;
}
}
}
int u = max({ w, u, j });
return u;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int as;
cin >> as;
for (int cfg = 0; cfg < as; cfg++) {
int w, k = 0, l = 0;
string a, b, c;
cin >> a >> b;
reverse(b.begin(), b.end());
for (int i = 0; i < b.length(); i++) {
c = b[i];
w = multiply(a, c, a.length());
k = suma(w, i);
l = max(k, l);
}
int narr[l];
narr[l] = { 0 };
copy(arr2 + 0, arr2 + l, narr);
int n = sizeof(narr) / sizeof(narr[0]);
reverse(narr, narr + n);
int qw = 0;
for (int i = 0; i < l; i++) {
if (narr[i] != 0) {
qw = 1;
}
if (qw == 1) {
cout << narr[i];
}
}
cout << endl;
}
return 0;
}
Code in which I tried but gives me an error:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<long long> vi;
typedef pair<long long, long long> pi;
typedef vector<pi> vpi;
#define FOR(i, a, b) for (ll i = ll(a); i < ll(b); i++)
#define ROF(i, a, b) for (ll i = ll(a); i >= ll(b); i--)
#define f first
#define s second
#define pb emplace_back
#define mp make_pair
#define SQ(a) (a) * (a)
#define all(a) (a).begin(), (a).end()
int arr[9999];
int multiply(string a, string b, int n)
{
int r = 0, j = 0;
int x = int(b[0] - 48);
for (int i = n - 1; i >= 0; i--) {
int mult = 0, y = int(a[i] - 48);
mult = x * y + r;
arr[j] = mult % 10;
r = (mult - mult % 10) / 10;
j++;
}
if (r != 0) {
arr[j] = r;
return n + 1;
}
else {
return n;
}
}
int arr2[9999] = { 0 }, u = 0; //here I declared it
int suma(int w, int f)
{
int b[w];
int r = 0;
int s = 0, j = 0;
w = w + f;
for (int i = f; i < w; i++) {
s = arr2[i] + arr[i - f] + r;
arr2[i] = s % 10;
r = (s - s % 10) / 10;
j++;
}
if (r != 0) {
if (w >= u) {
arr2[j] = r;
j++;
}
else {
while (r != 0) {
s = arr2[j] + arr[j - f] + r;
arr2[j] = s % 10;
r = (s - s % 10) / 10;
j++;
}
}
}
int u = max({ w, u, j });
return u;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int as;
cin >> as;
for (int cfg = 0; cfg < as; cfg++) {
arr2[9999] = { 0 }; //here I try to set all the values back to 0
int w, k = 0, l = 0;
string a, b, c;
cin >> a >> b;
reverse(b.begin(), b.end());
for (int i = 0; i < b.length(); i++) {
c = b[i];
w = multiply(a, c, a.length());
k = suma(w, i);
l = max(k, l);
}
int narr[l];
narr[l] = { 0 };
copy(arr2 + 0, arr2 + l, narr);
int n = sizeof(narr) / sizeof(narr[0]);
reverse(narr, narr + n);
int qw = 0;
for (int i = 0; i < l; i++) {
if (narr[i] != 0) {
qw = 1;
}
if (qw == 1) {
cout << narr[i];
}
}
cout << endl;
}
return 0;
}
Format!Style:
C++ online code formatter © 2014 by KrzaQ
Powered by vibe.d, the D language and clang-format
So the question would be if is there any way to reset all the values to 0 or any other way to solve the problem if you can you could submit a code that works if not just tell me how to fix it,thank you
To clear the arr array, you can use memset like:
memset(arr, 0, sizeof arr);
I'm trying to assign data from one object to another and get me this error and choose an exception:
Unhandled exception at location 0x00007FFDCD79A839 in C ++ Project. Exe: Microsoft C ++ exception: std :: length_error in memory location 0x000000DDD04FA560.
Field.cpp
RectangleShape Field::getField() {
return field;
}
Board.h
#pragma once
#include "DEFINIONS.h"
#include "Field.h"
class Board
{
private:
int length{ 3 };
int width{ 3 };
int lengthBoard{ 0 };
int widthBoard{ 0 };
int a{ 0 };
int b{ 0 };
bool check{ true };
RectangleShape ramka;
Field** board;
public:
Board(int length = 3, int width = 3, int margin_X = 0, int margin_Y = 0);
void drawMap(RenderWindow& window);
};
Board.cpp
Board::Board(int length, int width, int margin_X, int margin_Y) {
this->length = length;
this->width = width;
ramka.setSize(Vector2f(800, 800));
ramka.setFillColor(Color::Green);
ramka.setOrigin(700, 700);
ramka.setPosition(730, 730);
board = new Field * [length];
for (int i = 0; i < length; i++) {
board[i] = new Field[width];
}
for (int i = 0; i < length; i++) {
*this->board[i] = Field();
for (int j = 0; j < width; j++) {
*this->board[j] = Field();
lengthBoard = length * board[0][0].getSize() + (length - 1) * board[0][0].getOdleglosc();
}
}
while (check) {
for (int i = 0; i < length; i++) {
for (int j = 0; j < width; j++) {
if (lengthBoard > ramka.getSize().x&& lengthBoard > ramka.getSize().y) {
a = 0.95 * board[i][j].getSize();
b = board[i][j].getOdleglosc();
board[i][j].setSize(a);
board[i][j].setOdleglosc(b);
lengthBoard = length * board[0][j].getSize() + (length - 1) * board[0][j].getOdleglosc();
}
else
{
for (int i = 0; i < length; i++) {
for (int j = 0; j < width; j++) {
if (lengthBoard < ramka.getSize().x && lengthBoard < ramka.getSize().y) {
a = 1.05 * board[i][j].getSize();
b = board[i][j].getOdleglosc();
board[i][j].setSize(a);
board[i][j].setOdleglosc(b);
lengthBoard = length * board[0][j].getSize() + (length - 1) * board[0][j].getOdleglosc();
}
else {
check = false;
break;
}
}
}
if (!check)
break;
}
}
if (!check)
break;
}
}
for (int i = 0; i < length; i++)
for (int j = 0; j < width; j++)
board[i][j] = Field(i, j, margin_X, margin_Y, a, b);
}
void Board::drawMap(RenderWindow& window) {
// window.draw(ramka);
scaleBoard(window);
for (int i = 0; i < length; i++)
for (int j = 0; j < width; j++) {
window.draw(board[i][j].getField());
std::cout << board[i][j].getSize() << "---" << board[i][j].getOdleglosc() << std::endl;
std::cout << a << "----------------" << b << std::endl;
}
}
GameState.h
Board tablica;
void doIt(RenderWindow& window,int numer); //metoda pozwalajaca zainicjowac całą tablice
int game(RenderWindow& window, Event& event, Vector2f mouse, int numer);
};
GameState.cpp
void GameState::gameload(RenderWindow& window, Event &event, int numer) {
Board board(numer, numer);
tablica.setA(board.getA());
tablica.setB(board.getB());
//tablica.setBoard(board.getBoard());
tablica.setCheck(board.getCheck());
tablica.setLength(board.getLength());
tablica.setLengthBoard(board.getLengthBoard());
tablica.setRamka(board.getRamka());
tablica.setWidth(board.getWidth());
tablica.setWidthBoard(board.getWidthBoard());
loadBackground();
window.draw(background);
board.drawMap(window);
drawPause(window);
setTextureKrzyzyk();
setTextureKolko();
setTextureKolkoWin();
setTextureKrzyzykWin();
}
void GameState::doIt(RenderWindow& window,int numer)
{
loadBackground();
window.draw(background);
tablica.drawMap(window);
drawPause(window);
setTextureKrzyzyk();
setTextureKolko();
setTextureKolkoWin();
setTextureKrzyzykWin();
}
int GameState::game(RenderWindow& window, Event& event, Vector2f mouse, int numer) {
if (checker)
{
gameload(window, event, numer);
checker = false;
}
doIt(window,numer);
return pauseButton(mouse, event, STATE_GAME);
}
I have written code for matrix chain multiplication in dynamic programming in c++.
there is an error in the recursive call for printing the correct parenthesization of the matrices. I am taking input from text file and giving output on a text file. please help..
#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
int * MatrixChainOrder(int p[], int n)
{
static int m[100][100];
static int s[100][100];
int j, q;
int min = INT_MAX;
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
j = i + L - 1;
m[i][j] = min;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return (*s);
}
void Print(int *s, int i, int j)
{
ofstream outfile("output.text");
if (i == j)
{
outfile << "a1";
}
else
outfile << "(";
{
Print(*s, i, s[i][j]);
Print(*s, s[i][j] + 1, j);
outfile << ")";
}
outfile.close();
}
int main()
{
int arr[100];
int num, i = 0;
ifstream infile("input.text");
while (infile)
{
infile >> num;
arr[i] = num;
i++;
}
i = i - 1;
infile.close();
Print(MatrixChainOrder(arr, i - 1), 0, i - 1);
return 0;
}
In C++ it is better to use std::vector for arrays. Aside from that, you can't mix pointers and arrays like that because the compiler loses track of array size.
For example this doesn't work:
int x[10][20];
void foo(int *ptr)
{
//the numbers 10 and 20 have not been passed through
}
But you can change it to
int x[10][20];
void foo(int arr[10][20])
{
//the numbers 10 and 20 are available
}
MatrixChainOrder is supposed to return a number, according to this link
int MatrixChainOrder(int s[100][100], int p[], int n)
{
int m[100][100];
for (int i = 0; i < 100; i++) m[i][i] = 0;
for (int i = 0; i < 100; i++) s[i][i] = 0;
int q = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return q;
}
int main()
{
int arr[] = { 40, 20, 30, 10, 30 };
int array_size = sizeof(arr) / sizeof(int);
int n = array_size - 1;
int s[100][100];
int minimum = MatrixChainOrder(s, arr, n);
printf("{ 40, 20, 30, 10, 30 } should result in 26000 : %d\n", minimum);
return 0;
}
Likewise you can change your Print function
void Print(int s[100][100], int i, int j)
{
if (i < 0 || i >= 100 || j < 0 || j >= 100)
{
cout << "array bound error\n";
}
//safely access s[i][j] ...
}
I have a computation with a matrix(88147*2000) and it runs very slow.
So I want to use openMP to speed it up. This is my first time to use
openMP so I just use it in "loop-for".
This is my code:
#include<iostream>
#include<fstream>
#include<math.h>
#include<omp.h>
using namespace std;
#define LONGTH 88147
int label[LONGTH] ;
float data[LONGTH][2000] ;
float w[2000];
float e[2000];
void Input()
{
ifstream fin;
float a;
fin.open("/home/data.train");
if (!fin)
{
cout << "file error";
return;
}
for (int i = 0; i < LONGTH; i++)
{
fin >> a;
label[i] = int(a);
for (int j = 0; j < 2000; j++)
{
fin>>data[i][j];
}
}
fin.close();
cout<<"input over"<<endl;
return;
}
void Initial()
{
for (int i = 0; i < 2000; i++)
{
w[i] = 1;
e[i] = 1;
}
return;
}
bool End()
{
for (int i = 0; i < 2000; i++)
{
if (fabs(e[i])>pow(0.1, 6))
return 0;
}
return 1;
}
float Tkj(int i, int j, int k,float w[2000])
{
return w[i] * data[k][i] - w[j] * data[k][j];
}
float En(int n)//*computation*
{
float result = 0;
#pragma omp parallel for num_threads(64) reduction(+:result)
for (int k = 0; k < LONGTH; k++)
{
int tnum = omp_get_thread_num();
float tmp = 0;
int i = label[k] - 1;
for (int j = 0; j < 2000; j++)
{
if (j != i)
{
float l = 0;
if (n == i)
{
l = data[k][i];
float e = exp(Tkj(i, j, k,w));
tmp = tmp + (-e*l) / pow(1 + e, 2);
}
else if (n == j)
{
l = -data[k][j];
float e = exp(Tkj(i, j, k,w));
tmp = tmp + (-e*l) / pow(1 + e, 2);
}
else
{
continue;
}
}
}
result = result + tmp;
}
return result;
}
float Ex(float w[2000])
{
float result = 0;
#pragma omp parallel for num_threads(64) reduction(+:result)
for (int k = 0; k < LONGTH; k++)
{
int i = label[k] - 1;
float tmp = 0;
int tnum = omp_get_thread_num();
for (int j = 0; j < 2000; j++)
{
if (j != i)
{
tmp = tmp + 1 / (1 + exp(Tkj(i,j,k,w)));
}
}
result = result+tmp;
}
return result;
}
int main()
{
Input();
Initial();
float w2[2000] = { 0 };
float b = pow(0.1,5);
int times = 0;
while (!End()&×<=30000)
{
times++;
cout<<times<<endl;
for (int i = 0; i < 2000; i++)
{
e[i] = En(i);
w2[i] = w[i] - b*e[i];
}
if (Ex(w2)<=Ex(w))//better
{
b = b * 2;
for (int i = 0; i < 2000; i++)
w[i] = w2[i];
}
else//worser
{
b = b / 2;
}
}
ofstream fout("/home/w.txt");
for(int i=0;i<2000;i++)
{
fout<<w[i]<<' ';
}
fout.close();
return 0;
}
The function 'En' costs most of time,so I use "#pragma omp parallel for num_threads(64) reduction(+:result)"to speed it up.
I run it in a CentOS server which has 32 cores and use "-fopenmp" to compile it.But it doesn't be a little quicker.
How can I speed this program up more?