You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yacy_search_server/source/net/yacy/ai/greedy/Context.java

244 lines
9.3 KiB

// Context.java
// (C) 2009 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
// first published 03.12.2009 on http://yacy.net;
//
// This is a part of YaCy, a peer-to-peer based web search engine
//
// $LastChangedDate: 2009-05-28 01:51:34 +0200 (Do, 28 Mai 2009) $
// $LastChangedRevision: 5988 $
// $LastChangedBy: orbiter $
//
// LICENSE
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package net.yacy.ai.greedy;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Context<
SpecificRole extends Role,
SpecificFinding extends Finding<SpecificRole>,
SpecificModel extends Model<SpecificRole, SpecificFinding>
>{
private static final Object PRESENT = new Object();
private final Goal<SpecificRole, SpecificFinding, SpecificModel> goal;
private final SpecificModel initialModel;
private final SpecificRole initialRole;
private final PriorityBlockingQueue<Challenge<SpecificRole, SpecificFinding, SpecificModel>> result;
private final ConcurrentHashMap<SpecificModel, Object> models; // caches all observed models for a double-check
private final ConcurrentHashMap<SpecificRole, Integer> bestMove;
private final AtomicInteger instances;
private final long timeoutForSnapshot;
private final Semaphore termination;
private final boolean feedAssetCache, useAssetCache;
private long startTime;
private boolean fullfilled;
protected Context(
Goal<SpecificRole, SpecificFinding, SpecificModel> goal,
SpecificModel initialModel,
long timeoutForSnapshot, boolean feedAssetCache, boolean useAssetCache) {
this.goal = goal;
this.initialModel = initialModel;
this.initialRole = initialModel.currentRole();
this.models = new ConcurrentHashMap<SpecificModel, Object>();
this.result = new PriorityBlockingQueue<Challenge<SpecificRole, SpecificFinding, SpecificModel>>();
this.bestMove = new ConcurrentHashMap<SpecificRole, Integer>();
this.instances = new AtomicInteger(0);
this.timeoutForSnapshot = timeoutForSnapshot;
this.startTime = System.currentTimeMillis();
this.fullfilled = false;
this.termination = new Semaphore(0);
this.feedAssetCache = feedAssetCache;
this.useAssetCache = useAssetCache;
}
public int getInstanceCount() {
return this.instances.get();
}
public void incInstances() {
this.instances.incrementAndGet();
}
public int decInstances() {
return this.instances.decrementAndGet();
}
public boolean setBestMove(SpecificRole role, int ranking) {
Integer b = this.bestMove.get(role);
if (b == null) {
this.bestMove.put(role, ranking);
return true;
} else {
if (b.intValue() < ranking) {
this.bestMove.put(role, ranking);
return true;
}
}
return false;
}
public int getBestMove(SpecificRole role) {
Integer b = this.bestMove.get(role);
if (b == null) return Integer.MIN_VALUE;
return b.intValue();
}
public void addModel(SpecificModel model) {
this.models.put(model, PRESENT);
}
public Goal<SpecificRole, SpecificFinding, SpecificModel> getGoal() {
return goal;
}
public SpecificModel getInitialModel() {
return initialModel;
}
public boolean isKnownModel(SpecificModel model) {
return this.models.containsKey(model);
}
public int getKnownModelsCount() {
return this.models.size();
}
public void registerResult(Agent<SpecificRole, SpecificFinding, SpecificModel> agent, SpecificFinding finding) {
assert agent != null;
assert agent.getFinding() != null;
assert agent.getFinding().getRole() != null;
assert finding != null;
this.result.offer(new Challenge<SpecificRole, SpecificFinding, SpecificModel>(agent, finding));
}
public SpecificRole initialRole() {
return this.initialRole;
}
/**
* return one of the results from the problem solving computation.
* if there is no result available, then return null.
* a null result shows that there is either no solution at all
* or it was not possible to find one within the given time-out frame
* @return e challenge as a result or null if there is no result.
*/
public Challenge<SpecificRole, SpecificFinding, SpecificModel> takeResult() {
try {
while (!this.result.isEmpty()) {
Challenge<SpecificRole, SpecificFinding, SpecificModel> resultChallenge = this.result.take();
Agent<SpecificRole, SpecificFinding, SpecificModel> resultAgent = resultChallenge.getAgent();
if (resultAgent.isPrunedByTerminationInHistory(this.initialRole())) continue;
return resultChallenge;
}
// if this state is reached then all possible findings will cause a lost situation
return null;
} catch (InterruptedException e) {
return null;
}
}
public boolean hasNoResults() {
return this.result.isEmpty();
}
public int countResults() {
return this.result.size();
}
public void reset() {
this.startTime = System.currentTimeMillis();
this.termination.drainPermits();
}
public boolean feedAssetCache() {
return feedAssetCache;
}
public boolean useAssetCache() {
return useAssetCache;
}
public void announceCompletion() {
this.fullfilled = true;
this.termination.release();
}
public boolean isCompleted() {
if (this.fullfilled) return true;
//System.out.println("runtime = " + runtime);
boolean expired = System.currentTimeMillis() - this.startTime > this.timeoutForSnapshot;
if (expired) this.termination.release();
return expired;
}
public void awaitTermination(long pauseAfterAquire) {
try {
if (this.termination.tryAcquire(timeoutForSnapshot + pauseAfterAquire, TimeUnit.MILLISECONDS)) {
Thread.sleep(pauseAfterAquire);
} else {
System.out.println("timed-out termination");
}
} catch (InterruptedException e) {}
}
public void printReport(int count) {
System.out.println("==== " + this.getKnownModelsCount() + " models computed");
Challenge<SpecificRole, SpecificFinding, SpecificModel> resultChallenge;
Agent<SpecificRole, SpecificFinding, SpecificModel> resultAgent;
SpecificFinding resultFinding;
int i = 0;
while (count > 0) {
if (this.countResults() == 0) break;
resultChallenge = this.takeResult();
resultAgent = resultChallenge.getAgent();
resultFinding = resultChallenge.getFinding();
List<SpecificFinding> p = resultAgent.listPrunedByTerminationInHistory();
//if (p != null) continue;
//if (resultAgent.isPrunedByTerminationInHistory(resultAgent.initialModel.currentRole())) continue;
System.out.println("==== result " + i++ + "/" + this.countResults());
Finding<SpecificRole>[] moves = resultAgent.getFindings();
System.out.print("==== moves: ");
if (moves == null) System.out.println("null"); else {
for (int j = 0; j < moves.length; j++) {System.out.print(moves[j]); if (j < moves.length - 1) System.out.print(", "); }
} System.out.println();
System.out.println("==== first move: " + resultFinding);
assert resultFinding.getPriority() == resultAgent.getRanking(this.initialRole());
System.out.println("==== ranking: " + resultFinding.getPriority());
SpecificRole winner = resultAgent.getModel().isTermination();
if (winner != null) System.out.println("==== the winner is " + winner.toString());
if (p == null) {
System.out.println("==== pruning is null");
} else {
System.out.print("==== fail-moves are ");
for (SpecificFinding f: p) System.out.print(f + " ");
System.out.println("");
}
System.out.println(resultAgent.getModel().toString());
count--;
}
}
}