Need help with a math type problem

  • Thread starter Thread starter Imy
  • Start date Start date

Imy

Imy

Soldato
Joined
21 Nov 2005
Posts
2,773
Location
Warwickshire, UK
I'm currently working on a large e-commerce website (17k+ products) and was looking at ways to improve the price range navigation.

At the moment it gets the lowest and highest prices of the products being displayed and creates 6 evenly spaced price ranges. Unfortunately this system doesn't work too great because quite often product prices are grouped quite close together, with a few very high and very low priced items skewing the overall distribution of prices, and hence my price ranges.

What I would like to do is something a little bit more clever where the price ranges are chosen based on the distribution of prices, and to a certain extent, ignoring the very low/high values.

Example:
Prices: £1, £40, £42, £43, £43, £43, £47, £50, £52, £90, £600 would currently generate ranges similar to the following:
£0-£100 (10)
£100-£200 (0)
£200-£300 (0)
£300-£400 (0)
£400-£500 (0)
£500-£600 (1)

As you can see - pretty useless. I would instead like it to look more like the following:
£0-£30 (1)
£30-£40 (1)
£40-£45 (5)
£45-£50 (2)
£50-£100 (3)
£100-£600 (1)

Anyone got any ideas?

EDIT: fixed typo: £40-£50 => £45-£50
 
Last edited:
Imy said:
Prices: £1, £40, £42, £43, £43, £43, £47, £50, £52, £90, £600 would currently generate ranges similar to the following:

I would instead like it to look more like the following:
£0-£30 (1)
£30-£40 (1)
£40-£45 (5)
£40-£50 (2)
£50-£100 (3)
£100-£600 (1)

Anyone got any ideas?
Couple of ideas. Firstly, your ranges are a bit confused (40-45 and 40-50!). You've obviously decided you'd rather have 5 entries in the £40-45 pound range rather than split it up. This is a bit arbitrary, so I would generate a universal set of ranges you're happy with. (e.g. every pound for things < £20 then every £5 up to 50, every £10 up to 100). These are arbitrary decisions - my "ideal" solution is probably different from yours (I'd probably have £40-55 as one range, 1 at £90 and 1 at £600).

Then take the actual prices and allocate them to the ranges. Then repeatedly iterate over the ranges, looking at adjacent ranges and deciding whether to reduce them to a single range, until you're down to a total of 6 ranges. (e.g. suppose you have a range £1-5 and a range £6-10. Then there's only 1 item in £1-5 and none in £6-10, so you might as well merge them into one range £1-10. Keep doing things like this until you get down to 6 items).

An alternative (and perhaps easier) solution is to generate boundaries by looking at how many items should fall in each boundary. You have 13 items, so you want 2.1666 items in each boundary. So set the first boundary just greater than the 2nd item (£40), the 2nd just after the 4th item (£43), etc.
Then you get ranges something like 1-40, 40-43, 43-43,47-50,50-90,600. The 43-43 range is a bit of a problem, but you can easily do some post processing to sort that out. The drawback with this method is the ranges don't all come out as "nice" numbers, however.
 
DaveF said:
Couple of ideas. Firstly, your ranges are a bit confused (40-45 and 40-50!).
Sorry typo!

DaveF said:
You've obviously decided you'd rather have 5 entries in the £40-45 pound range rather than split it up. This is a bit arbitrary, so I would generate a universal set of ranges you're happy with. (e.g. every pound for things < £20 then every £5 up to 50, every £10 up to 100). These are arbitrary decisions - my "ideal" solution is probably different from yours (I'd probably have £40-55 as one range, 1 at £90 and 1 at £600).
Due to the total number of products in the system (£17k+), the lowest value comes out at 19p and the highest £4,280.30 and I can have a maximum of 6 ranges. Now each time a customer goes deeper into a category, the number of products (and therefore min/max prices) changes. For this reason I can't have an absolute set of ranges across the board.

DaveF said:
Then take the actual prices and allocate them to the ranges. Then repeatedly iterate over the ranges, looking at adjacent ranges and deciding whether to reduce them to a single range, until you're down to a total of 6 ranges. (e.g. suppose you have a range £1-5 and a range £6-10. Then there's only 1 item in £1-5 and none in £6-10, so you might as well merge them into one range £1-10. Keep doing things like this until you get down to 6 items).

An alternative (and perhaps easier) solution is to generate boundaries by looking at how many items should fall in each boundary. You have 13 items, so you want 2.1666 items in each boundary. So set the first boundary just greater than the 2nd item (£40), the 2nd just after the 4th item (£43), etc.
Then you get ranges something like 1-40, 40-43, 43-43,47-50,50-90,600. The 43-43 range is a bit of a problem, but you can easily do some post processing to sort that out. The drawback with this method is the ranges don't all come out as "nice" numbers, however.
I think that's the nail in the finger. This could work - as you say with some extra 'keep-clean' logic.

One other pain in the arse is that for readability purposes, the ranges are in whole pounds so there is some overlappying e.g. £40 goes into £30-£40 as well as £40-£50.

Cheers for the quick reply!
 
Last edited:
Imy said:
Due to the total number of products in the system (£17k+), the lowest value comes out at 19p and the highest £4,280.30 and I can have a maximum of 6 ranges. Now each time a customer goes deeper into a category, the number of products (and therefore min/max prices) changes. For this reason I can't have an absolute set of ranges across the board.
Yeah, I understood that. The point is that it's very hard for a computer to know what's a "nice" (i.e. aesthetically pleasing) range (why is £400-450 a nice range but £403-457 not?). So you create a complete set of ranges covering the entire set of products - there will be a lot more than 6 ranges, but each of them is "nice". (In practice you would probably work out how you wanted to divide up 10-100 pounds and then use the same ranges scaled up/down by powers of 10 to cover the rest of the price ranges). Then for any particular set of products you merge/discard from this 'canonical' set of ranges to get down to a set of 6.

I think this might give you "better" solutions than the other approach I gave you; in particular it's a bit more flexible. If you had the situation with 100 products costing between £500 & £510, and 2 products costing £1000 and £2000, the other solution will end up lumping the 2 expensive products together, whereas the "merging" method could decide that it was better to "keep" two slots for the £1K and £2K products (because although there are lots and lots of products in the other slot, no-one will actually care about the differences in prices). It's definitely a fair bit more complicated though.
 
Right so what you're saying is I hard-code a pool of 'acceptable' price ranges into the system, based on the lowest price and highest price product in the entire catalogue.

Next I work out how many items there should ideally be in each of the 6 ranges.

In turn I select a range, try to fill it with items until the desired amount is reached. If it fills I move onto the next 'nice range' from the pool. If it doesn't fill to the desired amount, I use the top value of the next 'nice' range in the pool and carry on filling; repeating as necessary.

Or have I misunderstood again?
 
Nope. As you said yourself, you're going to need a lot more than 6 ranges to cover the whole thing.

I tried writing out an example to make it clearer, but it actually didn't work too well - this method doesn't work well for small examples. I think it would be better for big examples (when you're query returns hundreds of hits), but I might be wrong.

Given it's more complicated and I don't seem to be able to explain it properly, I suggest you just forget it.
 
lol no worries this has helped.

The website displays a minimum of 10 products per page so I guess I can just turn off the price range filter altogether when there are 10 or fewer products being displayed.
 
I'd probably achieve this in a database stored procedure, with something like this (T-SQL):

Code:
CREATE TABLE #PriceFrequency (UpperBoundary INT, Frequency INT)

INSERT INTO #PriceFrequency
SELECT n.Number * 5, COUNT(p.ProductID)
FROM Number n
LEFT OUTER JOIN Product p ON n.Number * 5 >= p.Price AND (n.Number - 1) * 5 < p.Price
GROUP BY n.Number * 5;

...then using the #PriceFrequency table joined onto Number to drag out the UpperBoundary values which are equal to or over the number times by the average number of products you want in each range. The Number table, by the way, is just a list of numbers from (say) 1 - 1000 :)

This would probably be fairly efficient.

arty
 
I'll be doing the processing out of the db mainly because there's quite a number of processes I need to put it through before I'll get the desired result and most can't be done via a stored procedure.

I think applying the following rules might help keep the price ranges neat:

* For prices between £0-£50, price range upper limits are increased by £5 until filled by enough items
* For prices between £50-£100, price range upper limits are increased by £10 until filled by enough items
* For prices between £100-£300, price range upper limits are increased by £50 until filled by enough items
* For prices between £300-£1000, price range upper limits are increased by £100 until filled by enough items
* For prices that are £1000+, price range upper limits are increased by £500 until filled by enough items

Going back to my original example with the following prices: £1, £40, £42, £43, £43, £43, £47, £50, £52, £90, £600, this method should give me the following price ranges:
£0-£40 (2)
£40-£45 (5)
£45-£50 (2)
£50-£60 (2)
£60-£90 (1)
£90-£600 (2)

....not a mile off from what I was after. Its a little bit of all your ideas DaveF and appears to work with the example at least. I'll put it to the real test tomorrow.
 
Last edited:
how about you got 300 items, you order them

you take the first item e.g 2p, you then read the 50th item e.g. £3
and create first category

2p -£3(50 items) 1-50

you then take the 51st item e.g. £3.05, and the 100th item i.e. £5 and create the category

£3.05 - £5 (50 items) 51-100

and so on :)???

i could code a nice algorithm in java for this :D
 
hi i made an alogrithm and implemented it in java, if you need more explanation of it just ask :)

Code:
import java.util.*;

public class findBoundaries{
	ArrayList prices;
	int rangeFreq;
	public findBoundaries(ArrayList prices, int rangeFreq){
		this.prices = prices;
		this.rangeFreq = rangeFreq;
		sortPrices();
	}

	public void sortPrices(){
		Collections.sort(prices);
	}

	public void printBoundary(){
		int priceSize = prices.size();
		int loop = priceSize/rangeFreq;
		int mod = priceSize%rangeFreq;
		System.out.println("We have found "+priceSize +" products: ($"+prices.get(0)+" - $"+prices.get(priceSize-1)+")\n");
		int rangeCount =1;
		for(int i = 0;i< priceSize;){
			int productCount =0;
			System.out.print(rangeCount+".  $"+prices.get(i));
			i += (loop-1);
			productCount += (loop);
			if(mod>0){
				mod --;
				i++;
				productCount++;
			}
			System.out.print(" - $"+prices.get(i));

			System.out.print(" ("+productCount+")");
			System.out.println("");
			rangeCount++;
			i++;

		}
	}
	public static void main(String[] args) {
		ArrayList prices = new ArrayList();
		prices.add(1);		prices.add(43);		prices.add(47);		prices.add(50);
		prices.add(52);		prices.add(40);		prices.add(42);		prices.add(43);
		prices.add(43);		prices.add(56);		prices.add(92);		prices.add(603);
		prices.add(43);		prices.add(78);		prices.add(21);		prices.add(32);
		prices.add(223);	prices.add(178);	prices.add(121);	prices.add(432);
		prices.add(413);	prices.add(3);		prices.add(2);		prices.add(12);
		prices.add(53);		prices.add(88);		prices.add(11);		prices.add(92);
		findBoundaries fb = new findBoundaries(prices, 6);
		fb.printBoundary();

	}
}

you can pass a value to tell it how many ranges to put the prices into. Atm its on 6 on this line -> findBoundaries fb = new findBoundaries(prices, 6);

you can also pass an unordered price list in and it will order it before doing anything. here are some outputs of this java file.
---6 price ranges -------------------
We have found 28 products: ($1 - $603)

1. $1 - $12 (5)
2. $21 - $43 (5)
3. $43 - $50 (5)
4. $52 - $88 (5)
5. $92 - $178 (4)
6. $223 - $603 (4)
-------------------------------------

----3 price ranges--------------
We have found 28 products: ($1 - $603)

1. $1 - $43 (10)
2. $43 - $78 (9)
3. $88 - $603 (9)
-------------------------------

---12 price ranges ---------------
We have found 28 products: ($1 - $603)

1. $1 - $3 (3)
2. $11 - $21 (3)
3. $32 - $42 (3)
4. $43 - $43 (3)
5. $43 - $47 (2)
6. $50 - $52 (2)
7. $53 - $56 (2)
8. $78 - $88 (2)
9. $92 - $92 (2)
10. $121 - $178 (2)
11. $223 - $413 (2)
12. $432 - $603 (2)
--------------------------------------

you could put in a lot more prices and the alogithm would work the same
 
Last edited:
I did already get it working using a combination of solutions already posted but at first glance yours seems like it would be a lot quicker in processing.

There is one issue that yours doesn't address though but which I do need to do is to have 'nice' boundaries (see the rules I set in my previous post). Basically all boundaries are either multiples of 5, 10, 50, 100 or 500.

I could run your method first then apply the rules afterwards.

One problem that I am hitting at the moment which seems to occur no matter which method I use, is that I can't get an accurate count of products that appear in each price range. This is happening because I'm changing the boundaries to make them look nicer. As a not so clever fix I'm looping through each price range at the end of the code and running a query to find how many products would be returned.

Here's my code thus far:
Code:
	/**
	 * Gets price filter menu that appears on left hand side of shop-front website
	 *
	 * @return string
	 */
	public static function getPriceMenu() {
		// Initialise string holding HTML for the price range filter menu's content
		$strContent = "";

		// Before we do anything, check if the data requested is cached.  If it is then just
		// set the cached HTML as the content of the menu
		$objCache = new cachePrices();
		if ($objCache->load($_SERVER['REQUEST_URI'])) $strContent = $objCache->strContent;

		// Else generate a new menu
		else {
			// Only show price range menu when we're at least at a level 1 category
			if (category::getLevel() >= 1) {
				global $objDB;
				global $arrUrlPart;

				// If there is an active price range filter, display a notice saying so and provide an
				// option to remove the filter
				if ($arrActivePR = self::getPriceRangeFromUrl()) {
					$intFrom	= $arrActivePR[0];
					$intTo		= $arrActivePR[1];

					$strHref = "/";

					foreach ($arrUrlPart as $intKey => $strUrlPart) {
						if (substr($strUrlPart, 0, 6) != "price-") $strHref.= $strUrlPart . "/";
					}

					$strContent.=	"Filtering by products priced between <strong>£$intFrom - £$intTo</strong>\n" .
									"<br /><br style=\"line-height: 5px\" />\n" .
									"<p class=\"menuItem\"><img src=\"/img/menuItemArrow.gif\" /> <a href=\"$strHref\">Show all price ranges</a></p>\n";
				}

				// Else display a list of appropriate price range options
				else {
					$objCategory = new category(category::getIdFromUrl());
					$objCategory->loadChildCats($objCategory->idCategory, category::getLevel());

					// Get the total number of products being displayed
					$intProducts = category::getNumProducts($objCategory->idCategory);

					// Only show price range menu when there are more than 10 being displayed
					if ($intProducts > 10) {
						// Get all the individual prices
						$strSQL =  "SELECT intPrice FROM product
									WHERE idCategory IN ($objCategory->idCategory";

						if (count($objCategory->arrChildCat) > 0) {
							$strSQL.= ", " . implode(", ", $objCategory->arrChildCat) . ")";
						}

						else $strSQL.= ")";

						$idBrand = brand::getIdFromUrl();
						if ($idBrand > 0) $strSQL.= " AND idBrand = " . $idBrand;

						$strSQL.= " ORDER BY intPrice ASC";

						$objResult = $objDB->query($strSQL);

						// Calculate desired number of items per price range
						if ($intProducts <= 30) $intDesired = round($intProducts / 3);
						elseif (($intProducts > 30) && ($intProducts <= 40)) $intDesired = round($intProducts / 4);
						elseif (($intProducts > 40) && ($intProducts <= 50)) $intDesired = round($intProducts / 5);
						elseif ($intProducts > 50) $intDesired = round($intProducts / 6);

						$arrPR		= array();	// Initialise array that will hold price range data
						$intRecord	= 0;		// Initialise counter for current record in loop
						$intPR		= 0;		// Initialise counter for current price range

						while ($objRow = $objResult->fetch_object()) {
							$intRecord++;

							// Set rule for calculating how much to increase/decrease price range
							// start/end values by to find the appropriate one
							if ($objRow->intPrice <= 5000) $intRule = 500;
							elseif (($objRow->intPrice > 5000) && ($objRow->intPrice <= 10000)) $intRule = 1000;
							elseif (($objRow->intPrice > 10000) && ($objRow->intPrice <= 30000)) $intRule = 5000;
							elseif (($objRow->intPrice > 30000) && ($objRow->intPrice <= 100000)) $intRule = 10000;
							elseif ($objRow->intPrice > 100000) $intRule = 50000;

							// Set the current price range's start figure if not done already
							if (!isset($arrPR[$intPR]["intFrom"])) {
								// If this is the first record, we need to calculate it
								if ($intRecord == 1) {
									// Set start value to 0
									$intFrom = 0;

									// Keep incrementing by the rule amount until the start value overtakes
									// the current price in the loop
									while ($intFrom <= $objRow->intPrice) $intFrom = $intFrom + $intRule;

									// Then decrement once by the rule amount to give the final start figure
									$arrPR[$intPR]["intFrom"] = $intFrom - $intRule;
								}

								// Else the start figure is set to the end figure of the previous price range
								else $arrPR[$intPR]["intFrom"] = $arrPR[$intPR - 1]["intTo"];
							}

							// Set the current price range's end figure if not done already
							if (!isset($arrPR[$intPR]["intTo"])) {
								// Set the end value to the start value
								$intTo = $arrPR[$intPR]["intFrom"];

								// Keep incrementing by the rule amount until the end value overtakes
								// the current price in the loop and then you've got the desired value
								while ($intTo <= $objRow->intPrice) $intTo = $intTo + $intRule;
								$arrPR[$intPR]["intTo"] = $intTo;
							}

							// If the current price is less than or equal to the end value, increment
							// the products counter for the current price range
							if ($objRow->intPrice <= $arrPR[$intPR]["intTo"]) $arrPR[$intPR]["intProducts"]++;

							// Else we need to increment the end value by the rule amount until the
							// current price is less than or equal to it
							else {
								while ($objRow->intPrice > $arrPR[$intPR]["intTo"]) {
									$arrPR[$intPR]["intTo"] = $arrPR[$intPR]["intTo"] + $intRule;
								}

								// And then increment the products counter for the current price range
								$arrPR[$intPR]["intProducts"]++;
							}

							// If we've filled the current price range with the desired amount of
							// products, then move onto the next one
							if ($arrPR[$intPR]["intProducts"] >= $intDesired) $intPR++;
						}

						// The number of products figure for each price range is going to probably
						// be close to the correct amount but not exact due to the way I've coded
						// this (not wonderfully).  As a short term quick fix I decided to loop
						// through each price range and run a query to find the correct amount of
						// products that should be displayed as a result of activating the price
						// range filter
						for ($i = 0; $i < count($arrPR); $i++) {
							$strSQL =  "SELECT COUNT(idProduct) AS intProducts FROM product
										WHERE idCategory IN ($objCategory->idCategory";

							if (count($objCategory->arrChildCat) > 0) {
								$strSQL.= ", " . implode(", ", $objCategory->arrChildCat) . ")";
							}

							else $strSQL.= ")";

							$idBrand = brand::getIdFromUrl();
							if ($idBrand > 0) $strSQL.= " AND idBrand = " . $idBrand;

							$strSQL.=  " AND intPrice >= " . $arrPR[$i]["intFrom"] . "
										AND intPrice <= " . $arrPR[$i]["intTo"];

							$objResult = $objDB->query($strSQL);

							if ($objResult->num_rows > 0) {
								$objRow = $objResult->fetch_object();
								$arrPR[$i]["intProducts"] = $objRow->intProducts;
							}
							else $arrPR[$i]["intProducts"] = 0;
						}

						// Create the menu links HTML
						for ($i = 0; $i < count($arrPR); $i++) {
							$strHref = "/";

							foreach ($arrUrlPart as $intKey => $strUrlPart) {
								if (substr($strUrlPart, 0, 5) == "page-") $strPageUrlPart = $strUrlPart;
								else $strHref.= $strUrlPart . "/";
							}

							$strHref.= "price-" . ($arrPR[$i]["intFrom"] / 100) . "-" . ($arrPR[$i]["intTo"] / 100) . "/";

							if (strlen($strPageUrlPart) > 0) $strHref.= $strPageUrlPart . "/";

							$strFrom	= "£" . ($arrPR[$i]["intFrom"] / 100);
							$strTo		= "£" . ($arrPR[$i]["intTo"] / 100);

							if ($arrPR[$i]["intProducts"] > 0) {
								$strContent.= "<p class=\"menuItem\"><img src=\"/img/menuItemArrow.gif\" /> <a href=\"$strHref\">$strFrom - $strTo</a> (" . $arrPR[$i]["intProducts"] . ")</p>\n";
							}
						}
					}
				}
			}

			// Because this data wasn't cached, we add it to the cache table
			$objCache->strUrl = $_SERVER['REQUEST_URI'];
			$objCache->strContent = $strContent;
			$objCache->add();
		}

		// If content has been set load the content into a left menu template and return it
		// otherwise it means there are no products being displayed, in which case this menu isn't
		// required at all.
		if (strlen($strContent) > 0) {
			$strHTML = funcFile::read(TMPL_ROOT . "leftMenu.tmpl");
			$strHTML = str_replace("<#strTitle>", "Browse by price", $strHTML);
			$strHTML = str_replace("<#strContent>", $strContent, $strHTML);
			return $strHTML;
		}
	}

Appologies for the size of the functon; I haven't got round to splitting it out into smaller functions yet.
 
Last edited:
hi m8

i can try and get it working with nice boundaries if you want me too. it will add a bit to the overhead tho. gimme 30 minutes and i will come up with something :D
 
Hi, ive worked out an algorithm. you will need to experiment with variables in the main method ->>>

findBoundaries fb = new findBoundaries(prices, 8,10);

prices = collection of prices

8 = number of categories, this doesnt really return the correct number so just experiment with this number.

10 = the multples in which the boundaries are calculated, atm its 10, so it will return results like 1-10 , 21-30 etc.. again experiment

here is the code

Code:
import java.util.*;

public class findBoundaries{
	private ArrayList prices;
	private int rangeFreq;
	private int multiple;
	
	public findBoundaries(ArrayList prices, int rangeFreq, int multiple){
		this.prices = prices;
		this.rangeFreq = rangeFreq;
		this.multiple = multiple;
		sortPrices();
	}
	public void sortPrices(){
		Collections.sort(prices);
	}
	
	public int countRange(int low, int high) {
		int count = 0;
		Iterator counta = ((ArrayList)prices.clone()).iterator();
		while(counta.hasNext()) {
			int value = ((Integer)counta.next()).intValue();
			if(value>high) break;
			if(value >= low) {
				count++;
			}
		}
		return count;
	}
	
	public void printNiceBoundary(){
		int priceSize = prices.size();
		int loop = priceSize/rangeFreq;
		int mod = priceSize%rangeFreq;
		int finalPrice = getFinalPrice(((Integer)prices.get(priceSize-1)).intValue());
		System.out.println("We have found "+priceSize +" products: ($0 - $"+finalPrice+")\n");
		int range = multiple;
		int boundary =0;
		for(int ik = 0;ik<rangeFreq;ik++) {
			while(countRange(boundary,range)<=(loop +hasMod(mod)) && (range < finalPrice)){
				range +=multiple;	
			}
			int productRangeCount =countRange(boundary,(range));		
			System.out.println((ik+1)+".  $"+boundary +" - $"+ (range) +"("+productRangeCount+")");
			mod+=(loop-productRangeCount);
			boundary = range+1;
			if(boundary>finalPrice) break;
		}
	}
	
	public int hasMod(int mod){
		if(mod>0) {
			return 1;
		}
		return 0;
	}
	public int getFinalPrice(int price) {
		int i =price;
		while(i%multiple !=0) {
			i++;
		}
		return i;
	}
	public static void main(String[] args) {
		ArrayList prices = new ArrayList();
		prices.add(new Integer(1));		prices.add(new Integer(43));		prices.add(new Integer(47));		prices.add(new Integer(50));
		prices.add(new Integer(52));		prices.add(new Integer(40));		prices.add(new Integer(42));		prices.add(new Integer(43));
		prices.add(new Integer(43));		prices.add(new Integer(56));		prices.add(new Integer(92));		prices.add(new Integer(603));
		prices.add(new Integer(43));		prices.add(new Integer(78));		prices.add(new Integer(21));		prices.add(new Integer(32));
		prices.add(new Integer(223));	prices.add(new Integer(178));	prices.add(new Integer(121));	prices.add(new Integer(432));
		prices.add(new Integer(413));	prices.add(new Integer(3));		prices.add(new Integer(2));		prices.add(new Integer(12));
		prices.add(new Integer(53));		prices.add(new Integer(88));		prices.add(new Integer(11));		prices.add(new Integer(92));
		prices.add(new Integer(1));		prices.add(new Integer(43));		prices.add(new Integer(47));		prices.add(new Integer(50));
		prices.add(new Integer(153));		prices.add(new Integer(41));		prices.add(new Integer(44));		prices.add(new Integer(143));
		prices.add(new Integer(143));		prices.add(new Integer(56));		prices.add(new Integer(92));		prices.add(new Integer(603));
		prices.add(new Integer(143));		prices.add(new Integer(78));		prices.add(new Integer(21));		prices.add(new Integer(32));
		prices.add(new Integer(2123));	prices.add(new Integer(179));	prices.add(new Integer(1921));	prices.add(new Integer(432));
		prices.add(new Integer(413));	prices.add(new Integer(3));		prices.add(new Integer(2));		prices.add(new Integer(12));
		prices.add(new Integer(53));		prices.add(new Integer(88));		prices.add(new Integer(11));		prices.add(new Integer(92));
		prices.add(new Integer(1));		prices.add(new Integer(43));		prices.add(new Integer(47));		prices.add(new Integer(50));
		prices.add(new Integer(52));		prices.add(new Integer(40));		prices.add(new Integer(42));		prices.add(new Integer(43));
		prices.add(new Integer(43));		prices.add(new Integer(56));		prices.add(new Integer(92));		prices.add(new Integer(603));
		prices.add(new Integer(43));		prices.add(new Integer(78));		prices.add(new Integer(21));		prices.add(new Integer(32));
		prices.add(new Integer(223));	prices.add(new Integer(178));	prices.add(new Integer(121));	prices.add(new Integer(432));
		prices.add(new Integer(413));	prices.add(new Integer(3));		prices.add(new Integer(2));		prices.add(new Integer(12));
		prices.add(new Integer(53));		prices.add(new Integer(88));		prices.add(new Integer(11));		prices.add(new Integer(92));
		
		
		findBoundaries fb = new findBoundaries(prices, 8,10);
		fb.printNiceBoundary();
	}
}

here are some sample outputs

---------(8,10)-------------
We have found 84 products: ($0 - $2130)

1. $0 - $20(15)
2. $21 - $50(27)
3. $51 - $80(11)
4. $81 - $130(11)
5. $131 - $420(12)
6. $421 - $2130(8)

----------(8,20)----------------------
We have found 84 products: ($0 - $2140)

1. $0 - $20(15)
2. $21 - $60(35)
3. $61 - $100(12)
4. $101 - $240(11)
5. $241 - $2140(11)


---------(8,5)-----------------
We have found 84 products: ($0 - $2125)

1. $0 - $15(15)
2. $16 - $45(21)
3. $46 - $55(11)
4. $56 - $95(15)
5. $96 - $225(11)
6. $226 - $2125(11)


--------(5,50)--------------------
We have found 84 products: ($0 - $2150)

1. $0 - $50(42)
2. $51 - $100(20)
3. $101 - $450(17)
4. $451 - $2150(5)

---------(5,100)------------
We have found 84 products: ($0 - $2200)

1. $0 - $100(62)
2. $101 - $500(17)
3. $501 - $2200(5)

if you have any questions or request on the code, just post :D
 
Last edited:
Back
Top Bottom