SCSAPlaceImpl:
CEDAR
PROGRAM
IMPORTS Random, RealFns, SC, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCUtil, TerminalIO
EXPORTS SCPrivate
SHARES SC = {
debug: BOOLEAN ← TRUE;
ExchDescription:
TYPE =
RECORD [
inst1, inst2: SCPrivate.Instance ← NIL];
Freezing:
PROCEDURE [score:
REAL, temp:
REAL]
RETURNS [
BOOLEAN] = {
RETURN[TRUE]};
Equilibrium:
PROCEDURE [score:
REAL]
RETURNS [
BOOLEAN] = {
RETURN[TRUE]};
Select:
PROCEDURE [handle:
SC.Handle, selectStream: Random.RandomStream]
RETURNS [exch: ExchDescription ← [
NIL,
NIL]] = {
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
numInstances: SCPrivate.ZMaxInstanceSr ← structureData.instances.count;
numLogics: SCPrivate.ZMaxInstanceSr ← structureData.instances.numLogics;
numIOs: SCPrivate.ZMaxInstanceSr ← structureData.instances.numIOs;
index: SCPrivate.ZMaxInstanceSr ← Random.ChooseInt[selectStream, 1, numInstances];
otherIndex: SCPrivate.ZMaxInstanceSr;
inst1, inst2: SCPrivate.Instance;
IF 1 <= index
AND index <= numIOs
THEN {
got an IO, get another IO
inst1 ← GetNextIo[index];
IF inst1 = NIL THEN RETURN
ELSE {
otherIndex ← Random.ChooseInt[selectStream, 1, numIOs];
inst2 ← GetNextIo[otherIndex];
IF inst2 = NIL THEN RETURN}}
ELSE {
logicIndex: SCPrivate.ZMaxInstanceSr ← index - numIOs;
IF 1 <= logicIndex
AND logicIndex <= numLogics
THEN {
got a logic, get another logic
inst1 ← GetNextLogic[logicIndex];
IF inst1 = NIL THEN RETURN
ELSE {
otherIndex ← Random.ChooseInt[selectStream, numIOs + 1, numInstances];
inst2 ← GetNextLogic[otherIndex];
IF inst2 = NIL THEN RETURN}}
ELSE SC.Error[programmingError, "Invalid instance index"]};
RETURN[[inst1, inst2]]};
GetNextIo:
PROCEDURE [index: SCPrivate.ZMaxInstanceSr]
RETURNS [instance: SCPrivate.Instance]= {
RETURN[instance]};
GetNextLogic:
PROCEDURE [index: SCPrivate.ZMaxInstanceSr]
RETURNS [instance: SCPrivate.Instance]= {
RETURN[instance]};
Exchange:
PROCEDURE [handle:
SC.Handle, exch: ExchDescription]
RETURNS [didIt:
BOOLEAN ← TRUE] = {
};
FullScore:
PROCEDURE [handle:
SC.Handle]
RETURNS [score:
REAL] = {
RETURN[score]};
ModScore:
PROCEDURE [handle:
SC.Handle, exch: ExchDescription]
RETURNS [score:
REAL]= {
RETURN[score]};
Random0To1:
PROCEDURE [choiceStream: Random.RandomStream]
RETURNS [value:
REAL]= {
RETURN[value]};
SAPlace:
PUBLIC
PROCEDURE [handle:
SC.Handle, t0, alpha:
REAL, seed:
INT] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
lgRows: SCPrivate.LgRows ← layoutData.lgRows;
selectStream: Random.RandomStream ← Random.Create[LAST[INT], seed];
choiceStream: Random.RandomStream ← Random.Create[LAST[INT], seed];
startArea: SC.Number;
temp: REAL ← t0;
score: REAL ← FullScore[handle];
[lgRows.maxRowWidth, lgRows.numMaxRows] ← SCRowUtil.FindMaxRow[handle];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
startArea ← SCUtil.WriteResults["Position improvement\n starting area:", handle, 0];
UNTIL Freezing[score, temp]
DO
UNTIL Equilibrium[score]
DO
exch: ExchDescription ← Select[handle, selectStream];
didIt: BOOLEAN ← Exchange[handle, exch];
IF didIt
THEN {
trialScore: REAL ← ModScore[handle, exch];
deltaScore: REAL ← trialScore - score;
IF deltaScore < 0.0 THEN score ← trialScore
ELSE {
random: REAL ← Random0To1[choiceStream];
IF random < RealFns.Exp[-deltaScore/temp]
THEN {
[] ← Exchange[handle, exch];
score ← ModScore[handle, exch]}}};
ENDLOOP;
temp ← alpha * temp;
ENDLOOP;
SCInstUtil.AllOffsets[handle];
[lgRows.maxRowWidth, lgRows.numMaxRows] ← SCRowUtil.FindMaxRow[handle];
SCWidthUtil.AllChanWidths[handle, areaFom];
SCInstUtil.AsgnChanPos[handle];
[] ← SCUtil.WriteResults["End position improvement\n ending area:", handle, startArea];
IF debug THEN SCPlaceUtil.WriteCurPlace[handle]};
}.