![](/user_photo/_userpic.png)
C++ For Mathematicians (2006) [eng]
.pdf![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR461x1.jpg)
436 |
C++ for Mathematicians |
return b < that.b;
}
};
inline ostream& operator<<(ostream& os, const Interval& I) { os << "[" << I.getA() << "," << I.getB() << "]";
return os;
}
#endif
7.2 The following program accomplishes the required task. It does its work by the following observation. Suppose the intervals are I1,I2,... ,In where Ij = [a j,b j] with a j < b j. Let α = maxj a j and β = minj b j. Interval Ik meets all intervals if and only if ak ≤ β and bk ≥ α.
#include "Interval.h" #include "uniform.h" using namespace std;
double find_max_A(const Interval* list, long ni) { double ans = list[0].getA();
for (long k=1; k<ni; k++) {
if (ans < list[k].getA()) ans = list[k].getA();
}
return ans;
}
double find_min_B(const Interval* list, long ni) { double ans = list[0].getB();
for (long k=1; k<ni; k++) {
if (ans > list[k].getB()) ans = list[k].getB();
}
return ans;
}
bool one_meets_all(const Interval* list, long ni) { double alpha = find_max_A(list,ni);
double beta = find_min_B(list,ni);
for (long k=0; k<ni; k++) {
if ((list[k].getA() <= beta) && (list[k].getB() >= alpha)) { return true;
}
}
return false;
}
int main() { seed(); long ni;
cout << "Enter number of intervals --> "; cin >> ni;
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR462x1.jpg)
|
|
|
Answers |
437 |
|
||
|
long nreps; |
|
|
|
|
|
|
|
cout << "Enter number of repetitions --> "; |
|
|
||||
|
cin >> nreps; |
|
|
|
|
|
|
|
Interval* list; |
|
|
|
|
|
|
|
list = new Interval[ni]; |
|
|
|
|
||
|
long count = 0; |
|
|
|
|
|
|
|
for (long j=0; j<nreps; j++) { |
|
|
||||
|
for (long k=0; k<ni; k++) { |
|
|
||||
|
list[k] = Interval(unif(), unif()); |
|
|
||||
} |
|
|
|
|
|
|
|
|
if (one_meets_all(list,ni)) count++; |
|
|
||||
} |
|
|
|
|
|
|
|
|
cout << "Success rate: " << 100*double(count)/double(nreps) |
|
|
||||
|
<< "%" << endl; |
|
|
|
|
||
|
delete[] list; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Here is a sample run of the program. |
|
|
||||
|
|
|
|
|
|
||
|
Enter number of intervals --> 100 |
|
|
||||
|
|
|
|||||
|
Enter number of repetitions --> 100000 |
|
|
||||
|
Success rate: 66.659% |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
It appears that about 2 |
of the time there is an interval that meets all the others. |
|||||
|
|
3 |
|
|
∞, the probability there is such an interval |
||
|
One might |
conjecture that as n |
→ |
||||
|
2 |
|
|
|
|
||
|
approaches |
3 (and this is true). |
On the other hand, it is not hard to show |
that for n = 2, the probability that the two intervals intersect is exactly 23 . The surprise is that for any value of n ≥ 2, the probability there is an interval that intersects all the others is 23 . [Reference: J. Justicz, E. Scheinerman, and P. Winkler, Random intervals, American Mathematical Monthly 97 (December 1990) 881–889.]
7.3How can we sort the array and not modify it? Work with a copy. Here’s the code.
#include <iostream> #include <algorithm> using namespace std;
double median(const double* array, long nels) { if (nels < 0) return 0.;
if (nels == 0) return array[0];
// make a copy of the array double* copy_array; copy_array = new double[nels];
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR463x1.jpg)
438 |
C++ for Mathematicians |
for (int k=0; k<nels; k++) copy_array[k] = array[k];
// sort the copy
sort(copy_array, copy_array+nels);
//extract the single middle element or the averages
//of two most central elements in the sorted list double ans;
if (nels%2 == 1) {
ans = copy_array[nels/2];
}
else {
ans = (copy_array[nels/2] + copy_array[(nels/2)+1]) / 2.;
}
//free the copy and return the result
delete[] copy_array; return ans;
}
7.4We can modify Program 7.3 to do the work. We need to generate all primitive Pythagorean triples containing a leg or a hypotenuse whose length is at most
100. To do this, we run the constructor PTriple(m,n) for all m,n ≤ 100. Note that if either m or n is greater than 100, then all three of 2mn, m2 − n2, and m2 + n2 exceed 100 and may be ignored. Here’s a program.
#include "PTriple.h" #include <iostream> #include <algorithm> using namespace std;
/**
*Count the number of triples with a given leg and
*a given hypotenuse
*/ |
|
int main() { |
|
PTriple* table; |
// table to hold the triples |
const int N = 100; |
// maximum length we’re counting |
int leg_count[N+1]; |
// tally leg lengths |
int hyp_count[N+1]; |
// tally hypotenuse lengths |
//Make sure counters are all zero for (int k=0; k<=N; k++) {
leg_count[k] = 0; hyp_count[k] = 0;
}
//Allocate space for the table table = new PTriple[2*N*N];
//Populate the table with all possible PTriples long idx = 0; // index into the table
for (long m=1; m<=N; m++) {
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR464x1.jpg)
Answers |
439 |
for (long n=1; n<=N; n++) { PTriple P = PTriple(m,n); if (P.getA() <= N) {
table[idx] = P; idx++;
}
}
}
//Sort the table sort(table, table+idx);
//Process unique elements in the tables leg_count[table[0].getA()]++; leg_count[table[0].getB()]++; hyp_count[table[0].getC()]++;
for (int k=1; k<idx; k++) {
if (table[k] != table[k-1]) { long a,b,c;
a = table[k].getA(); b = table[k].getB(); c = table[k].getC();
if (a<=N) leg_count[a]++; if (b<=N) leg_count[b]++; if (c<=N) hyp_count[c]++;
}
}
cout << "Length\tLeg\tHypotenuse" << endl; for (int k=0; k<=N; k++) {
cout << k << "\t" << leg_count[k] << "\t" << hyp_count[k] << endl;
}
// Release memory held by the table delete[] table;
return 0;
}
When the program is run, we see the following output.
|
|
|
|
||
|
Length |
Leg |
Hypotenuse |
|
|
|
|
||||
0 |
1 |
0 |
|
|
|
1 |
1 |
1 |
|
|
|
2 |
0 |
0 |
|
|
|
3 |
1 |
0 |
|
|
|
4 |
1 |
0 |
|
|
|
5 |
1 |
1 |
|
|
|
6 |
0 |
0 |
|
|
|
7 |
1 |
0 |
|
|
|
8 |
1 |
0 |
|
|
|
9 |
1 |
0 |
|
|
|
.................. |
|
|
|||
90 |
0 |
0 |
|
|
|
91 |
2 |
0 |
|
|
|
|
|
|
|
|
|
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR465x1.jpg)
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR466x1.jpg)
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR467x1.jpg)
442 |
C++ for Mathematicians |
and the result follows.
This sequence also arises in counting the number of perfect partitions of an integer. See the On-Line Encyclopedia of Integer Sequences, sequence A002033 and Eric W. Weisstein, “Perfect Partitions,” from Mathworld—A Wolfram Web Resource.
http://mathworld.wolfram.com/PerfectPartition.html
8.5Here is a file Partition.h that creates the class (with all methods and procedures written inline).
#ifndef PARTITION_H #define PARTITION_H
#include <set> #include <iostream> #include <vector> using namespace std;
class Partition { private:
///A multiset to hold the parts multiset<int> parts;
///An integer to hold the sum int sum;
public:
///Default constructor: create null partition of 0 Partition() {
sum = 0; parts.clear();
}
///Add a new part to this partition
void add_part(int n) { if (n <= 0) {
cerr << "Cannot add nonpositive part to a partition" << endl;
return;
}
parts.insert(n); sum += n;
}
///What is the sum of the parts? int get_sum() const { return sum; }
///How many parts in this partition?
int nparts() const { return parts.size(); }
/// Get a vector containing the parts vector<int> get_parts() const {
vector<int> ans; ans.resize(nparts());
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR468x1.jpg)
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR469x1.jpg)
444 |
C++ for Mathematicians |
set<Partition> make_partitions(int n, int mp) { set<Partition> ans;
set<Partition> tmp;
if (mp>n) mp = n;
if (n==0) { ans.insert(Partition()); return ans;
}
for (int k=1; k<=n; k++) { tmp.clear();
tmp = make_partitions(n-k,k); set<Partition>::iterator sp;
for (sp = tmp.begin(); sp != tmp.end(); sp++) { Partition P = *sp;
P.add_part(k); ans.insert(P);
}
}
return ans;
}
set<Partition> make_partitions(int n) { return make_partitions(n,n);
}
int main() {
cout << "Enter n: "; int n;
cin >> n;
set<Partition> PS = make_partitions(n); set<Partition>::iterator pp;
for (pp = PS.begin(); pp != PS.end(); pp++) { cout << *pp << endl;
}
cout << PS.size() << " partitions of " << n << endl; return 0;
}
Here is a sample run of the program.
|
|
|
||
|
Enter n: 6 |
|
||
|
|
|||
6 |
= 6 |
|
|
|
6 |
= 5+1 |
|
|
|
6 |
= 4+2 |
|
|
|
6 |
= 3+3 |
|
|
|
6 |
= 4+1+1 |
|
|
|
6 |
= 3+2+1 |
|
|
|
6 |
= 2+2+2 |
|
|
|
6 |
= 3+1+1+1 |
|
|
|
6 |
= 2+2+1+1 |
|
|
|
6 |
= 2+1+1+1+1 |
|
|
|
|
|
|
|
|
![](/html/611/317/html_XkIwBBZW6e.0JgL/htmlconvd-64c5QR470x1.jpg)