Skip to content

Commit

Permalink
Fixed bug where markets were being visited despite nothing being boug…
Browse files Browse the repository at this point in the history
…ht there. Changed GTCF to go from 0 to 1.
  • Loading branch information
Mike Speriosu committed Jul 12, 2013
1 parent baff312 commit 799580d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class GaussianTPPResolver(val dpc:Double,
val acoIterations:Int)
extends TPPResolver(new TPPInstance(
//new MaxentPurchaseCoster(corpus, modelDirPath),
new MultiPurchaseCoster(List(new GaussianPurchaseCoster,//new SimpleContainmentPurchaseCoster,
new MaxentPurchaseCoster(corpus, modelDirPath))),
if(modelDirPath != null) new MultiPurchaseCoster(List(new GaussianPurchaseCoster, //new SimpleContainmentPurchaseCoster,
new MaxentPurchaseCoster(corpus, modelDirPath))) else new MultiPurchaseCoster(List(new GaussianPurchaseCoster)),
if(articleInfoPath != null && linkPath != null) new LinkTravelCoster(articleInfoPath, linkPath, GaussianTPPResolver.loadGaz(gazPath))
else if(marketProbPath != null) new FileTravelCoster(marketProbPath, corpus, dpc)
else new GaussianTravelCoster)) {
Expand Down Expand Up @@ -63,15 +63,30 @@ class GaussianTPPResolver(val dpc:Double,
if(tppInstance.markets == null) {
//println(tppInstance.purchaseCoster.asInstanceOf[MultiPurchaseCoster].purchaseCosters(1).asInstanceOf[MaxentPurchaseCoster])
tppInstance.markets =
if(threshold < 0) (new GridMarketCreator(doc, dpc, tppInstance.purchaseCoster.asInstanceOf[MultiPurchaseCoster].purchaseCosters(1).asInstanceOf[MaxentPurchaseCoster])).apply
else (new ClusterMarketCreator(doc, threshold, tppInstance.purchaseCoster.asInstanceOf[MultiPurchaseCoster].purchaseCosters(1).asInstanceOf[MaxentPurchaseCoster])).apply
if(threshold < 0) (new GridMarketCreator(doc, dpc, tppInstance.purchaseCoster.asInstanceOf[MultiPurchaseCoster].purchaseCosters.last/*.asInstanceOf[MaxentPurchaseCoster]*/)).apply
else (new ClusterMarketCreator(doc, threshold, tppInstance.purchaseCoster.asInstanceOf[MultiPurchaseCoster].purchaseCosters.last/*.asInstanceOf[MaxentPurchaseCoster]*/)).apply
docsToMarkets.put(doc.getId, tppInstance.markets)
}

val solver = new ACOTPPSolver(factory, population)

var tour = solver(tppInstance)

if(doc.getId.equals("d94")) {
var prev:MarketVisit = null
for(mv <- tour) {
if(prev != null)
println(" Travel cost: "+tppInstance.travelCoster(prev.market, mv.market))

val totalPurchaseCost = mv.purchasedLocations.map(_._2).map(purLoc => tppInstance.purchaseCoster(mv.market, purLoc)).sum
println("Total purchase cost of "+mv.purchasedLocations.size+" locations at market with centroid at ("+mv.market.centroid+"): "+totalPurchaseCost)

prev = mv
}

solver.writeKML(tour, "d94-tour.kml")
}

// Maintain a best tour and minimum cost for this document across all iterations:
val cost = tppInstance.computeTourCost(tour)
val prevBestTourAndCost = docsToBestTours.getOrElse(doc.getId, (null, Double.PositiveInfinity))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.util.ArrayList

import scala.collection.JavaConversions._

class ClusterMarketCreator(doc:Document[StoredToken], val thresholdInKm:Double, val purchaseCoster:MaxentPurchaseCoster = null) extends MarketCreator(doc) {
class ClusterMarketCreator(doc:Document[StoredToken], val thresholdInKm:Double, val purchaseCoster:PurchaseCoster = null) extends MarketCreator(doc) {

val threshold = thresholdInKm / 6372.8

Expand Down
103 changes: 78 additions & 25 deletions src/main/scala/opennlp/fieldspring/tr/tpp/ConstructionTPPSolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,50 +105,103 @@ object ConstructionTPPSolver {

val pc = tppInstance.purchaseCoster

//var boughtSomething = false

// Buy goods that haven't been bought before or that are cheaper than when previously bought
for((topMen, potLoc) <- market.locations) {
if(resolvedToponymMentions.contains(topMen)) {
if(pc(resolvedToponymMentions(topMen), potLoc) > pc(market, potLoc)) {
marketVisit.purchasedLocations.put(topMen, potLoc)
resolvedToponymMentions.put(topMen, market)

//boughtSomething = true
}
}
else {
marketVisit.purchasedLocations.put(topMen, potLoc)
resolvedToponymMentions.put(topMen, market)
//boughtSomething = true
}
}

// Unbuy goods that have already been purchased elsewhere for the same or cheaper
// prices. There should be a more efficient way to do this where we keep track of
// where purchased goods were purchased before, thereby not needing to iterate through
// all the markets already in the tour
for(existingMarketVisit <- tour) {
var index = 0
val purLocs = marketVisit.purchasedLocations.toList
while(index < purLocs.size) {
//for((topMen, newPotLoc) <- marketVisit.purchasedLocations) {
val topMen = purLocs(index)._1
val newPotLoc = purLocs(index)._2
val prevPotLoc = existingMarketVisit.purchasedLocations.getOrElse(topMen, null)
if(prevPotLoc != null) {
if(pc(existingMarketVisit.market, prevPotLoc) <= pc(marketVisit.market, newPotLoc)) {
//print(purLocs.size+" => ")
marketVisit.purchasedLocations.remove(topMen)
//println(purLocs.size)
}
else {
existingMarketVisit.purchasedLocations.remove(topMen)
// Only unbuy goods and insert this market into the tour if we actually bought anything here
if(marketVisit.purchasedLocations.size > 0) {

// Unbuy goods that have already been purchased elsewhere for the same or cheaper
// prices. There should be a more efficient way to do this where we keep track of
// where purchased goods were purchased before, thereby not needing to iterate through
// all the markets already in the tour
var mvIndex = 0
val mvIndecesToRemove = new ArrayList[Int]
for(existingMarketVisit <- tour) {
var purLocIndex = 0
val purLocs = marketVisit.purchasedLocations.toList
while(purLocIndex < purLocs.size) {
//for((topMen, newPotLoc) <- marketVisit.purchasedLocations) {
val topMen = purLocs(purLocIndex)._1
val newPotLoc = purLocs(purLocIndex)._2
val prevPotLoc = existingMarketVisit.purchasedLocations.getOrElse(topMen, null)
if(prevPotLoc != null) {
if(pc(existingMarketVisit.market, prevPotLoc) <= pc(marketVisit.market, newPotLoc)) {
//print(purLocs.size+" => ")
marketVisit.purchasedLocations.remove(topMen)
//println(purLocs.size)
}
else {
existingMarketVisit.purchasedLocations.remove(topMen)
}
}
purLocIndex += 1
}
index += 1

if(existingMarketVisit.purchasedLocations.size == 0)
mvIndecesToRemove.add(mvIndex)

mvIndex += 1
}

// Remove market visits from the tour where we no longer buy anything
for(i <- mvIndecesToRemove) {
tour.remove(i)
var innerIndex = 0
for(j <- mvIndecesToRemove) {
if(j > i)
mvIndecesToRemove.set(innerIndex, j-1)
innerIndex += 1
}
}

// Check to make sure we're still buying something at this market after unbuying
if(marketVisit.purchasedLocations.size > 0) {
//println(index)
optimalInsert(tour, marketVisit, tppInstance.travelCoster) // This puts the market in the place that minimizes the added travel cost
}

}
}

if(marketVisit.purchasedLocations.size > 0) {
//println(index)
tour.insert(index, marketVisit) // This puts the market in the place that minimizes the added travel cost
def optimalInsert(tour:ArrayList[MarketVisit], marketVisit:MarketVisit, tc:TravelCoster) {
if(tour.size == 0)
tour.insert(0, marketVisit)

else {
var leastTC = Double.PositiveInfinity
var optIndex = -1
var index = 0
for(existingMV <- tour) {
val thisTC = tc(marketVisit.market, existingMV.market)
if(thisTC < leastTC) {
optIndex = index
leastTC = thisTC
}

index += 1
}
val thisTC = tc(tour.last.market, marketVisit.market)
if(thisTC < leastTC) {
optIndex = tour.size
}

tour.insert(optIndex, marketVisit)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,24 @@ class GaussianTravelCoster extends TravelCoster {

def g(x:Double, y:Double) = GaussianUtil.g(x,y)

val maxHeight = g(0.0,0.0)

def apply(m1:Market, m2:Market): Double = {
1.0-g(m1.centroid.distance(m2.centroid)/variance, 0)
(maxHeight-g(m1.centroid.distance(m2.centroid)/variance, 0))/maxHeight
}

/* old implementation:
def apply(m1:Market, m2:Market): Double = {
1.0-g(m1.centroid.distance(m2.centroid)/variance, 0)
}*/
}

object GaussianTravelCoster extends App {
val gtc = new GaussianTravelCoster
println((gtc.maxHeight-gtc.g(0,0))/gtc.maxHeight)
println((gtc.maxHeight-gtc.g(0.25,0))/gtc.maxHeight)
println((gtc.maxHeight-gtc.g(0.5,0))/gtc.maxHeight)
println((gtc.maxHeight-gtc.g(1.0,0))/gtc.maxHeight)
println((gtc.maxHeight-gtc.g(2.0,0))/gtc.maxHeight)
println((gtc.maxHeight-gtc.g(3.0,0))/gtc.maxHeight)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import opennlp.fieldspring.tr.util._

import scala.collection.JavaConversions._

class GridMarketCreator(doc:Document[StoredToken], val dpc:Double, val purchaseCoster:MaxentPurchaseCoster = null) extends MarketCreator(doc) {
class GridMarketCreator(doc:Document[StoredToken], val dpc:Double, val purchaseCoster:PurchaseCoster = null) extends MarketCreator(doc) {
override def apply:List[Market] = {
val cellNumsToPotLocs = new scala.collection.mutable.HashMap[Int, scala.collection.mutable.HashMap[ToponymMention, PotentialLocation]]

Expand Down

0 comments on commit 799580d

Please sign in to comment.