0% found this document useful (0 votes)
29 views

Chapter 3 Brute Force Student

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

Chapter 3 Brute Force Student

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

1

Chapter 3: Brute Force and Exhaustive Search

Introduction

The subject of this chapter is brute force and its important special case, exhaustive
search. Brute force can be described as follows:
Brute force is a straightforward approach to solving a problem, usually directly
based on the problem statement and definitions of the concepts involved.

Example: Computing 𝑥 𝑛 .
By the definition of exponentiation,
𝑥𝑛 = ⏟ 𝑥 × …× 𝑥
𝑛 𝑡𝑖𝑚𝑒𝑠
𝑛
This suggests simply computing 𝑥 by multiplying 1 by 𝑥 𝑛 times.

The role of brute force


1. Brute-force is applicable to a very wide variety of problems.
2. A brute-force algorithm can still be useful for solving small-size instances of a
problem.
3. The expense of designing a more efficient algorithm may be unjustifiable if only a
few instances of a problem need to be solved and a brute-force algorithm can solve
those instances with acceptable speed.
4. A brute-force algorithm can serve an important theoretical or educational purpose
as a yardstick with which to judge more efficient alternatives for solving a problem.
5. A first application of the brute-force approach often results in an algorithm that can
be improved with a modest amount of effort.

Example: Bubble sort - Θ(𝑛2 )


Bubblesort(a[1 .. n]) {
for (i = 2; i  n; i++)
for (j = n; j  i; j--)
if (a[j - 1] > a[j])
a[j - 1]  a[j];
}
Note: We can improve the above algorithm by exploiting some observations and an
upgrade version of Bubble sort is Shake sort.
2

Example: Brute force string matching


SequentialStringSearch(T[1 .. n], P[1 .. m]) {
count = 0;
for (i = 1; i ≤ n – m + 1; i++) {
j = 0;
while (j < m) && (P[1 + j] == T[i + j])
j++;
if (j == m)
count++;
}
return count;
}

The best-case efficiency: 𝐵(𝑛) =


The worst-case efficiency: 𝑊(𝑛) =
The average-case efficiency: 𝐴(𝑛) =

Find the subsequence with largest sum of elements in an array

Given an array of 𝑛 integers 𝑎1 , 𝑎2 , … , 𝑎𝑛 . The task is to find indices 𝑖 and 𝑗 with


𝑗
1 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛, such that the sum ∑𝑘=𝑖 𝑎𝑘 is as large as possible. If the array contains all
non-positive numbers, then the largest sum is 0.

Brute force version with running time Θ(𝑛3 )


MaxContSubSum(a[1 .. n]) {
maxSum = 0;
for (i = 1; i ≤ n; i++)
for (j = i; j ≤ n; j++) {
curSum = 0;
for (k = i; k ≤ j; k++)
curSum += a[k];
if (curSum > maxSum)
maxSum = curSum;
}
return maxSum;
}
3

Upgrade version with running time Θ(𝑛2 )

MaxContSubSum(a[1 .. n]) {
maxSum = 0;
for (i = 1; i ≤ n; i++) {
curSum = 0;
for (j = i; j ≤ n; j++) {
curSum += a[j];
if (curSum > maxSum)
maxSum = curSum;
}
}
return maxSum;
}

Dynamic programming version with running time Θ(𝑛)

MaxContSubSum(a[1 .. n]) {
maxSum = curSum = 0;
for (j = 1; j ≤ n; j++) {
curSum += a[j];
if (curSum > maxSum)
maxSum = curSum;
else
if (curSum < 0)
curSum = 0;
}
return maxSum;
}

The change-making problem

Given 𝑘 denominations: 𝑑1 < 𝑑2 < ⋯ < 𝑑𝑘 where 𝑑1 = 1. Find the minimum


number of coins (of certain denominations) that add up to a given amount of money 𝑛.
4

Example: Suppose that there are 4 denominations: 𝑑1 = 1, 𝑑2 = 5, 𝑑3 = 10, 𝑑4 =


25 and the amount of money 𝑛 = 72. The minimum number of coins is 6 including two
pennies, two dimes, and two quarters.

Idea: Find all 𝑘-tuples 〈𝑐1 , 𝑐2 , … , 𝑐𝑘 〉 such that:


𝑐1 × 𝑑1 + 𝑐2 × 𝑑2 + ⋯ + 𝑐𝑘 × 𝑑𝑘 = 𝑛
where 𝑐𝑖 is the number of coins of denomination 𝑑𝑖 . Among these 𝑘-tuples we choose the
one with the smallest sum ∑𝑘𝑖=1 𝑐𝑖 .

The efficiency of this algorithm is as follows:


𝑛 𝑛 𝑛 𝑛𝑘
𝑇(𝑛) = × ×…× = ∈ Θ(𝑛𝑘 )
𝑑1 𝑑2 𝑑𝑘 𝑑1 × 𝑑2 × … × 𝑑𝑘
because 𝑑1 , 𝑑2 , … , 𝑑𝑘 are constants.

Closest-Pair Problem

This problem calls for finding the two closest points in a set of 𝑛 points in the plan.

Algorithm with running time Θ(𝑛2 )

BruteForceClosestPoints(P[1 .. n]) {
dmin = ;
for (i = 1; i ≤ n - 1; i++)
for (j = i + 1; j ≤ n; j++) {
d = √(𝑃[𝑖]. 𝑥 − 𝑃[𝑗]. 𝑥)2 + (𝑃[𝑖]. 𝑦 − 𝑃[𝑗]. 𝑦)2 ;
if (d < dmin) {
dmin = d;
point1 = P[i];
point2 = P[j];
}
}
return <point1, point2>;
}
5

Convex-hull problem

Intuitively, the convex-hull of a set of 𝑛 points in the plane is the smallest convex
polygon that contains all of them either inside or on its boundary.
Note: Mathematicians call the vertices of such a polygon “extreme points.” Finding these
points is the way to construct the convex hull for a given set of 𝑛 points.

A brute force approach is based on the following observation:


“A line segment 𝑝𝑞̅̅̅ connecting two points 𝑝 and 𝑞 of a set of 𝑛 points is a part of
the convex hull’s boundary if and only if all the other points of the set lie on the same side
of the straight line through these two points.”

It’s known that the straight line through two points (𝑥1 , 𝑦1 ) and (𝑥2 , 𝑦2 ) in the
coordinate plane can be defined by the equation
𝑎𝑥 + 𝑏𝑦 = 𝑐
where 𝑎 = 𝑦2 − 𝑦1 , 𝑏 = 𝑥1 − 𝑥2 , 𝑐 = 𝑥1 𝑦2 − 𝑥2 𝑦1 .
Second, such a line divides the plane into two half-planes: for all the points in one
of them, 𝑎𝑥 + 𝑏𝑦 > 𝑐, while for all the points in the other, 𝑎𝑥 + 𝑏𝑦 < 𝑐. For the points on
the line itself, 𝑎𝑥 + 𝑏𝑦 = 𝑐.

Brute force algorithm with running time Θ(𝑛3 )


for (each point pi  S: i = 1 → n - 1)
for (each point pj  S: j = i + 1 → n) {
Construct the line 𝑝̅̅̅̅̅;
𝑖 𝑝𝑗
if (all the other points in S lie on the same side of
𝑝
̅̅̅̅̅)
𝑖 𝑝𝑗
Store the pair of two points <pi, qj>;
}
6

Now, let’s consider another brute force approach whose output is a list of the
extreme points in a counterclockwise order.

Initially, the point with the lowest y-value must be the first extreme point in the
result list. If there are two points with the same lowest y-value then the leftmost one is the
first extreme point.

Assume that 𝑝 is the current extreme point, how to find out the next one?

Let’s denote 𝑐𝑢𝑟𝐴𝑛𝑔𝑙𝑒 the current angle (initially, 𝑐𝑢𝑟𝐴𝑛𝑔𝑙𝑒 = 0). The next
extreme point 𝑞 must satisfy the following condition:

̂
𝑐𝑢𝑟𝐴𝑛𝑔𝑙𝑒 ≤ (𝑝𝑞
̅̅̅, ̂
0𝑥) < (𝑝𝑟
̅̅̅, 0𝑥), ∀𝑟 ∈ 𝑆: 𝑟 ≠ 𝑝, 𝑟 ≠ 𝑞

Note: The value of 𝑐𝑢𝑟𝐴𝑛𝑔𝑙𝑒 is increased from 0 to 2𝜋.

 

  

Algorithm

computeAngle(point from, point to) {


angle = atan2(to.y - from.y, to.x - from.x);
if (angle < 0)
angle += 2 * ;
return angle;
}
7

findNextExtremePoint(S, cur, curAngle) {


minAngle = 2 * ;
S \= cur;
for (each point p in S) {
angle = computeAngle(cur, p);
if (angle < minAngle && angle ≥ curAngle) {
next = p;
minAngle = angle;
}
}
S = cur;
return [next, minAngle];
}

computeConvexHull(S) {
convexHull = ;
// Let “first” be the first extreme point
convexHull = first;
curAngle = 0;
point cur = first;
while (true) {
[next, curAngle] = findNextExtremePoint(S, cur,
curAngle);
if (first == next)
break;
convexHull = next;
cur = next;
}
return convexHull;
}

What is the efficiency of this algorithm? In the worst case, the running time is
2 ).
Θ(𝑛 Otherwise?
8

Exhaustive Search

Exhaustive search is simply a brute-force approach to combinatorial problems.

Algorithm for finding all subsets of a set of size 𝑛


for (k = 0; k < 2n; k++)
Output the binary string of length n representing k;

Algorithm for generating all permutations of a set


Permutation(pivot, a[1 .. n]) {
if (pivot == n)
Output(a);
else
for (i = pivot; i  n; i++) {
a[pivot]  a[i];
Permutation(pivot + 1, a);
a[pivot]  a[i];
}
}
Permutation(1, a);

Example: Let’s consider all permutations of four elements 𝑎1 , 𝑎2 , 𝑎3 , 𝑎4


𝑎1 , 𝑎2 , 𝑎3 , 𝑎4 𝑎2 , 𝑎1 , 𝑎3 , 𝑎4 𝑎3 , 𝑎2 , 𝑎1 , 𝑎4 𝑎4 , 𝑎2 , 𝑎3 , 𝑎1
𝑎1 , 𝑎2 , 𝑎4 , 𝑎3 𝑎2 , 𝑎1 , 𝑎4 , 𝑎3 𝑎3 , 𝑎2 , 𝑎4 , 𝑎1 𝑎4 , 𝑎2 , 𝑎1 , 𝑎3
𝑎1 , 𝑎3 , 𝑎2 , 𝑎4 𝑎2 , 𝑎3 , 𝑎1 , 𝑎4 𝑎3 , 𝑎1 , 𝑎2 , 𝑎4 𝑎4 , 𝑎3 , 𝑎2 , 𝑎1
𝑎1 , 𝑎3 , 𝑎4 , 𝑎2 𝑎2 , 𝑎3 , 𝑎4 , 𝑎1 𝑎3 , 𝑎1 , 𝑎4 , 𝑎2 𝑎4 , 𝑎3 , 𝑎1 , 𝑎2
𝑎1 , 𝑎4 , 𝑎3 , 𝑎2 𝑎2 , 𝑎4 , 𝑎3 , 𝑎1 𝑎3 , 𝑎4 , 𝑎1 , 𝑎2 𝑎4 , 𝑎1 , 𝑎3 , 𝑎2
𝑎1 , 𝑎4 , 𝑎2 , 𝑎3 𝑎2 , 𝑎4 , 𝑎1 , 𝑎3 𝑎3 , 𝑎4 , 𝑎2 , 𝑎1 𝑎4 , 𝑎1 , 𝑎2 , 𝑎3

Let’s denote 𝑇(𝑛) the number of times the basic operation must be executed to
generate all permutations of a set of 𝑛 elements. The recurrence relation is as follows:
𝑇(𝑛) = 𝑛𝑇(𝑛 − 1) + Θ(𝑛)
with the initial condition 𝑇(1) = 0.
Hint: 𝑇(𝑛) ∈ Ω(𝑛!)
9

Traveling Salesman Problem

The problem asks to find the shortest tour through a given set of 𝑛 cities that visits
each city exactly once before returning to the city where it started.

Note: The problem can also be stated as the problem of finding the shortest Hamiltonian
circuit of a weighted graph.

Hamiltonian circuit: Given a graph of 𝑛 vertices. A Hamiltonian circuit is defined


as a sequence of 𝑛 + 1 vertices: 𝑣𝑖0 , 𝑣𝑖1 , …, 𝑣𝑖𝑛−1 , 𝑣𝑖𝑛 such that:
1. 𝑣𝑖0 ≡ 𝑣𝑖𝑛
2. ∀𝑗 ∈ [0, 𝑛 − 1]: 𝑣𝑖𝑗 is adjacent to 𝑣𝑖𝑗+1
3. ∀𝑗, 𝑘 ∈ [0, 𝑛 − 1]: 𝑣𝑖𝑗 ≠ 𝑣𝑖𝑘 iff 𝑗 ≠ 𝑘

In words, a Hamiltonian circuit is defined as a cycle that passes through all the
vertices of the graph exactly once.

Idea: With no loss of generality, we can assume that all circuits start and end at one
particular vertex 𝑣𝑖0 . Thus, we can get (𝑛 − 1)! potential tours by generating all the
permutations of 𝑛 − 1 intermediate cities and attach 𝑣𝑖0 to the beginning and the end of
each permutation. Then, we verify if each potential tours is a Hamiltonian circuit? If it’s
true then we compute the tour lengths, and find the shortest among them.

The time efficiency of this algoritm is Θ(𝑛!).

Sum of subsets problem

The sum of subsets problem consists of finding all subsets of a given set A =
{𝑎1 , 𝑎2 , … , 𝑎𝑛 } of 𝑛 distinct positive integers that sum to a positive integer 𝑘.

Example: If A = {3,5,6,7,8,9,10} and 𝑘 = 15, there will be more than one subset
whose sum is 15. The subsets are {3,5,7}, {7,8}, {6,9}, …

A brute force approach is to generate all subsets of the given set A and compute the
sum of each subset.
The time efficiency of this algoritm is Θ(2𝑛 ).
10

Knapsach problem

Given 𝑛 items of known weights 𝑤1 , 𝑤2 , … , 𝑤𝑛 and values 𝑣1 , 𝑣2 , … , 𝑣𝑛 and a


knapsack of capacity 𝐶, find the most valuable subset of the items that fit into the knapsack.

The knapsack problem can also be formally stated as follows:


𝑛

𝑚𝑎𝑥𝑖𝑚𝑖𝑧𝑒 ∑ 𝑣𝑖 𝑥𝑖
𝑖=1
𝑛

𝑠𝑢𝑏𝑗𝑒𝑐𝑡 𝑡𝑜 ∑ 𝑤𝑖 𝑥𝑖 ≤ 𝐶 𝑤ℎ𝑒𝑟𝑒 𝑥𝑖 ∈ {0, 1}, 𝑖 = 1, . . , 𝑛


𝑖=1

A simplistic approach to solving this problem would be to enumerate all subsets of


the 𝑛 items, and select the one that satisfies the constraints and maximizes the profits.
The obvious problem with this strategy is the running time which is at least Θ(2𝑛 )
corresponding to the power set of 𝑛 items.

Assignment problem

There are 𝑛 people who need to be assigned to execute 𝑛 jobs, one person per job.
The cost if the 𝑖 𝑡ℎ person is assigned to the 𝑗 𝑡ℎ job is a known quantity 𝐶𝑖,𝑗 for each pair
𝑖, 𝑗 = 1,2, … , 𝑛. The problem is to find an assignment with the minimum total cost.

Example:
𝐶 Job 1 Job 2 Job 3 Job 4
Person 1 9 2 7 8
Person 2 6 4 3 7
Person 3 5 8 1 8
Person 4 7 6 9 4

We can describe feasible solutions to the assignment problem as 𝑛-tuples


〈𝑗1 , 𝑗2 , … , 𝑗𝑛 〉: ∀𝑖 ∈ [1, 𝑛], 𝑗𝑖 ∈ [1, 𝑛] in which the 𝑖𝑡ℎ component (𝑗𝑖 ) indicates the column
of the element selected in the 𝑖𝑡ℎ row.

Example: 〈2,4,1,3〉 indicates the assignment of person 1 to job 2, person 2 to job 4,


person 3 to job 1, and person 4 to job 3.
11

The exhaustive-search approach to this problem would require generating all the
permutations of integers 1,2, … , 𝑛, computing the total cost of each assignment by
summing up the corresponding elements of the cost matrix, and finally selecting the one
with the smallest sum.

Of course, the running time of this approach is Θ(𝑛!).

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy