How to generate random integer that are random "enough"? - performance

I'm trying to solve the 280th problem in Project Euler, and for this I have written the following simulation;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
/* Directions
1
2 3
4
*/
int grid[5][5] = {
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2}
};
int InitPos[2] = {2, 2};
int MaxExp = 5000000;
bool Success = false;
int StepCount = 0;
int ExpNumber = 1;
int AntsBag = 0;
void Init();
void CarryFood(int * pos);
void LeftFood(int * pos);
bool checkMovability(int * pos, int direction);
bool moveToDirection(int pos[2], int direction);
bool checkSuccess();
void ShowResult();
int main(int argc, char const *argv[])
{
timeval curTime;
gettimeofday(&curTime, NULL);
int milli = curTime.tv_usec / 1000;
time_t t;
srand((unsigned)time(&t));
//timeTData*.txt corresponds to using "time(&t)" above
//milliData.txt corresponds to using "milli" variable above
//timeTUnsigData*.txt corresponds to using "(unsigned)time(&t)" above
printf("%% Experiment Number : %d \n", MaxExp);
while(ExpNumber <= MaxExp)
{
Init();
int pos[2];
pos[0] = InitPos[0];
pos[1] = InitPos[1];
do{
int direction = (rand() % 4) + 1;
if (moveToDirection(pos, direction))
{
StepCount++;
}
if (pos[1] == 4&&grid[pos[0]][4]==2&&AntsBag==0)
{
CarryFood(pos);
}
if (pos[1] == 0&&grid[pos[0]][0]==0&&AntsBag==2)
{
LeftFood(pos);
}
checkSuccess();
}
while(!Success);
ShowResult();
ExpNumber++;
}
return 0;
}
void Init()
{
Success = false;
StepCount = 0;
AntsBag = 0;
int gridInit[5][5] = {
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2},
{0, 0, 0, 0, 2}
};
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
grid[i][j] = gridInit[i][j];
}
}
}
void ShowResult()
{
/*
for (int i = 0; i < 5; ++i)
{
printf("\n");
for (int j = 0; j < 5; ++j)
{
printf("%d ", grid[i][j]);
}
}
*/
printf("%d %d\n", StepCount, ExpNumber);
}
void CarryFood(int * pos)
{
AntsBag = 2;
grid[pos[0]][4] = 0;
}
void LeftFood(int * pos)
{
AntsBag = 0;
grid[pos[0]][0] = 2;
}
bool checkMovability(int * pos, int direction)
{
switch(direction)
{
case 1:
{
if(pos[1]==0){
return false;
}
break;
}
case 2:
{
if (pos[0]==0)
{
return false;
}
break;
}
case 3:
{
if (pos[0]==4)
{
return false;
}
break;
}
case 4:
{
if (pos[1]==4)
{
return false;
}
break;
}
default:
{
printf("Wrong direction input is given!!\n");
return false;
break;
}
}
return true;
}
bool moveToDirection(int * pos, int direction)
{
if ( !checkMovability(pos, direction) )
{
return false;
}
switch(direction){
case 1:
{
pos[1] -= 1;
break;
}
case 2:
{
pos[0] -= 1;
break;
}
case 3:
{
pos[0] += 1;
break;
}
case 4:
{
pos[1] += 1;
break;
}
default:
{
printf("I'm stunned!\n");
return false;
break;
}
}
return true;
}
bool checkSuccess()
{
for (int i = 0; i < 5; ++i)
{
if (grid[i][0] != 2)
{
return false;
}
}
//printf("Success!\n");
Success = true;
return true;
}
And the redirected the output to a *.txt file and find the expected value of the number of steps with the following octave code;
clear
load data.txt
n = data(:,1);
output_precision(15);
mean(n)
%% The actual data
%% milliData1 -> 430.038224000000
%% milliData2 -> 430.031745000000
%% timeTData1 -> 430.029882400000
%% timeTData2 -> 430.019626400000
%% timeUnsigData1 -> 430.028159000000
%% timeUnsigData2 -> 430.009509000000
However, even I run the exact same code twice I get different results, as you can see from the above results.(Note that, I have tried this with different srand(..) inputs for the reason I'm going to explain).
I thought that the reason for this is because how I generate a random integer between 1-4 for the random directions of the ant, because as far as I have been though, the probability distribution of this experiment should be the same as long as I repeat the experiment large number of time (in this particular case 5000000 times).
So my first question is that is it really the problem with the method of how I generate random integers ? If so, how can we overcome this problem, I mean how can we generate integer random enough so that when we repeat the same experiment large number of times, the expected value between those is smaller than these result that I have got ?

You can use something like
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<int> dist{1, 4};
int randNumber = dist(gen);
This generates a more uniform distribution of values.

Related

How to efficiently compute weird numbers

I am trying to print n weird numbers where n is really big number (eg: 10000).
I found this site to check the algorithm for n 600 if I have some errors:
http://www.numbersaplenty.com/set/weird_number/more.php
However, my algorithm is really slow in bigger numbers:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
int n = 2;
for ( int count = 1 ; count <= 15000 ; n += 2 ) {
if (n % 6 == 0) {
continue;
}
List<Integer> properDivisors = getProperDivisors(n);
int divisorSum = properDivisors.stream().mapToInt(i -> i.intValue()).sum();
if ( isDeficient(divisorSum, n) ) {
continue;
}
if ( isWeird(n, properDivisors, divisorSum) ) {
System.out.printf("w(%d) = %d%n", count, n);
count++;
}
}
}
private static boolean isWeird(int n, List<Integer> divisors, int divisorSum) {
return isAbundant(divisorSum, n) && ! isSemiPerfect(divisors, n);
}
private static boolean isDeficient(int divisorSum, int n) {
return divisorSum < n;
}
private static boolean isAbundant(int divisorSum, int n) {
return divisorSum > n;
}
private static boolean isSemiPerfect(List<Integer> divisors, int sum) {
int size = divisors.size();
// The value of subset[i][j] will be true if there is a subset of divisors[0..j-1] with sum equal to i
boolean subset[][] = new boolean[sum+1][size+1];
// If sum is 0, then answer is true
for (int i = 0; i <= size; i++) {
subset[0][i] = true;
}
// If sum is not 0 and set is empty, then answer is false
for (int i = 1; i <= sum; i++) {
subset[i][0] = false;
}
// Fill the subset table in bottom up manner
for ( int i = 1 ; i <= sum ; i++ ) {
for ( int j = 1 ; j <= size ; j++ ) {
subset[i][j] = subset[i][j-1];
int test = divisors.get(j-1);
if ( i >= test ) {
subset[i][j] = subset[i][j] || subset[i - test][j-1];
}
}
}
return subset[sum][size];
}
private static final List<Integer> getProperDivisors(int number) {
List<Integer> divisors = new ArrayList<Integer>();
long sqrt = (long) Math.sqrt(number);
for ( int i = 1 ; i <= sqrt ; i++ ) {
if ( number % i == 0 ) {
divisors.add(i);
int div = number / i;
if ( div != i && div != number ) {
divisors.add(div);
}
}
}
return divisors;
}
}
I have three easy breakouts:
If a number is divisable by 6 it is semiperfect which means it cannot be weird
If a number is deficient this means it cannot be weird
The above points are based on https://mathworld.wolfram.com/DeficientNumber.html
If a a number is odd it cannot be weird at least for 10^21 numbers (which is good for the numbers I am trying to obtain).
The other optimization that I used is the optimization for finding all the dividers of a number. Instead of looping to n, we loop to SQRT(n).
However, I still need to optimize:
1. isSemiPerfect because it is really slow
2. If I can optimize further getProperDivisors it will be good too.
Any suggestions are welcome, since I cannot find any more optimizations to find 10000 weird numbers in reasonable time.
PS: Any code in Java, C#, PHP and JavaScript are OK for me.
EDIT: I found this topic and modified isSemiPerfect to look like this. However, it looks like it does not optimize but slow down the calculations:
private static boolean isSemiPerfect(List<Integer> divisors, int n) {
BigInteger combinations = BigInteger.valueOf(2).pow(divisors.size());
for (BigInteger i = BigInteger.ZERO; i.compareTo(combinations) < 0; i = i.add(BigInteger.ONE)) {
int sum = 0;
for (int j = 0; j < i.bitLength(); j++) {
sum += i.testBit(j) ? divisors.get(j) : 0;
}
if (sum == n) {
return true;
}
}
return false;
}
The issue is indeed in function isSemiPerfect. I transposed your code in C++, it was still quite slow.
Then I modified this function by using backtracking. I now obtain the first 15000 weird values in about 15s. My interpretation is that in about all the cases, the value is semiperfect, and the backtracking function converges rapidly.
Note also that in my backtracking implementation, I sort the divisors, which allow to reduce the number of cases to be examined.
Edit 1: an error was corrected in getProperDivisors. Final results did not seem to be modified !
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>
// return true if sum is obtained
bool test_sum (std::vector<int>& arr, int amount) {
int n = arr.size();
std::sort(arr.begin(), arr.end(), std::greater<int>());
std::vector<int> bound (n);
std::vector<int> select (n);
bound[n-1] = arr[n-1];
for (int i = n-2; i >= 0; --i) {
bound[i] = bound[i+1] + arr[i];
}
int sum = 0; // current sum
int i = 0; // index of the coin being examined
bool up_down = true;
while (true) {
if (up_down) {
if (i == n || sum + bound[i] < amount) {
up_down = false;
i--;
continue;
}
sum += arr[i];
select[i] = 1;
if (sum == amount) return true;
if (sum < amount) {
i++;
continue;
}
up_down = false;
if (select[i] == 0) i--;
} else { // DOWN
if (i < 0) break;
if (select[i] == 0) {
i--;
} else {
sum -= arr[i];
select[i] = 0;
i++;
up_down = true;
}
}
}
return false;
}
bool isDeficient(int divisorSum, int n) {
return divisorSum < n;
}
bool isAbundant(int divisorSum, int n) {
return divisorSum > n;
}
bool isSemiPerfect(std::vector<int> &divisors, int sum) {
int size = divisors.size();
// The value of subset[i][j] will be true if there is a subset of divisors[0..j-1] with sum equal to i
//bool subset[sum+1][size+1];
std::vector<std::vector<bool>> subset(sum+1, std::vector<bool> (size+1));
// If sum is 0, then answer is true
for (int i = 0; i <= size; i++) {
subset[0][i] = true;
}
// If sum is not 0 and set is empty, then answer is false
for (int i = 1; i <= sum; i++) {
subset[i][0] = false;
}
// Fill the subset table in bottom up manner
for ( int i = 1 ; i <= sum ; i++ ) {
for ( int j = 1 ; j <= size ; j++ ) {
subset[i][j] = subset[i][j-1];
int test = divisors[j-1];
if ( i >= test ) {
subset[i][j] = subset[i][j] || subset[i - test][j-1];
}
}
}
return subset[sum][size];
}
bool isWeird(int n, std::vector<int> &divisors, int divisorSum) {
//return isAbundant(divisorSum, n) && !isSemiPerfect(divisors, n);
return isAbundant(divisorSum, n) && !test_sum(divisors, n);
}
std::vector<int> getProperDivisors_old(int number) {
std::vector<int> divisors;
long sqrtn = sqrt(number);
for ( int i = 1 ; i <= sqrtn ; i++ ) {
if ( number % i == 0 ) {
divisors.push_back(i);
int div = number / i;
if (div != i && div != number) {
divisors.push_back(div);
}
}
}
return divisors;
}
std::vector<int> getProperDivisors(int number) {
std::vector<int> divisors;
long sqrtn = sqrt(number);
divisors.push_back(1);
for ( int i = 2 ; i <= sqrtn ; i++ ) {
if (number % i == 0) {
divisors.push_back(i);
int div = number/i;
if (div != i) divisors.push_back(div);
}
}
return divisors;
}
int main() {
int n = 2, count;
std::vector<int> weird;
int Nweird = 15000;
for (count = 0; count < Nweird; n += 2) {
if (n % 6 == 0) continue;
auto properDivisors = getProperDivisors(n);
int divisorSum = std::accumulate (properDivisors.begin(), properDivisors.end(), 0);
if (isDeficient(divisorSum, n) ) {
continue;
}
if (isWeird(n, properDivisors, divisorSum)) {
//std::cout << count << " " << n << "\n";
weird.push_back (n);
count++;
}
}
for (int i = Nweird - 10; i < Nweird; ++i) {
std::cout << weird.at(i) << " ";
}
std::cout << "\n";
}
EDIT 2 The generation of Divisors were completely redefined. It uses now prime decomposition. Much more complex, but global time divided by 7.5. Generation of weird numbers take now 2s on my PC.
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>
template <typename T>
struct factor {T val = 0; T mult = 0;};
template <typename T>
class decompo {
private:
std::vector<T> memory = {2, 3, 5, 7, 11, 13, 17, 19, 23, 31, 37, 39, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
T index = 0;
public:
decompo () {};
void reset () {index = 0;};
T pop () {index = memory.size() - 1; return memory[index];};
T get_next ();
std::vector<T> find_all_primes (T n);
std::vector<factor<T>> decomp (T n);
std::vector<T> GetDivisors (T n);
void complete (T n);
};
template <typename T>
T decompo<T>::get_next () {
++index;
if (index <= memory.size()) {
return memory[index-1];
}
T n = memory.size();
T candidate = memory[n-1] + 2;
while (1) {
bool found = true;
for (T i = 1; memory[i] * memory[i] <= candidate; ++i) {
if (candidate % memory[i] == 0) {
found = false;
break;
}
}
if (found) {
memory.push_back (candidate);
return candidate;
}
candidate += 2;
}
}
template <typename T>
std::vector<T> decompo<T>::find_all_primes (T n) {
reset();
std::vector<T> result;
while (1) {
T candidate = get_next();
if (candidate <= n) {
result.push_back (candidate);
} else {
return result;
}
}
}
template <typename T>
void decompo<T>::complete (T n) {
T last = pop();
while (last < n) {
last = get_next();
}
return;
}
template <typename T>
std::vector<factor<T>> decompo<T>::decomp (T n) {
reset();
std::vector<factor<T>> result;
if (n < 2) return result;
T candidate = get_next();
T last_prime = 0;
while (candidate*candidate <= n) {
if (n % candidate == 0) {
if (candidate == last_prime) {
result[result.size()-1].mult ++;
} else {
result.push_back ({candidate, 1});
last_prime = candidate;
}
n /= candidate;
} else {
candidate = get_next();
}
}
if (n > 1) {
if (n != last_prime) result.push_back ({n, 1});
else result[result.size()-1].mult ++;
}
return result;
}
template <typename T>
std::vector<T> decompo<T>::GetDivisors (T n) {
std::vector<T> div;
auto primes = decomp (n);
int n_primes = primes.size();
std::vector<int> exponent (n_primes, 0);
div.push_back(1);
int current_index = 0;
int product = 1;
std::vector<int> product_partial(n_primes, 1);;
while (true) {
current_index = 0;
while (current_index < n_primes && exponent[current_index] == primes[current_index].mult) current_index++;
if (current_index == n_primes) break;
for (int index = 0; index < current_index; ++index) {
exponent[index] = 0;
product /= product_partial[index];
product_partial[index] = 1;
}
exponent[current_index]++;
product *= primes[current_index].val;
product_partial[current_index] *= primes[current_index].val;
if (product != n && product != 1) div.push_back (product);
}
return div;
}
// return true if sum is obtained
bool test_sum (std::vector<int>& arr, int amount) {
int n = arr.size();
std::sort(arr.begin(), arr.end(), std::greater<int>());
std::vector<int> bound (n);
std::vector<int> select (n);
bound[n-1] = arr[n-1];
for (int i = n-2; i >= 0; --i) {
bound[i] = bound[i+1] + arr[i];
}
int sum = 0; // current sum
int i = 0; // index of the coin being examined
bool up_down = true;
while (true) {
if (up_down) {
if (i == n || sum + bound[i] < amount) {
up_down = false;
i--;
continue;
}
sum += arr[i];
select[i] = 1;
if (sum == amount) return true;
if (sum < amount) {
i++;
continue;
}
up_down = false;
if (select[i] == 0) i--;
} else { // DOWN
if (i < 0) break;
if (select[i] == 0) {
i--;
} else {
sum -= arr[i];
select[i] = 0;
i++;
up_down = true;
}
}
}
return false;
}
bool isDeficient(int divisorSum, int n) {
return divisorSum < n;
}
bool isAbundant(int divisorSum, int n) {
return divisorSum > n;
}
bool isSemiPerfect(std::vector<int> &divisors, int sum) {
int size = divisors.size();
// The value of subset[i][j] will be true if there is a subset of divisors[0..j-1] with sum equal to i
//bool subset[sum+1][size+1];
std::vector<std::vector<bool>> subset(sum+1, std::vector<bool> (size+1));
// If sum is 0, then answer is true
for (int i = 0; i <= size; i++) {
subset[0][i] = true;
}
// If sum is not 0 and set is empty, then answer is false
for (int i = 1; i <= sum; i++) {
subset[i][0] = false;
}
// Fill the subset table in bottom up manner
for ( int i = 1 ; i <= sum ; i++ ) {
for ( int j = 1 ; j <= size ; j++ ) {
subset[i][j] = subset[i][j-1];
int test = divisors[j-1];
if ( i >= test ) {
subset[i][j] = subset[i][j] || subset[i - test][j-1];
}
}
}
return subset[sum][size];
}
bool isWeird(int n, std::vector<int> &divisors, int divisorSum) {
//return isAbundant(divisorSum, n) && !isSemiPerfect(divisors, n);
return isAbundant(divisorSum, n) && !test_sum(divisors, n);
}
std::vector<int> getProperDivisors(int number) {
std::vector<int> divisors;
long sqrtn = sqrt(number);
divisors.push_back(1);
for ( int i = 2 ; i <= sqrtn ; i++ ) {
if (number % i == 0) {
divisors.push_back(i);
int div = number/i;
if (div != i) divisors.push_back(div);
}
}
return divisors;
}
int main() {
decompo <int> decomposition;
decomposition.complete (1e3); // not relly useful
int n = 2, count;
std::vector<int> weird;
int Nweird = 15000;
for (count = 0; count < Nweird; n += 2) {
if (n % 6 == 0) continue;
//auto properDivisors = getProperDivisors(n);
auto properDivisors = decomposition.GetDivisors(n);
int divisorSum = std::accumulate (properDivisors.begin(), properDivisors.end(), 0);
if (isDeficient(divisorSum, n) ) {
continue;
}
if (isWeird(n, properDivisors, divisorSum)) {
//std::cout << count << " " << n << "\n";
weird.push_back (n);
count++;
}
}
for (int i = Nweird - 10; i < Nweird; ++i) {
std::cout << weird.at(i) << " ";
}
std::cout << "\n";
}

compilation error while uploading sketch to arduino uno

I'm stuck in uploading the arduino sketch to the uno board. I ran into a type error problem. I am not using the polulu wheel encoder. Please help me resolve this issue.
RobotController:14: error: 'PololuWheelEncoders2' does not name a type
RobotController.pde: In function 'void setup()':
RobotController:83: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void ReadSonar()':
RobotController:271: error: 'MID_SPEED' was not declared in this scope
RobotController.pde: In function 'int NormalizeSpeed(int)':
RobotController:340: error: 'MID_SPEED' was not declared in this scope
RobotController:343: error: 'MID_SPEED' was not declared in this scope
RobotController.pde: In function 'void SetMotors(int, int, int, int, bool, bool, bool)':
RobotController:359: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void NormalizeMotors()':
RobotController:368: error: 'MID_SPEED' was not declared in this scope
RobotController:369: error: 'encoders' was not declared in this scope
RobotController.pde: In function 'void SynchronizeMotors()':
RobotController:392: error: 'encoders' was not declared in this scope
RobotController:398: error: 'MID_SPEED' was not declared in this scope
RobotController:407: error: 'MID_SPEED' was not declared in this scope
#include <Usb.h>
#include <AndroidAccessory.h>
#include <PololuWheelEncoders2.h>
#include <Servo.h>
AndroidAccessory acc("Manufacturer", "Model", "Description", "Version", "URI", "Serial");
byte RcvMsg[5];
byte SntMsg[5];
Servo rightSideMotors;
Servo leftSideMotors;
PololuWheelEncoders2 encoders;
const int MIN_SPEED = 40;
const int MAX_SPEED = 140;
const int RIGHT_ADV_THRES = 100;
const int WHEEL_CIR = 36; //wheel circumference in cm
const int BAUD_RATE = 9600;
const int LAS_HOR_PIN = 2; //blue
const int LAS_VERT_PIN = 3; //white
const int CAM_HOR_PIN = 4;
const int CAM_VERT_PIN = 5;
const int FRONT_SONAR = 8;
const int REAR_SONAR = 9;
const int SPEED_CONT_PIN = 14;
const int DIR_CONT_PIN = 6;
int LoopCount = 0;
Servo LaserHor;
Servo CameraHor;
Servo CameraVert;
Servo LaserVert;
int RightSideAdv = 0;
long LeftSideStop = 0;
long RightSideStop = 0;
int LeftSideSpeed = 0;
int RightSideSpeed = 0;
const int DELAY = 1;
const int READ_SONAR_FREQ = 10;
const int BROADCAST_SONAR_FREQ = 10;
const int SONAR_SAMPLES = 30;
const int SONAR_TAKE_ACTION_THRESHOLD = 50;
const int SYNCH_MOTORS_FREQ = 100;
bool HeedSonar = true;
bool Synchronize = false;
bool WatchForStop = true;
bool TEST_CYCLE = false;
int TEST_COUNT = 0;
enum Commands { CmdMoveForward, CmdMoveForwardDistance, CmdMoveBackward, CmdMoveBackwardDistance, CmdSpinLeft, CmdSpinLeftDistance, CmdSpinRight, CmdSpinRightDistance, CmdStop, CmdMoveCameraVert, CmdMoveCameraHor };
enum Events { EvtFrontSonar, EvtRearSonar, EvtSonarStop, EvtDistanceStop };
void setup () {
Serial.begin(BAUD_RATE);
//LaserHor.attach(LAS_HOR_PIN);
LaserVert.attach(LAS_VERT_PIN);
CameraHor.attach(CAM_HOR_PIN);
CameraVert.attach(CAM_VERT_PIN);
//LaserHor.write(90);
LaserVert.write(90);
CameraHor.write(90);
CameraVert.write(90);
rightSideMotors.attach(SPEED_CONT_PIN);
leftSideMotors.attach(DIR_CONT_PIN);
pinMode(FRONT_SONAR, INPUT);
pinMode(REAR_SONAR, INPUT);
encoders.init(10, 11, 13, 12);
MoveForward(50, 1000);
acc.powerOn();
}
void TestCycle() {
/*Serial.println("STOPPING:");
Serial.println(LeftSideStop);
Serial.println(RightSideStop);
Serial.println(abs(encoders.getCountsLeft()) - LeftSideStop);
Serial.println(abs(encoders.getCountsRight()) - RightSideStop);*/
TEST_COUNT++;
if (TEST_COUNT == 1) {
CameraHor.write(45);
delay(150);
CameraHor.write(0);
delay(1000);
CameraHor.write(45);
delay(150);
CameraHor.write(135);
delay(150);
CameraHor.write(180);
delay(1000);
CameraHor.write(135);
delay(150);
CameraHor.write(90);
delay(150);
SpinRight(50, 180);
}
if (TEST_COUNT == 2) {
CameraVert.write(45);
delay(500);
CameraVert.write(135);
delay(500);
CameraVert.write(90);
delay(500);
MoveForward(90, 1000);
}
if (TEST_COUNT == 3) {
CameraVert.write(130);
}
}
void loop() {
if (acc.isConnected()) {
LaserVert.write(130);
ReadIncomingSignal();
if (WatchForStop) {
NormalizeMotors();
}
if (HeedSonar) {
UpdateLoopCount();
if (LoopCount % READ_SONAR_FREQ == 0) {
ReadSonar();
}
if (LoopCount % SYNCH_MOTORS_FREQ == 0) {
SynchronizeMotors();
}
delay(DELAY);
}
}
else {
LaserVert.write(90);
}
}
void SendToAndroid(byte signal, unsigned long value) {
//Serial.print("Sending: ");
//Serial.println(signal);
SntMsg[0] = signal;
SntMsg[1] = value >> 24;
SntMsg[2] = value >> 16;
SntMsg[3] = value >> 8;
SntMsg[4] = value;
acc.write(SntMsg, 5);
}
void ReadIncomingSignal() {
int len = acc.read(RcvMsg, 9, 1);
while (len > 0) {
switch(RcvMsg[0]){
case CmdMoveForward:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveForward(speed);
break;
}
case CmdMoveForwardDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
MoveForward(speed, distance);
break;
}
case CmdMoveBackward:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveBackward(speed);
break;
}
case CmdMoveBackwardDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
MoveBackward(speed, distance);
break;
}
case CmdSpinLeft:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
SpinLeft(speed);
break;
}
case CmdSpinLeftDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
SpinLeft(speed, distance);
break;
}
case CmdSpinRight:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
SpinRight(speed);
break;
}
case CmdSpinRightDistance:
{
int speed = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
int distance = getIntFromBytes(RcvMsg[5], RcvMsg[6], RcvMsg[7], RcvMsg[8]);
SpinRight(speed, distance);
break;
}
case CmdStop:
{
Stop();
break;
}
case CmdMoveCameraVert:
{
int degrees = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveCameraVert(degrees);
break;
}
case CmdMoveCameraHor:
{
int degrees = getIntFromBytes(RcvMsg[1], RcvMsg[2], RcvMsg[3], RcvMsg[4]);
MoveCameraHor(degrees);
break;
}
}
len = acc.read(RcvMsg, 9, 1);
}
}
int getIntFromBytes(byte b1, byte b2, byte b3, byte b4)
{
int value = 0;
value += b1;
value <<= 8;
value += b2;
value <<= 8;
value += b3;
value <<= 8;
value += b4;
return value;
}
void UpdateLoopCount() {
LoopCount = (LoopCount % 1000) + 1;
}
void ReadSonar()
{
unsigned long frontSum = 0;
unsigned long rearSum = 0;
for (int i = 0; i < SONAR_SAMPLES; i++) {
unsigned long frontDuration = pulseIn(FRONT_SONAR, HIGH);
unsigned long rearDuration = pulseIn(REAR_SONAR, HIGH);
frontSum += frontDuration / 147.0 * 2.54;
rearSum += rearDuration / 147.0 * 2.54;
}
unsigned long frontAvg = frontSum / SONAR_SAMPLES;
unsigned long rearAvg = rearSum / SONAR_SAMPLES;
bool forward = LeftSideSpeed > MID_SPEED || RightSideSpeed > MID_SPEED;
if (HeedSonar && ((forward && frontAvg <= SONAR_TAKE_ACTION_THRESHOLD) || (!forward && rearAvg <= SONAR_TAKE_ACTION_THRESHOLD))) {
Stop();
}
Serial.println(LoopCount);
Serial.println(frontAvg);
if (LoopCount % BROADCAST_SONAR_FREQ == 0) {
SendToAndroid(EvtFrontSonar, frontAvg);
SendToAndroid(EvtRearSonar, rearAvg);
}
}
void MoveForward(int speed) {
SetMotors(speed, speed, 0, 0, true, true, false);
}
void MoveForward(int speed, int cms) {
SetMotors(speed, speed, cms, cms, true, true, true);
}
void MoveBackward(int speed) {
SetMotors(-speed, -speed, 0, 0, true, true, false);
}
void MoveBackward(int speed, int cms) {
SetMotors(-speed, -speed, cms, cms, true, true, true);
}
void SpinLeft(int speed) {
SetMotors(-speed, speed, 0, 0, true, false, false);
}
void SpinLeft(int speed, int degrees) {
int cms = (degrees / 3.0);
int extra = ((cms - 30) / 30.0);
cms += extra;
SetMotors(-speed, speed, cms, cms, true, false, true);
}
void SpinRight(int speed) {
SetMotors(speed, -speed, 0, 0, true, false, false);
}
void SpinRight(int speed, int degrees) {
int cms = (degrees / 3.0);
int extra = ((cms - 30) / 30.0) * 2.0;
cms += extra;
SetMotors(speed, -speed, cms, cms, true, false, true);
}
void MoveCameraVert(int degrees) {
CameraVert.write(degrees);
}
void MoveCameraHor(int degrees) {
CameraHor.write(degrees);
}
void Stop() {
SetMotors(0, 0, 0, 0, false, true, true);
if (TEST_CYCLE) {
TestCycle();
}
}
int NormalizeSpeed(int speedAsPercent) {
if (speedAsPercent == 0) {
return MID_SPEED;
}
else {
return (int)(MID_SPEED + ((MAX_SPEED - MID_SPEED) * (speedAsPercent / 100.0)));
}
}
long NormalizeDistance(int cms) {
return (long)((cms * 3200.0) / WHEEL_CIR); //64 counts per rev, 50:1 ratio = 64 * 50 = 3200
}
void SetMotors(int leftSpeed, int rightSpeed, int leftStop, int rightStop, bool synchronize, bool heedSonar, bool watchForStop) {
LeftSideSpeed = NormalizeSpeed(leftSpeed);
RightSideSpeed = NormalizeSpeed(rightSpeed);
LeftSideStop = NormalizeDistance(leftStop);
RightSideStop = NormalizeDistance(rightStop);
leftSideMotors.write(LeftSideSpeed);
rightSideMotors.write(RightSideSpeed);
encoders.getCountsAndResetRight();
encoders.getCountsAndResetLeft();
Synchronize = synchronize;
HeedSonar = heedSonar;
WatchForStop = watchForStop;
RightSideAdv = 0;
}
void NormalizeMotors() {
if (LeftSideSpeed != MID_SPEED || RightSideSpeed != MID_SPEED) {
long left = abs(encoders.getCountsLeft());
long right = abs(encoders.getCountsRight());
bool stopLeft = left >= LeftSideStop;
bool stopRight = right >= RightSideStop;
if (stopLeft && stopRight) {
Stop();
}
else {
if (stopLeft) {
LeftSideSpeed = 0;
leftSideMotors.write(MID_SPEED);
}
if (stopRight) {
RightSideSpeed = 0;
rightSideMotors.write(MID_SPEED);
}
}
}
}
void SynchronizeMotors() {
if (Synchronize) {
long left = abs(encoders.getCountsLeft());
long right = abs(encoders.getCountsRight());
int newRightAdv = right - left;
if (abs(newRightAdv) > RIGHT_ADV_THRES && abs(newRightAdv) > abs(RightSideAdv)) {
if (newRightAdv > 0) {
//Serial.println("DOWN");
if (RightSideSpeed < MID_SPEED) {
RightSideSpeed += 1;
}
else {
RightSideSpeed -= 1;
}
}
else {
//Serial.println("UP");
if (RightSideSpeed < MID_SPEED) {
RightSideSpeed -= 1;
}
else {
RightSideSpeed += 1;
}
}
rightSideMotors.write(RightSideSpeed);
}
RightSideAdv = newRightAdv;
}
}
thanks in advance!
Do you not need the Poloulu wheel encoders? In line 12, you create a variable named "encoders" which is set to type = PololuWheelEncoders2. The error is telling you that this is not a valid type for a variable.

Converting Relation to Matrix

I have 2 sets and 1 relation. I want to show them in a matrix.
char a[] = "12345";
char b[] = "ABCDE";
char r[] = "1C2B3E4D5A";
int rel[LA][LA] = {
/* A B C D E*/
/* 1*/{0, 0, 0, 0, 0} ,
/* 2*/{0, 0, 0, 0, 0} ,
/* 3*/{0, 0, 0, 0, 0} ,
/* 4*/{0, 0, 0, 0, 0} ,
/* 5*/{0, 0, 0, 0, 0} };
in the char array each char is an element
char a[] = "12345"; is A{1,2,3,4,5}
Relation char r[] = "1C2B3E4D5A"; is R= {(1,C),(2.B).... }
My question is how can I Show them on Matrix that If there is a relation on A and B in R in the matrix this point get 1 .
Output must like that :
int rel[LA][LA] = {
/* A B C D E*/
/* 1*/{0, 0, 1, 0, 0} ,
/* 2*/{0, 1, 0, 0, 0} ,
/* 3*/{0, 0, 0, 0, 1} ,
/* 4*/{0, 0, 0, 1, 0} ,
/* 5*/{1, 0, 0, 0, 0} };
Firstly I tried :
for(i=0;i<LR-1;i=i+2){ // Look at element from A
for(j=0;j<LA;j++){ // Look at A
if(r[i]==a[j]){
for(k=1;k<LR;k=k+2){ // Look at element from B
for(m=0;m<LA;m++){ // Look at B
if(r[k]==b[m]){
rel[j][m]=1; // if both exist that point gets 1
}
}
}
}
}
}
It does not work.
Here is a solution to your problem:
public static void main(String[] args) {
char[] a = "12345".toCharArray();
char[] b = "ABCDE".toCharArray();
char[] r = "1C2B3E4D5A".toCharArray();
int LA=a.length;
int LB=b.length;
int LR=r.length;
int[][] rel=new int[LA][LB];
for(int i=0;i<LR;i+=2){
int indexa=index(a,r[i]);
int indexb=index(b,r[i+1]);
rel[indexa][indexb]=1;
}
// Print out the matrix
for(int i=0;i<LA;i++){
for(int j=0;j<LB;j++){
System.out.print(rel[i][j]);
}
System.out.println("");
}
}
/**
* Return the position of a value v array arr
*/
public static int index(char[] arr,char v){
for(int i=0;i<arr.length;i++){
if(arr[i]==v){
return i;
}
}
return -1;
}

Heap sort not working as expected

I'm trying to implement heap sort using the CLRS book. My code is:
private void maxHeapify(int[] input, int i) {
int l = left(i);
int r = right(i);
int largest;
if(l <= heapSize && input[l] > input[i]) {
largest = l;
} else {
largest = i;
}
if(r <= heapSize && input[r] > input[largest]) {
largest = r;
}
if(largest != i) {
swap(input, i, largest);
maxHeapify(input, largest);
}
}
private void buildMaxHeap(int[] input) {
heapSize = input.length;
for(int i = (input.length-1)/2; i >= 0; i--) {
maxHeapify(input, i);
}
}
public void heapSort(int[] input) {
buildMaxHeap(input);
for(int i = input.length-1; i > 0; i--) {
swap(input, 0, i);
heapSize--;
maxHeapify(input, 0);
}
}
For an input of {1, 5, 3, 7, 2, 0, 6, 2}, I'm getting the answer as 7 3 0 6 2 5 1 2. Why is this happening? I'm guessing it has something to do with the line for(int i = (input.length-1)/2; i >= 0; i--) but I can't put my finger on it.

Tampering detection by using sobel edge in processing

I have to use Sobel edge detection to detect how an image has been tampered with. I have been able to implement the edge filter, but have not been able to figure out how to use it to detect tampering. I want to show the tampering by highlighting the region that has been tampered with in another color.
Can someone help please?
PImage img, edgeImg;
int[][] sobelx = { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } };
int[][] sobely = { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
void setup() {
img = loadImage("face1.jpg");
size(img.width, img.height);
edgeImg = createImage(img.width, img.height, RGB);
}
void draw() {
image(img, 0, 0);
int matrixsize = 3;
loadPixels();
img.loadPixels();
int loc = 0;
for (int x = 1; x < img.width - 1; x++) {
for (int y = 1; y < img.height - 1; y++) {
loc = x + y * img.width;
int sx = convolution(x, y, sobelx, matrixsize, img);
int sy = convolution(x, y, sobely, matrixsize, img);
int sum = abs(sy) + abs(sx);
sum = constrain(sum, 0, 255);
edgeImg.pixels[loc] = sum;
}
}
edgeImg.updatePixels();
image(edgeImg, 0, 0);
filter(THRESHOLD, 0.8);
}
int convolution(int x, int y, int [][] mat, int matrixsize, PImage img) {
float rtotal = 0.0;
float gtotal = 0.0;
float btotal = 0.0;
int total = 0;
int offset = matrixsize/2;
for(int i=0; i<matrixsize; i++) {
for(int j=0; j<matrixsize; j++) {
int xloc = x + i - offset;
int yloc = y + j - offset;
int loc = xloc + img.width*yloc;
loc = constrain(loc,0,img.pixels.length - 1);
rtotal = rtotal + red(img.pixels[loc])*mat[i][j];
gtotal = gtotal + green(img.pixels[loc])*mat[i][j];
btotal = btotal + blue(img.pixels[loc])*mat[i][j];
total = total + int(brightness(img.pixels[loc])*mat[i][j]);
}
}
rtotal = constrain(rtotal, 0, 255);
gtotal = constrain(gtotal, 0, 255);
btotal = constrain(btotal, 0, 255);
return total;
}
I don't know how the algorithm can be used for your particular purpose, but I would guess you would need to run the same filter to the original image and compare the results.
PImage original = loadImage("face1.jpg");
PImage edgeImg; // previously created
original.loadPixels();
edgeImg.loadPixels();
for (int i=0; i<original.pixels.length; i++) {
color origPx = original.pixels[i];
color edgePx = edgeImg.pixels[i];
// compare red values, since the edgeImg is B&W
if ( (origPx >> 16 & 0xFF) != (edgePx >> 16 & 0xFF) ) {
// don't match? do something!
}
}

Resources